@palindromepay/sdk 1.9.4

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,1217 @@
1
+ /**
2
+ * PALINDROME CRYPTO ESCROW SDK
3
+ *
4
+ * Corrected and optimized SDK matching the actual smart contract interfaces.
5
+ *
6
+ * Key contract functions:
7
+ * - createEscrow(token, buyer, amount, maturityDays, arbiter, title, ipfsHash, sellerWalletSig)
8
+ * - createEscrowAndDeposit(token, seller, amount, maturityDays, arbiter, title, ipfsHash, buyerWalletSig)
9
+ * - deposit(escrowId, buyerWalletSig)
10
+ * - acceptEscrow(escrowId, sellerWalletSig)
11
+ * - confirmDelivery(escrowId, buyerWalletSig)
12
+ * - confirmDeliverySigned(escrowId, coordSignature, deadline, nonce, buyerWalletSig)
13
+ * - requestCancel(escrowId, walletSig)
14
+ * - cancelByTimeout(escrowId)
15
+ * - autoRelease(escrowId)
16
+ * - startDispute(escrowId)
17
+ * - startDisputeSigned(escrowId, signature, deadline, nonce)
18
+ * - submitDisputeMessage(escrowId, role, ipfsHash)
19
+ * - submitArbiterDecision(escrowId, resolution, ipfsHash, arbiterWalletSig)
20
+ * - Wallet: withdraw()
21
+ */
22
+ import { Address, Abi, PublicClient, WalletClient, Hex, Transport, Account, Chain } from "viem";
23
+ import { ApolloClient } from "@apollo/client";
24
+ export type ViemError = {
25
+ message: string;
26
+ shortMessage?: string;
27
+ cause?: {
28
+ reason?: string;
29
+ message?: string;
30
+ };
31
+ code?: number;
32
+ stack?: string;
33
+ };
34
+ export type ContractError = ViemError & {
35
+ contractAddress?: Address;
36
+ functionName?: string;
37
+ args?: readonly unknown[];
38
+ };
39
+ export type RPCError = {
40
+ message: string;
41
+ code?: number;
42
+ data?: unknown;
43
+ };
44
+ export type UnknownError = {
45
+ message?: string;
46
+ toString(): string;
47
+ };
48
+ export type LogLevel = 'debug' | 'info' | 'warn' | 'error' | 'none';
49
+ export interface SDKLogger {
50
+ debug(message: string, context?: unknown): void;
51
+ info(message: string, context?: unknown): void;
52
+ warn(message: string, context?: unknown): void;
53
+ error(message: string, context?: unknown): void;
54
+ }
55
+ import { Escrow } from "./types/escrow";
56
+ export declare enum EscrowState {
57
+ AWAITING_PAYMENT = 0,
58
+ AWAITING_DELIVERY = 1,
59
+ DISPUTED = 2,
60
+ COMPLETE = 3,
61
+ REFUNDED = 4,
62
+ CANCELED = 5
63
+ }
64
+ export declare enum DisputeResolution {
65
+ Complete = 3,
66
+ Refunded = 4
67
+ }
68
+ export declare enum Role {
69
+ None = 0,
70
+ Buyer = 1,
71
+ Seller = 2,
72
+ Arbiter = 3
73
+ }
74
+ export declare enum SDKErrorCode {
75
+ WALLET_NOT_CONNECTED = "WALLET_NOT_CONNECTED",
76
+ WALLET_ACCOUNT_MISSING = "WALLET_ACCOUNT_MISSING",
77
+ NOT_BUYER = "NOT_BUYER",
78
+ NOT_SELLER = "NOT_SELLER",
79
+ NOT_ARBITER = "NOT_ARBITER",
80
+ INVALID_STATE = "INVALID_STATE",
81
+ INSUFFICIENT_BALANCE = "INSUFFICIENT_BALANCE",
82
+ ALLOWANCE_FAILED = "ALLOWANCE_FAILED",
83
+ SIGNATURE_EXPIRED = "SIGNATURE_EXPIRED",
84
+ TRANSACTION_FAILED = "TRANSACTION_FAILED",
85
+ INVALID_ROLE = "INVALID_ROLE",
86
+ INVALID_TOKEN = "INVALID_TOKEN",
87
+ VALIDATION_ERROR = "VALIDATION_ERROR",
88
+ RPC_ERROR = "RPC_ERROR",
89
+ EVIDENCE_ALREADY_SUBMITTED = "EVIDENCE_ALREADY_SUBMITTED",
90
+ ESCROW_NOT_FOUND = "ESCROW_NOT_FOUND",
91
+ ALREADY_ACCEPTED = "ALREADY_ACCEPTED"
92
+ }
93
+ export type EscrowWalletClient = WalletClient<Transport, Chain, Account>;
94
+ export declare class SDKError extends Error {
95
+ code: SDKErrorCode;
96
+ details?: ViemError | RPCError | UnknownError | Record<string, unknown>;
97
+ constructor(message: string, code: SDKErrorCode, details?: ViemError | RPCError | UnknownError | Record<string, unknown>);
98
+ }
99
+ export interface PalindromeEscrowSDKConfig {
100
+ publicClient: PublicClient;
101
+ contractAddress: Address;
102
+ walletClient?: EscrowWalletClient;
103
+ apolloClient?: ApolloClient;
104
+ chain?: Chain;
105
+ /** Cache TTL in milliseconds (default: 5000) */
106
+ cacheTTL?: number;
107
+ /** Maximum cache entries before LRU eviction (default: 1000) */
108
+ maxCacheSize?: number;
109
+ /** Enable automatic retry on RPC failures (default: true) */
110
+ enableRetry?: boolean;
111
+ /** Maximum retry attempts (default: 3) */
112
+ maxRetries?: number;
113
+ /** Retry delay in milliseconds (default: 1000) */
114
+ retryDelay?: number;
115
+ /** Gas buffer percentage (default: 20) */
116
+ gasBuffer?: number;
117
+ /** Transaction receipt timeout in milliseconds (default: 60000) */
118
+ receiptTimeout?: number;
119
+ subgraphUrl?: string;
120
+ /**
121
+ * Skip eth_call simulation before sending transactions (default: false)
122
+ * Enable this for chains with unreliable RPC simulation (e.g., Base Sepolia)
123
+ * When true, transactions are sent directly without pre-flight simulation
124
+ */
125
+ skipSimulation?: boolean;
126
+ /**
127
+ * Default gas limit when simulation is skipped (default: 500000n)
128
+ * Only used when skipSimulation is true
129
+ */
130
+ defaultGasLimit?: bigint;
131
+ /**
132
+ * Logger instance for SDK events and errors (default: console)
133
+ * Set to custom logger or use noOpLogger to disable
134
+ */
135
+ logger?: SDKLogger;
136
+ /**
137
+ * Minimum log level to output (default: 'info')
138
+ * 'debug' shows all logs, 'none' disables all logging
139
+ */
140
+ logLevel?: LogLevel;
141
+ }
142
+ export interface CreateEscrowParams {
143
+ token: Address;
144
+ buyer: Address;
145
+ amount: bigint;
146
+ maturityTimeDays?: bigint;
147
+ arbiter?: Address;
148
+ title: string;
149
+ ipfsHash?: string;
150
+ }
151
+ export interface CreateEscrowAndDepositParams {
152
+ token: Address;
153
+ seller: Address;
154
+ amount: bigint;
155
+ maturityTimeDays?: bigint;
156
+ arbiter?: Address;
157
+ title: string;
158
+ ipfsHash?: string;
159
+ }
160
+ /** Raw escrow data from contract (before type narrowing to Address/Hex) */
161
+ export interface RawEscrowData {
162
+ token: `0x${string}`;
163
+ buyer: `0x${string}`;
164
+ seller: `0x${string}`;
165
+ arbiter: `0x${string}`;
166
+ wallet: `0x${string}`;
167
+ amount: bigint;
168
+ depositTime: bigint;
169
+ maturityTime: bigint;
170
+ disputeStartTime: bigint;
171
+ state: number;
172
+ buyerCancelRequested: boolean;
173
+ sellerCancelRequested: boolean;
174
+ tokenDecimals: number;
175
+ sellerWalletSig: `0x${string}`;
176
+ buyerWalletSig: `0x${string}`;
177
+ arbiterWalletSig: `0x${string}`;
178
+ }
179
+ /** Parsed escrow data with proper types */
180
+ export interface EscrowData {
181
+ token: Address;
182
+ buyer: Address;
183
+ seller: Address;
184
+ arbiter: Address;
185
+ wallet: Address;
186
+ amount: bigint;
187
+ depositTime: bigint;
188
+ maturityTime: bigint;
189
+ disputeStartTime: bigint;
190
+ state: EscrowState;
191
+ buyerCancelRequested: boolean;
192
+ sellerCancelRequested: boolean;
193
+ tokenDecimals: number;
194
+ sellerWalletSig: Hex;
195
+ buyerWalletSig: Hex;
196
+ arbiterWalletSig: Hex;
197
+ }
198
+ export interface EscrowCreatedEvent {
199
+ escrowId: bigint;
200
+ buyer: Address;
201
+ seller: Address;
202
+ token: Address;
203
+ amount: bigint;
204
+ arbiter: Address;
205
+ maturityTime: bigint;
206
+ title: string;
207
+ ipfsHash: string;
208
+ }
209
+ export interface DisputeSubmissionStatus {
210
+ buyer: boolean;
211
+ seller: boolean;
212
+ arbiter: boolean;
213
+ allSubmitted: boolean;
214
+ }
215
+ export declare class PalindromeEscrowSDK {
216
+ readonly contractAddress: Address;
217
+ readonly abiEscrow: Abi;
218
+ readonly abiWallet: Abi;
219
+ readonly abiERC20: Abi;
220
+ readonly publicClient: PublicClient;
221
+ readonly walletClient?: EscrowWalletClient;
222
+ readonly apollo: ApolloClient;
223
+ readonly chain: Chain;
224
+ private readonly cacheTTL;
225
+ private readonly maxCacheSize;
226
+ private readonly enableRetry;
227
+ private readonly maxRetries;
228
+ private readonly retryDelay;
229
+ private readonly gasBuffer;
230
+ private readonly receiptTimeout;
231
+ private readonly skipSimulation;
232
+ private readonly defaultGasLimit;
233
+ private readonly logger;
234
+ private readonly logLevel;
235
+ /** LRU cache for escrow data with automatic eviction */
236
+ private escrowCache;
237
+ /** Cache for token decimals (rarely changes, no eviction needed) */
238
+ private tokenDecimalsCache;
239
+ /** Cache for immutable contract values */
240
+ private walletBytecodeHashCache;
241
+ private feeReceiverCache;
242
+ /** Cached multicall support status per chain (null = not yet detected) */
243
+ private multicallSupported;
244
+ private readonly STATE_NAMES;
245
+ constructor(config: PalindromeEscrowSDKConfig);
246
+ /**
247
+ * Internal logging helper that respects log level configuration
248
+ */
249
+ private log;
250
+ /**
251
+ * Execute a contract write with resilient simulation handling.
252
+ *
253
+ * This method handles unreliable RPC simulation on certain chains (e.g., Base Sepolia)
254
+ * by falling back to direct transaction sending when simulation fails.
255
+ *
256
+ * @param walletClient - The wallet client to use
257
+ * @param params - Contract call parameters
258
+ * @param params.address - Contract address
259
+ * @param params.abi - Contract ABI
260
+ * @param params.functionName - Function to call
261
+ * @param params.args - Function arguments
262
+ * @returns Transaction hash
263
+ */
264
+ private resilientWriteContract;
265
+ /**
266
+ * Wait for transaction receipt with timeout and retry logic.
267
+ */
268
+ private waitForReceipt;
269
+ /**
270
+ * Execute an async operation with retry logic.
271
+ */
272
+ private withRetry;
273
+ /**
274
+ * Extract error message from unknown error type.
275
+ */
276
+ private extractErrorMessage;
277
+ /**
278
+ * Validate common escrow creation parameters.
279
+ */
280
+ private validateCreateEscrowParams;
281
+ /**
282
+ * Verify caller is the buyer, throw if not.
283
+ */
284
+ private verifyBuyer;
285
+ /**
286
+ * Verify caller is the seller, throw if not.
287
+ */
288
+ private verifySeller;
289
+ /**
290
+ * Verify caller is the arbiter, throw if not.
291
+ */
292
+ private verifyArbiter;
293
+ /**
294
+ * Verify escrow is in expected state, throw if not.
295
+ */
296
+ private verifyState;
297
+ /**
298
+ * Send transaction directly without simulation.
299
+ * Encodes function data manually and sends with fixed gas limit.
300
+ *
301
+ * @param walletClient - The wallet client to send from
302
+ * @param params - Contract write parameters
303
+ * @returns Transaction hash
304
+ */
305
+ private sendTransactionDirect;
306
+ /**
307
+ * Detect if error is a simulation failure (not user rejection or validation error).
308
+ *
309
+ * @param error - The error to check
310
+ * @returns True if error is from simulation failure
311
+ */
312
+ private isSimulationErrorType;
313
+ /**
314
+ * Set a value in the LRU cache with automatic eviction.
315
+ */
316
+ private setCacheValue;
317
+ /**
318
+ * Get a value from the LRU cache, refreshing its position.
319
+ */
320
+ private getCacheValue;
321
+ /**
322
+ * Get the EIP-712 domain for wallet authorization signatures
323
+ */
324
+ private getWalletDomain;
325
+ /**
326
+ * Get the EIP-712 domain for escrow contract signatures
327
+ */
328
+ private getEscrowDomain;
329
+ private readonly walletAuthorizationTypes;
330
+ private readonly confirmDeliveryTypes;
331
+ private readonly startDisputeTypes;
332
+ /**
333
+ * Sign a wallet authorization for a participant
334
+ * Used for: deposit, confirmDelivery, requestCancel, submitArbiterDecision
335
+ */
336
+ signWalletAuthorization(walletClient: EscrowWalletClient, walletAddress: Address, escrowId: bigint): Promise<Hex>;
337
+ /**
338
+ * Sign a confirm delivery message (for gasless meta-tx)
339
+ */
340
+ signConfirmDelivery(walletClient: EscrowWalletClient, escrowId: bigint, deadline: bigint, nonce: bigint): Promise<Hex>;
341
+ /**
342
+ * Sign a start dispute message (for gasless meta-tx)
343
+ */
344
+ signStartDispute(walletClient: EscrowWalletClient, escrowId: bigint, deadline: bigint, nonce: bigint): Promise<Hex>;
345
+ /**
346
+ * Create a signature deadline (timestamp + minutes)
347
+ */
348
+ createSignatureDeadline(minutesFromNow?: number): Promise<bigint>;
349
+ /**
350
+ * Check if signature deadline has expired
351
+ */
352
+ isSignatureDeadlineExpired(deadline: bigint, safetySeconds?: number): boolean;
353
+ /**
354
+ * Predict the wallet address for a given escrow ID (before creation)
355
+ */
356
+ predictWalletAddress(escrowId: bigint): Promise<Address>;
357
+ /**
358
+ * Get raw escrow data from contract
359
+ */
360
+ getEscrowById(escrowId: bigint): Promise<RawEscrowData>;
361
+ /**
362
+ * Get parsed escrow data
363
+ */
364
+ getEscrowByIdParsed(escrowId: bigint): Promise<EscrowData>;
365
+ /**
366
+ * Get next escrow ID
367
+ */
368
+ getNextEscrowId(): Promise<bigint>;
369
+ /**
370
+ * Get the nonce bitmap from the contract.
371
+ *
372
+ * Each bitmap word contains NONCE_BITMAP_SIZE nonce states. A set bit means the nonce is used.
373
+ *
374
+ * @param escrowId - The escrow ID
375
+ * @param signer - The signer's address
376
+ * @param wordIndex - The word index (nonce / NONCE_BITMAP_SIZE)
377
+ * @returns The bitmap as a bigint
378
+ */
379
+ getNonceBitmap(escrowId: bigint, signer: Address, wordIndex?: bigint): Promise<bigint>;
380
+ /**
381
+ * Check if a specific nonce has been used.
382
+ *
383
+ * @param escrowId - The escrow ID
384
+ * @param signer - The signer's address
385
+ * @param nonce - The nonce to check
386
+ * @returns True if the nonce has been used
387
+ */
388
+ isNonceUsed(escrowId: bigint, signer: Address, nonce: bigint): Promise<boolean>;
389
+ /**
390
+ * Maximum nonce word index to prevent infinite loops.
391
+ * 100 words = 25,600 nonces per escrow per signer.
392
+ */
393
+ private static readonly MAX_NONCE_WORDS;
394
+ /**
395
+ * Get the next available nonce for a signer.
396
+ *
397
+ * Queries the contract's nonce bitmap and finds the first unused nonce.
398
+ * This is the recommended way to get a nonce for signed transactions.
399
+ *
400
+ * @param escrowId - The escrow ID
401
+ * @param signer - The signer's address
402
+ * @returns The next available nonce
403
+ * @throws SDKError if nonce space is exhausted (> 25,600 nonces used)
404
+ */
405
+ getUserNonce(escrowId: bigint, signer: Address): Promise<bigint>;
406
+ /**
407
+ * Calculate estimated number of bitmap words needed for nonce count.
408
+ * Uses conservative estimate with buffer to minimize round trips.
409
+ *
410
+ * @param count - Number of nonces needed
411
+ * @returns Estimated number of bitmap words to fetch
412
+ */
413
+ private getEstimatedWordCount;
414
+ /**
415
+ * Detect if chain supports Multicall3 and cache result.
416
+ * Performs a test multicall on first invocation and caches the result.
417
+ *
418
+ * @param escrowId - Escrow ID for test call
419
+ * @param signer - Signer address for test call
420
+ */
421
+ private detectMulticallSupport;
422
+ /**
423
+ * Fetch nonce bitmaps using either multicall or sequential calls.
424
+ * Automatically uses multicall if supported, otherwise falls back to sequential.
425
+ *
426
+ * @param escrowId - The escrow ID
427
+ * @param signer - The signer's address
428
+ * @param wordCount - Number of bitmap words to fetch
429
+ * @returns Array of bitmap results with status
430
+ */
431
+ private fetchNonceBitmaps;
432
+ /**
433
+ * Scan bitmap words for available (unused) nonces.
434
+ * Performs bit-level scanning with early exit when count is reached.
435
+ *
436
+ * @param bitmapResults - Array of bitmap words fetched from contract
437
+ * @param count - Maximum number of nonces to find
438
+ * @returns Array of available nonce values
439
+ */
440
+ private scanBitmapsForNonces;
441
+ /**
442
+ * Get multiple available nonces at once (for batch operations).
443
+ *
444
+ * @param escrowId - The escrow ID
445
+ * @param signer - The signer's address
446
+ * @param count - Number of nonces to retrieve (max NONCE_BITMAP_SIZE)
447
+ * @returns Array of available nonces
448
+ * @throws SDKError if count exceeds limit or nonce space is exhausted
449
+ */
450
+ getMultipleNonces(escrowId: bigint, signer: Address, count: number): Promise<bigint[]>;
451
+ /**
452
+ * @deprecated No longer needed - nonces are tracked by the contract
453
+ */
454
+ resetNonceTracker(): void;
455
+ /**
456
+ * Get dispute submission status
457
+ */
458
+ getDisputeSubmissionStatus(escrowId: bigint): Promise<DisputeSubmissionStatus>;
459
+ getTokenDecimals(tokenAddress: Address): Promise<number>;
460
+ getTokenBalance(account: Address, tokenAddress: Address): Promise<bigint>;
461
+ getTokenAllowance(owner: Address, spender: Address, tokenAddress: Address): Promise<bigint>;
462
+ formatTokenAmount(amount: bigint, decimals: number): string;
463
+ /**
464
+ * Approve token spending if needed
465
+ */
466
+ approveTokenIfNeeded(walletClient: EscrowWalletClient, token: Address, spender: Address, amount: bigint): Promise<Hex | null>;
467
+ /**
468
+ * Create a new escrow as the seller
469
+ *
470
+ * This function creates a new escrow where the caller (seller) is offering goods/services
471
+ * to a buyer. The escrow starts in AWAITING_PAYMENT state until the buyer deposits funds.
472
+ *
473
+ * The seller's wallet authorization signature is automatically generated and attached,
474
+ * which will be used later for 2-of-3 multisig withdrawals from the escrow wallet.
475
+ *
476
+ * @param walletClient - The seller's wallet client (must have account connected)
477
+ * @param params - Escrow creation parameters
478
+ * @param params.token - ERC20 token address for payment
479
+ * @param params.buyer - Buyer's wallet address
480
+ * @param params.amount - Payment amount in token's smallest unit (e.g., wei for 18 decimals)
481
+ * @param params.maturityTimeDays - Optional days until maturity (default: 1, min: 1, max: 3650)
482
+ * @param params.arbiter - Optional arbiter address for dispute resolution
483
+ * @param params.title - Escrow title/description (1-500 characters, supports encrypted hashes)
484
+ * @param params.ipfsHash - Optional IPFS hash for additional details
485
+ * @returns Object containing escrowId, transaction hash, and wallet address
486
+ * @throws {SDKError} WALLET_NOT_CONNECTED - If wallet client is not connected
487
+ * @throws {SDKError} VALIDATION_ERROR - If parameters are invalid
488
+ * @throws {SDKError} TRANSACTION_FAILED - If the transaction fails
489
+ */
490
+ createEscrow(walletClient: EscrowWalletClient, params: CreateEscrowParams): Promise<{
491
+ escrowId: bigint;
492
+ txHash: Hex;
493
+ walletAddress: Address;
494
+ }>;
495
+ /**
496
+ * Create a new escrow and deposit funds as the buyer (single transaction)
497
+ *
498
+ * This function creates a new escrow and immediately deposits the payment in one transaction.
499
+ * The escrow starts in AWAITING_DELIVERY state. The seller must call `acceptEscrow` to
500
+ * provide their wallet signature before funds can be released.
501
+ *
502
+ * Token approval is automatically handled if needed.
503
+ *
504
+ * @param walletClient - The buyer's wallet client (must have account connected)
505
+ * @param params - Escrow creation parameters
506
+ * @param params.token - ERC20 token address for payment
507
+ * @param params.seller - Seller's wallet address
508
+ * @param params.amount - Payment amount in token's smallest unit (e.g., wei for 18 decimals)
509
+ * @param params.maturityTimeDays - Optional days until maturity (default: 1, min: 1, max: 3650)
510
+ * @param params.arbiter - Optional arbiter address for dispute resolution
511
+ * @param params.title - Escrow title/description (1-500 characters, supports encrypted hashes)
512
+ * @param params.ipfsHash - Optional IPFS hash for additional details
513
+ * @returns Object containing escrowId, transaction hash, and wallet address
514
+ * @throws {SDKError} WALLET_NOT_CONNECTED - If wallet client is not connected
515
+ * @throws {SDKError} VALIDATION_ERROR - If parameters are invalid
516
+ * @throws {SDKError} INSUFFICIENT_BALANCE - If buyer has insufficient token balance
517
+ * @throws {SDKError} TRANSACTION_FAILED - If the transaction fails
518
+ */
519
+ createEscrowAndDeposit(walletClient: EscrowWalletClient, params: CreateEscrowAndDepositParams): Promise<{
520
+ escrowId: bigint;
521
+ txHash: Hex;
522
+ walletAddress: Address;
523
+ }>;
524
+ /**
525
+ * Deposit funds into an existing escrow as the buyer
526
+ *
527
+ * This function is used when the seller created the escrow via `createEscrow`.
528
+ * The buyer deposits the required payment amount, transitioning the escrow from
529
+ * AWAITING_PAYMENT to AWAITING_DELIVERY state.
530
+ *
531
+ * Token approval is automatically handled if needed.
532
+ * The buyer's wallet authorization signature is automatically generated.
533
+ *
534
+ * @param walletClient - The buyer's wallet client (must have account connected)
535
+ * @param escrowId - The escrow ID to deposit into
536
+ * @returns Transaction hash
537
+ * @throws {SDKError} WALLET_NOT_CONNECTED - If wallet client is not connected
538
+ * @throws {SDKError} NOT_BUYER - If caller is not the designated buyer
539
+ * @throws {SDKError} INVALID_STATE - If escrow is not in AWAITING_PAYMENT state
540
+ * @throws {SDKError} INSUFFICIENT_BALANCE - If buyer has insufficient token balance
541
+ */
542
+ deposit(walletClient: EscrowWalletClient, escrowId: bigint): Promise<Hex>;
543
+ /**
544
+ * Accept an escrow as the seller (for buyer-created escrows)
545
+ *
546
+ * This function is required when the buyer created the escrow via `createEscrowAndDeposit`.
547
+ * The seller must accept to provide their wallet authorization signature, which is
548
+ * required for the 2-of-3 multisig withdrawal mechanism.
549
+ *
550
+ * Without accepting, the seller cannot receive funds even if the buyer confirms delivery.
551
+ *
552
+ * @param walletClient - The seller's wallet client (must have account connected)
553
+ * @param escrowId - The escrow ID to accept
554
+ * @returns Transaction hash
555
+ * @throws {SDKError} WALLET_NOT_CONNECTED - If wallet client is not connected
556
+ * @throws {SDKError} NOT_SELLER - If caller is not the designated seller
557
+ * @throws {SDKError} INVALID_STATE - If escrow is not in AWAITING_DELIVERY state
558
+ * @throws {SDKError} ALREADY_ACCEPTED - If escrow was already accepted
559
+ */
560
+ acceptEscrow(walletClient: EscrowWalletClient, escrowId: bigint): Promise<Hex>;
561
+ /**
562
+ * Confirm delivery and release funds to the seller
563
+ *
564
+ * This function is called by the buyer after receiving the goods/services.
565
+ * It transitions the escrow to COMPLETE state and authorizes payment release to the seller.
566
+ *
567
+ * After confirmation, anyone can call `withdraw` on the escrow wallet to execute
568
+ * the actual token transfer (requires 2-of-3 signatures: buyer + seller).
569
+ *
570
+ * A 1% fee is deducted from the payment amount.
571
+ *
572
+ * @param walletClient - The buyer's wallet client (must have account connected)
573
+ * @param escrowId - The escrow ID to confirm
574
+ * @returns Transaction hash
575
+ * @throws {SDKError} WALLET_NOT_CONNECTED - If wallet client is not connected
576
+ * @throws {SDKError} NOT_BUYER - If caller is not the designated buyer
577
+ * @throws {SDKError} INVALID_STATE - If escrow is not in AWAITING_DELIVERY state
578
+ */
579
+ confirmDelivery(walletClient: EscrowWalletClient, escrowId: bigint): Promise<Hex>;
580
+ /**
581
+ * Confirm delivery via meta-transaction (gasless for buyer)
582
+ *
583
+ * This function allows a relayer to submit the confirm delivery transaction on behalf
584
+ * of the buyer. The buyer signs the confirmation off-chain, and the relayer pays the gas.
585
+ *
586
+ * Use `prepareConfirmDeliverySigned` to generate the required signatures.
587
+ *
588
+ * @param walletClient - The relayer's wallet client (pays gas)
589
+ * @param escrowId - The escrow ID to confirm
590
+ * @param coordSignature - Buyer's EIP-712 signature for the confirmation
591
+ * @param deadline - Signature expiration timestamp (must be within 24 hours)
592
+ * @param nonce - Buyer's nonce for replay protection
593
+ * @param buyerWalletSig - Buyer's wallet authorization signature
594
+ * @returns Transaction hash
595
+ * @throws {SDKError} WALLET_NOT_CONNECTED - If wallet client is not connected
596
+ * @throws {SDKError} SIGNATURE_EXPIRED - If deadline has passed
597
+ */
598
+ confirmDeliverySigned(walletClient: EscrowWalletClient, escrowId: bigint, coordSignature: Hex, deadline: bigint, nonce: bigint, buyerWalletSig: Hex): Promise<Hex>;
599
+ /**
600
+ * Prepare signatures for gasless confirm delivery
601
+ *
602
+ * This helper function generates all the signatures needed for a gasless confirm delivery.
603
+ * The buyer signs off-chain, and the resulting data can be sent to a relayer who will
604
+ * submit the transaction and pay the gas.
605
+ *
606
+ * The deadline is set to 60 minutes from the current block timestamp.
607
+ *
608
+ * @param buyerWalletClient - The buyer's wallet client (must have account connected)
609
+ * @param escrowId - The escrow ID to confirm
610
+ * @returns Object containing coordSignature, buyerWalletSig, deadline, and nonce
611
+ * @throws {SDKError} WALLET_NOT_CONNECTED - If wallet client is not connected
612
+ * @throws {SDKError} NOT_BUYER - If caller is not the designated buyer
613
+ */
614
+ prepareConfirmDeliverySigned(buyerWalletClient: EscrowWalletClient, escrowId: bigint): Promise<{
615
+ coordSignature: Hex;
616
+ buyerWalletSig: Hex;
617
+ deadline: bigint;
618
+ nonce: bigint;
619
+ }>;
620
+ /**
621
+ * Request cancellation of an escrow
622
+ *
623
+ * This function allows either the buyer or seller to request cancellation.
624
+ * Both parties must call this function for a mutual cancellation to occur.
625
+ *
626
+ * - If only one party requests: The request is recorded, awaiting the other party
627
+ * - If both parties request: The escrow is automatically canceled and funds returned to buyer
628
+ *
629
+ * Use `getCancelRequestStatus` to check if the other party has already requested.
630
+ *
631
+ * @param walletClient - The buyer's or seller's wallet client
632
+ * @param escrowId - The escrow ID to cancel
633
+ * @returns Transaction hash
634
+ * @throws {SDKError} WALLET_NOT_CONNECTED - If wallet client is not connected
635
+ * @throws {SDKError} INVALID_ROLE - If caller is not buyer or seller
636
+ * @throws {SDKError} INVALID_STATE - If escrow is not in AWAITING_DELIVERY state
637
+ */
638
+ requestCancel(walletClient: EscrowWalletClient, escrowId: bigint): Promise<Hex>;
639
+ /**
640
+ * Cancel escrow by timeout (unilateral cancellation by buyer)
641
+ *
642
+ * This function allows the buyer to cancel the escrow unilaterally if:
643
+ * - The buyer has already requested cancellation via `requestCancel`
644
+ * - The maturity time has passed
645
+ * - The seller has not agreed to mutual cancellation
646
+ * - No dispute is active
647
+ * - An arbiter is assigned to the escrow
648
+ *
649
+ * Funds are returned to the buyer without any fee deduction.
650
+ *
651
+ * @param walletClient - The buyer's wallet client (must have account connected)
652
+ * @param escrowId - The escrow ID to cancel
653
+ * @returns Transaction hash
654
+ * @throws {SDKError} WALLET_NOT_CONNECTED - If wallet client is not connected
655
+ * @throws {SDKError} NOT_BUYER - If caller is not the designated buyer
656
+ * @throws {SDKError} INVALID_STATE - If conditions for timeout cancel are not met
657
+ */
658
+ cancelByTimeout(walletClient: EscrowWalletClient, escrowId: bigint): Promise<Hex>;
659
+ /**
660
+ * Auto-release funds to seller after maturity time
661
+ *
662
+ * This function allows the seller to claim funds unilaterally after the maturity time
663
+ * has passed. This protects sellers when buyers become unresponsive after receiving
664
+ * goods/services.
665
+ *
666
+ * Requirements:
667
+ * - Escrow must be in AWAITING_DELIVERY state
668
+ * - No dispute has been started
669
+ * - Buyer has not requested cancellation
670
+ * - maturityTime has passed
671
+ * - Seller has already provided wallet signature (via createEscrow or acceptEscrow)
672
+ *
673
+ * A 1% fee is deducted from the payment amount.
674
+ *
675
+ * @param walletClient - The seller's wallet client (must have account connected)
676
+ * @param escrowId - The escrow ID to auto-release
677
+ * @returns Transaction hash
678
+ * @throws {SDKError} WALLET_NOT_CONNECTED - If wallet client is not connected
679
+ * @throws {SDKError} NOT_SELLER - If caller is not the designated seller
680
+ * @throws {SDKError} INVALID_STATE - If escrow is not in AWAITING_DELIVERY state
681
+ * @throws {SDKError} INVALID_STATE - If dispute is active or buyer requested cancel
682
+ * @throws {SDKError} VALIDATION_ERROR - If seller wallet signature is missing
683
+ */
684
+ autoRelease(walletClient: EscrowWalletClient, escrowId: bigint): Promise<Hex>;
685
+ /**
686
+ * Start a dispute for an escrow
687
+ *
688
+ * This function initiates a dispute when there's a disagreement between buyer and seller.
689
+ * Once started, the escrow enters DISPUTED state and requires arbiter resolution.
690
+ *
691
+ * Either the buyer or seller can start a dispute. An arbiter must be assigned to the
692
+ * escrow for disputes to be possible.
693
+ *
694
+ * After starting a dispute:
695
+ * 1. Both parties should submit evidence via `submitDisputeMessage`
696
+ * 2. The arbiter reviews evidence and makes a decision via `submitArbiterDecision`
697
+ * 3. The arbiter can rule in favor of buyer (REFUNDED) or seller (COMPLETE)
698
+ *
699
+ * @param walletClient - The buyer's or seller's wallet client
700
+ * @param escrowId - The escrow ID to dispute
701
+ * @returns Transaction hash
702
+ * @throws {SDKError} WALLET_NOT_CONNECTED - If wallet client is not connected
703
+ * @throws {SDKError} INVALID_STATE - If escrow is not in AWAITING_DELIVERY state
704
+ */
705
+ startDispute(walletClient: EscrowWalletClient, escrowId: bigint): Promise<Hex>;
706
+ /**
707
+ * Start a dispute via meta-transaction (gasless for buyer/seller)
708
+ *
709
+ * This function allows a relayer to submit the start dispute transaction on behalf
710
+ * of the buyer or seller. The initiator signs off-chain, and the relayer pays the gas.
711
+ *
712
+ * Use `signStartDispute` to generate the required signature.
713
+ *
714
+ * @param walletClient - The relayer's wallet client (pays gas)
715
+ * @param escrowId - The escrow ID to dispute
716
+ * @param signature - Buyer's or seller's EIP-712 signature
717
+ * @param deadline - Signature expiration timestamp (must be within 24 hours)
718
+ * @param nonce - Signer's nonce for replay protection
719
+ * @returns Transaction hash
720
+ * @throws {SDKError} WALLET_NOT_CONNECTED - If wallet client is not connected
721
+ * @throws {SDKError} SIGNATURE_EXPIRED - If deadline has passed
722
+ */
723
+ startDisputeSigned(walletClient: EscrowWalletClient, escrowId: bigint, signature: Hex, deadline: bigint, nonce: bigint): Promise<Hex>;
724
+ /**
725
+ * Submit evidence for a dispute
726
+ *
727
+ * This function allows the buyer or seller to submit evidence supporting their case.
728
+ * Each party can only submit evidence once. Evidence is stored on IPFS and the hash
729
+ * is recorded on-chain.
730
+ *
731
+ * The arbiter will review submitted evidence before making a decision. Both parties
732
+ * should submit evidence for a fair resolution. After 30 days, the arbiter can make
733
+ * a decision even without complete evidence.
734
+ *
735
+ * @param walletClient - The buyer's or seller's wallet client
736
+ * @param escrowId - The escrow ID
737
+ * @param role - The caller's role (Role.Buyer or Role.Seller)
738
+ * @param ipfsHash - IPFS hash containing the evidence (max 500 characters)
739
+ * @returns Transaction hash
740
+ * @throws {SDKError} WALLET_NOT_CONNECTED - If wallet client is not connected
741
+ * @throws {SDKError} EVIDENCE_ALREADY_SUBMITTED - If caller already submitted evidence
742
+ * @throws {SDKError} INVALID_STATE - If escrow is not in DISPUTED state
743
+ */
744
+ submitDisputeMessage(walletClient: EscrowWalletClient, escrowId: bigint, role: Role.Buyer | Role.Seller, ipfsHash: string): Promise<Hex>;
745
+ /**
746
+ * Submit arbiter's decision to resolve a dispute
747
+ *
748
+ * This function is called by the designated arbiter to resolve a dispute.
749
+ * The arbiter reviews evidence submitted by both parties and makes a final decision.
750
+ *
751
+ * The arbiter can rule:
752
+ * - DisputeResolution.Complete (3): Funds go to seller (with 1% fee)
753
+ * - DisputeResolution.Refunded (4): Funds go to buyer (no fee)
754
+ *
755
+ * Requirements:
756
+ * - Both parties must have submitted evidence, OR
757
+ * - 30 days + 1 hour timeout has passed since dispute started
758
+ *
759
+ * The arbiter's wallet signature is automatically generated for the multisig.
760
+ *
761
+ * @param walletClient - The arbiter's wallet client (must have account connected)
762
+ * @param escrowId - The escrow ID to resolve
763
+ * @param resolution - DisputeResolution.Complete or DisputeResolution.Refunded
764
+ * @param ipfsHash - IPFS hash containing the decision explanation
765
+ * @returns Transaction hash
766
+ * @throws {SDKError} WALLET_NOT_CONNECTED - If wallet client is not connected
767
+ * @throws {SDKError} NOT_ARBITER - If caller is not the designated arbiter
768
+ * @throws {SDKError} INVALID_STATE - If escrow is not in DISPUTED state
769
+ */
770
+ submitArbiterDecision(walletClient: EscrowWalletClient, escrowId: bigint, resolution: DisputeResolution, ipfsHash: string): Promise<Hex>;
771
+ /**
772
+ * Withdraw funds from the escrow wallet
773
+ *
774
+ * This function executes the actual token transfer from the escrow wallet to the
775
+ * designated recipient. The wallet contract uses a 2-of-3 multisig mechanism:
776
+ *
777
+ * - COMPLETE state: Requires buyer + seller signatures → funds go to seller
778
+ * - REFUNDED state: Requires buyer + arbiter signatures → funds go to buyer
779
+ * - CANCELED state: Requires buyer + seller signatures → funds go to buyer
780
+ *
781
+ * Anyone can call this function (typically the recipient), as the signatures
782
+ * were already collected during the escrow lifecycle. The wallet contract
783
+ * automatically reads and verifies signatures from the escrow contract.
784
+ *
785
+ * @param walletClient - Any wallet client (typically the recipient)
786
+ * @param escrowId - The escrow ID to withdraw from
787
+ * @returns Transaction hash
788
+ * @throws {SDKError} WALLET_NOT_CONNECTED - If wallet client is not connected
789
+ * @throws {SDKError} INVALID_STATE - If escrow is not in a final state (COMPLETE/REFUNDED/CANCELED)
790
+ */
791
+ withdraw(walletClient: EscrowWalletClient, escrowId: bigint): Promise<Hex>;
792
+ /**
793
+ * Get valid signature count for wallet
794
+ */
795
+ getWalletSignatureCount(escrowId: bigint): Promise<number>;
796
+ /**
797
+ * Get wallet balance
798
+ */
799
+ getWalletBalance(escrowId: bigint): Promise<bigint>;
800
+ getEscrows(): Promise<Escrow[]>;
801
+ getEscrowsByBuyer(buyer: string): Promise<Escrow[]>;
802
+ getEscrowsBySeller(seller: string): Promise<Escrow[]>;
803
+ getEscrowDetail(id: string): Promise<Escrow | undefined>;
804
+ getDisputeMessages(escrowId: string): Promise<any[]>;
805
+ /**
806
+ * Get a human-readable status label with color and description for an escrow state.
807
+ * This is useful for displaying escrow status in UIs.
808
+ *
809
+ * @param state - The escrow state enum value
810
+ * @returns An object containing:
811
+ * - label: Human-readable status name
812
+ * - color: Suggested UI color (orange, blue, red, green, gray)
813
+ * - description: Detailed explanation of what this state means
814
+ *
815
+ * @example
816
+ * ```typescript
817
+ * const sdk = new PalindromeEscrowSDK(...);
818
+ * const escrow = await sdk.getEscrowByIdParsed(1n);
819
+ * const status = sdk.getStatusLabel(escrow.state);
820
+ * console.log(status.label); // "Awaiting Payment"
821
+ * console.log(status.color); // "orange"
822
+ * console.log(status.description); // "Buyer needs to deposit funds"
823
+ * ```
824
+ */
825
+ getStatusLabel(state: EscrowState): {
826
+ label: string;
827
+ color: string;
828
+ description: string;
829
+ };
830
+ /**
831
+ * Get user role for an escrow
832
+ */
833
+ getUserRole(userAddress: Address, escrow: EscrowData): Role;
834
+ /**
835
+ * Simulate a transaction before executing
836
+ * Returns success status, gas estimate, and revert reason if failed
837
+ */
838
+ simulateTransaction(walletClient: EscrowWalletClient, functionName: string, args: any[], contractAddress?: Address): Promise<{
839
+ success: boolean;
840
+ gasEstimate?: bigint;
841
+ revertReason?: string;
842
+ result?: any;
843
+ }>;
844
+ /**
845
+ * Simulate deposit before executing
846
+ */
847
+ simulateDeposit(walletClient: EscrowWalletClient, escrowId: bigint): Promise<{
848
+ success: boolean;
849
+ gasEstimate?: bigint;
850
+ revertReason?: string;
851
+ needsApproval?: boolean;
852
+ approvalAmount?: bigint;
853
+ }>;
854
+ /**
855
+ * Simulate confirm delivery before executing
856
+ */
857
+ simulateConfirmDelivery(walletClient: EscrowWalletClient, escrowId: bigint): Promise<{
858
+ success: boolean;
859
+ gasEstimate?: bigint;
860
+ revertReason?: string;
861
+ }>;
862
+ /**
863
+ * Simulate withdraw before executing
864
+ */
865
+ simulateWithdraw(walletClient: EscrowWalletClient, escrowId: bigint): Promise<{
866
+ success: boolean;
867
+ gasEstimate?: bigint;
868
+ revertReason?: string;
869
+ signatureCount?: number;
870
+ }>;
871
+ /**
872
+ * Estimate gas for a transaction with buffer
873
+ */
874
+ estimateGasWithBuffer(walletClient: EscrowWalletClient, functionName: string, args: any[], contractAddress?: Address): Promise<bigint>;
875
+ /**
876
+ * Health check
877
+ */
878
+ healthCheck(): Promise<{
879
+ rpcConnected: boolean;
880
+ contractDeployed: boolean;
881
+ subgraphConnected: boolean;
882
+ errors: string[];
883
+ }>;
884
+ /**
885
+ * Get escrow status with optional caching
886
+ */
887
+ getEscrowStatus(escrowId: bigint, forceRefresh?: boolean): Promise<{
888
+ state: EscrowState;
889
+ stateName: string;
890
+ label: string;
891
+ color: string;
892
+ description: string;
893
+ }>;
894
+ /**
895
+ * Get cache statistics
896
+ */
897
+ getCacheStats(): {
898
+ escrowCacheSize: number;
899
+ tokenDecimalsCacheSize: number;
900
+ };
901
+ /**
902
+ * Clear all caches
903
+ */
904
+ clearAllCaches(): void;
905
+ /**
906
+ * Clear escrow cache only
907
+ */
908
+ clearEscrowCache(): void;
909
+ /**
910
+ * Clear multicall cache (useful when switching chains)
911
+ */
912
+ clearMulticallCache(): void;
913
+ /**
914
+ * Watch for escrow events related to a user
915
+ */
916
+ watchUserEscrows(userAddress: Address, callback: (escrowId: bigint, event: EscrowCreatedEvent) => void, options?: {
917
+ fromBlock?: bigint;
918
+ }): {
919
+ dispose: () => void;
920
+ };
921
+ /**
922
+ * Watch for state changes on a specific escrow
923
+ */
924
+ watchEscrowStateChanges(escrowId: bigint, callback: (newState: EscrowState, previousState: EscrowState) => void, options?: {
925
+ pollingInterval?: number;
926
+ }): {
927
+ dispose: () => void;
928
+ };
929
+ /**
930
+ * Check if user has submitted evidence for a dispute
931
+ */
932
+ hasSubmittedEvidence(escrowId: bigint, role: Role): Promise<boolean>;
933
+ /**
934
+ * Get cancellation request status for an escrow
935
+ *
936
+ * This helper function checks whether the buyer and/or seller have requested
937
+ * cancellation. Use this to determine if mutual cancellation is pending or complete.
938
+ *
939
+ * Cancellation flow:
940
+ * - Either party calls `requestCancel` to initiate
941
+ * - If only one party requested, the other must also call `requestCancel` for mutual cancel
942
+ * - When both request, the escrow is automatically canceled and funds return to buyer
943
+ * - Alternatively, buyer can use `cancelByTimeout` after maturity time (if arbiter is set)
944
+ *
945
+ * @param escrowId - The escrow ID to check
946
+ * @returns Object with buyer/seller cancel request status and whether mutual cancel is complete
947
+ */
948
+ getCancelRequestStatus(escrowId: bigint): Promise<{
949
+ buyerRequested: boolean;
950
+ sellerRequested: boolean;
951
+ mutualCancelComplete: boolean;
952
+ }>;
953
+ /**
954
+ * Get user balances for multiple tokens (batched for performance).
955
+ * Uses Promise.all to fetch all balances and decimals in parallel.
956
+ */
957
+ getUserBalances(userAddress: Address, tokens: Address[]): Promise<Map<Address, {
958
+ balance: bigint;
959
+ decimals: number;
960
+ formatted: string;
961
+ }>>;
962
+ /**
963
+ * Get maturity info for an escrow
964
+ */
965
+ getMaturityInfo(depositTime: bigint, maturityDays: bigint): {
966
+ hasDeadline: boolean;
967
+ maturityDays: number;
968
+ maturityTimestamp: bigint;
969
+ isPassed: boolean;
970
+ remainingSeconds: number;
971
+ };
972
+ /**
973
+ * Get all escrows for a user (as buyer or seller)
974
+ */
975
+ getUserEscrows(userAddress: Address): Promise<Escrow[]>;
976
+ /**
977
+ * Check if a user can deposit to an escrow.
978
+ * A user can deposit if:
979
+ * - The escrow exists and is in AWAITING_PAYMENT state
980
+ * - The user is either the buyer or seller
981
+ *
982
+ * @param userAddress - The address of the user to check
983
+ * @param escrowId - The escrow ID to check
984
+ * @returns True if the user can deposit, false otherwise
985
+ */
986
+ canUserDeposit(userAddress: Address, escrowId: bigint): Promise<boolean>;
987
+ /**
988
+ * Check if a user can accept an escrow (seller accepting after buyer deposit).
989
+ * A user can accept if:
990
+ * - The escrow is in AWAITING_DELIVERY state
991
+ * - The user is the seller
992
+ *
993
+ * @param userAddress - The address of the user to check
994
+ * @param escrowId - The escrow ID to check
995
+ * @returns True if the user can accept, false otherwise
996
+ */
997
+ canUserAcceptEscrow(userAddress: Address, escrowId: bigint): Promise<boolean>;
998
+ /**
999
+ * Check if a user can confirm delivery (buyer confirming receipt).
1000
+ * A user can confirm delivery if:
1001
+ * - The escrow is in AWAITING_DELIVERY or DISPUTED state
1002
+ * - The user is the buyer
1003
+ *
1004
+ * @param userAddress - The address of the user to check
1005
+ * @param escrowId - The escrow ID to check
1006
+ * @returns True if the user can confirm delivery, false otherwise
1007
+ */
1008
+ canUserConfirmDelivery(userAddress: Address, escrowId: bigint): Promise<boolean>;
1009
+ /**
1010
+ * Check if a user can start a dispute.
1011
+ * A user can start a dispute if:
1012
+ * - The escrow is in AWAITING_DELIVERY state
1013
+ * - The escrow has an arbiter set
1014
+ * - The user is either the buyer or seller
1015
+ *
1016
+ * @param userAddress - The address of the user to check
1017
+ * @param escrowId - The escrow ID to check
1018
+ * @returns True if the user can start a dispute, false otherwise
1019
+ */
1020
+ canUserStartDispute(userAddress: Address, escrowId: bigint): Promise<boolean>;
1021
+ /**
1022
+ * Check if an escrow can be withdrawn (auto-release check).
1023
+ * An escrow can be withdrawn if:
1024
+ * - It's in AWAITING_DELIVERY state
1025
+ * - The maturity time has passed (if deadline is set)
1026
+ *
1027
+ * @param escrowId - The escrow ID to check
1028
+ * @returns True if the escrow can be withdrawn, false otherwise
1029
+ */
1030
+ canUserWithdraw(escrowId: bigint): Promise<boolean>;
1031
+ /**
1032
+ * Check if a seller can perform auto-release.
1033
+ * A seller can auto-release if:
1034
+ * - The escrow is in AWAITING_DELIVERY state
1035
+ * - The maturity time has passed (if deadline is set)
1036
+ * - The user is the seller
1037
+ *
1038
+ * @param userAddress - The address of the user to check
1039
+ * @param escrowId - The escrow ID to check
1040
+ * @returns True if the seller can auto-release, false otherwise
1041
+ */
1042
+ canSellerAutoRelease(userAddress: Address, escrowId: bigint): Promise<boolean>;
1043
+ /**
1044
+ * Check if an address is the buyer in an escrow.
1045
+ *
1046
+ * @param userAddress - The address to check
1047
+ * @param escrow - The escrow data
1048
+ * @returns True if the address is the buyer
1049
+ */
1050
+ isBuyer(userAddress: Address, escrow: EscrowData): boolean;
1051
+ /**
1052
+ * Check if an address is the seller in an escrow.
1053
+ *
1054
+ * @param userAddress - The address to check
1055
+ * @param escrow - The escrow data
1056
+ * @returns True if the address is the seller
1057
+ */
1058
+ isSeller(userAddress: Address, escrow: EscrowData): boolean;
1059
+ /**
1060
+ * Check if an address is the arbiter in an escrow.
1061
+ *
1062
+ * @param userAddress - The address to check
1063
+ * @param escrow - The escrow data
1064
+ * @returns True if the address is the arbiter
1065
+ */
1066
+ isArbiter(userAddress: Address, escrow: EscrowData): boolean;
1067
+ /**
1068
+ * Check if an escrow has an arbiter set.
1069
+ *
1070
+ * @param escrow - The escrow data
1071
+ * @returns True if the escrow has an arbiter (non-zero address)
1072
+ */
1073
+ hasArbiter(escrow: EscrowData): boolean;
1074
+ /**
1075
+ * Compare two addresses for equality (case-insensitive, normalized).
1076
+ * This is a public utility method that can be used to compare Ethereum addresses.
1077
+ *
1078
+ * @param a - First address to compare
1079
+ * @param b - Second address to compare
1080
+ * @returns True if the addresses are equal (case-insensitive)
1081
+ *
1082
+ * @example
1083
+ * ```typescript
1084
+ * const sdk = new PalindromeEscrowSDK(...);
1085
+ * const areEqual = sdk.addressEquals(
1086
+ * "0xabc...",
1087
+ * "0xABC..."
1088
+ * ); // true
1089
+ * ```
1090
+ */
1091
+ addressEquals(a: Address | string, b: Address | string): boolean;
1092
+ /**
1093
+ * Get current gas price information from the network.
1094
+ * Returns standard, fast, and instant gas price estimates in gwei.
1095
+ *
1096
+ * @returns Object containing gas price estimates
1097
+ *
1098
+ * @example
1099
+ * ```typescript
1100
+ * const gasPrice = await sdk.getCurrentGasPrice();
1101
+ * console.log(`Standard: ${gasPrice.standard} gwei`);
1102
+ * console.log(`Fast: ${gasPrice.fast} gwei`);
1103
+ * console.log(`Instant: ${gasPrice.instant} gwei`);
1104
+ * ```
1105
+ */
1106
+ getCurrentGasPrice(): Promise<{
1107
+ standard: bigint;
1108
+ fast: bigint;
1109
+ instant: bigint;
1110
+ wei: bigint;
1111
+ }>;
1112
+ /**
1113
+ * Estimate gas cost for creating an escrow.
1114
+ *
1115
+ * @param params - Create escrow parameters
1116
+ * @returns Gas estimation details
1117
+ *
1118
+ * @example
1119
+ * ```typescript
1120
+ * const estimate = await sdk.estimateGasForCreateEscrow({
1121
+ * token: tokenAddress,
1122
+ * buyer: buyerAddress,
1123
+ * amount: 1000000n,
1124
+ * maturityDays: 7n,
1125
+ * arbiter: zeroAddress,
1126
+ * title: 'Test',
1127
+ * ipfsHash: ''
1128
+ * });
1129
+ * console.log(`Gas limit: ${estimate.gasLimit}`);
1130
+ * console.log(`Cost: ${estimate.estimatedCostEth} ETH`);
1131
+ * ```
1132
+ */
1133
+ estimateGasForCreateEscrow(params: {
1134
+ token: Address;
1135
+ buyer: Address;
1136
+ amount: bigint;
1137
+ maturityDays: bigint;
1138
+ arbiter: Address;
1139
+ title: string;
1140
+ ipfsHash: string;
1141
+ }): Promise<{
1142
+ gasLimit: bigint;
1143
+ estimatedCostWei: bigint;
1144
+ estimatedCostEth: string;
1145
+ }>;
1146
+ /**
1147
+ * Estimate gas cost for depositing to an escrow.
1148
+ *
1149
+ * @param escrowId - The escrow ID
1150
+ * @returns Gas estimation details
1151
+ *
1152
+ * @example
1153
+ * ```typescript
1154
+ * const estimate = await sdk.estimateGasForDeposit(escrowId);
1155
+ * console.log(`Gas limit: ${estimate.gasLimit}`);
1156
+ * ```
1157
+ */
1158
+ estimateGasForDeposit(escrowId: bigint): Promise<{
1159
+ gasLimit: bigint;
1160
+ estimatedCostWei: bigint;
1161
+ estimatedCostEth: string;
1162
+ }>;
1163
+ /**
1164
+ * Estimate gas cost for confirming delivery.
1165
+ *
1166
+ * @param escrowId - The escrow ID
1167
+ * @returns Gas estimation details
1168
+ *
1169
+ * @example
1170
+ * ```typescript
1171
+ * const estimate = await sdk.estimateGasForConfirmDelivery(escrowId);
1172
+ * console.log(`Cost: ${estimate.estimatedCostEth} ETH`);
1173
+ * ```
1174
+ */
1175
+ estimateGasForConfirmDelivery(escrowId: bigint): Promise<{
1176
+ gasLimit: bigint;
1177
+ estimatedCostWei: bigint;
1178
+ estimatedCostEth: string;
1179
+ }>;
1180
+ /**
1181
+ * Estimate gas cost for withdrawing from escrow wallet.
1182
+ *
1183
+ * @returns Gas estimation details
1184
+ *
1185
+ * @example
1186
+ * ```typescript
1187
+ * const estimate = await sdk.estimateGasForWithdraw();
1188
+ * ```
1189
+ */
1190
+ estimateGasForWithdraw(): Promise<{
1191
+ gasLimit: bigint;
1192
+ estimatedCostWei: bigint;
1193
+ estimatedCostEth: string;
1194
+ }>;
1195
+ /**
1196
+ * Get fee receiver address (cached - rarely changes)
1197
+ * @param forceRefresh - Set to true to bypass cache and fetch fresh value
1198
+ */
1199
+ getFeeReceiver(forceRefresh?: boolean): Promise<Address>;
1200
+ /** Cached fee basis points (lazily computed from contract) */
1201
+ private cachedFeeBps;
1202
+ /**
1203
+ * Get fee percentage in basis points.
1204
+ * Tries to read FEE_BPS from contract, falls back to default (100 = 1%).
1205
+ * Result is cached for performance.
1206
+ */
1207
+ getFeeBps(): Promise<bigint>;
1208
+ /**
1209
+ * Calculate fee for an amount.
1210
+ * Uses the same logic as the contract's _computeFeeAndNet.
1211
+ */
1212
+ calculateFee(amount: bigint, tokenDecimals?: number): Promise<{
1213
+ fee: bigint;
1214
+ net: bigint;
1215
+ }>;
1216
+ }
1217
+ export default PalindromeEscrowSDK;