@agirails/sdk 2.5.2 → 2.5.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.
Files changed (172) hide show
  1. package/dist/ACTPClient.d.ts +18 -0
  2. package/dist/ACTPClient.d.ts.map +1 -1
  3. package/dist/ACTPClient.js +67 -22
  4. package/dist/ACTPClient.js.map +1 -1
  5. package/dist/adapters/BasicAdapter.d.ts +12 -0
  6. package/dist/adapters/BasicAdapter.d.ts.map +1 -1
  7. package/dist/adapters/BasicAdapter.js +30 -4
  8. package/dist/adapters/BasicAdapter.js.map +1 -1
  9. package/dist/adapters/StandardAdapter.d.ts +20 -3
  10. package/dist/adapters/StandardAdapter.d.ts.map +1 -1
  11. package/dist/adapters/StandardAdapter.js +45 -11
  12. package/dist/adapters/StandardAdapter.js.map +1 -1
  13. package/dist/cli/commands/publish.js +16 -4
  14. package/dist/cli/commands/publish.js.map +1 -1
  15. package/dist/cli/commands/register.js +16 -4
  16. package/dist/cli/commands/register.js.map +1 -1
  17. package/dist/cli/commands/tx.js +31 -3
  18. package/dist/cli/commands/tx.js.map +1 -1
  19. package/dist/cli/utils/client.d.ts.map +1 -1
  20. package/dist/cli/utils/client.js +1 -0
  21. package/dist/cli/utils/client.js.map +1 -1
  22. package/dist/config/networks.d.ts +2 -2
  23. package/dist/config/networks.d.ts.map +1 -1
  24. package/dist/config/networks.js +27 -22
  25. package/dist/config/networks.js.map +1 -1
  26. package/dist/level0/request.d.ts.map +1 -1
  27. package/dist/level0/request.js +2 -1
  28. package/dist/level0/request.js.map +1 -1
  29. package/dist/runtime/BlockchainRuntime.d.ts.map +1 -1
  30. package/dist/runtime/BlockchainRuntime.js +11 -5
  31. package/dist/runtime/BlockchainRuntime.js.map +1 -1
  32. package/dist/runtime/MockStateManager.d.ts.map +1 -1
  33. package/dist/runtime/MockStateManager.js +2 -1
  34. package/dist/runtime/MockStateManager.js.map +1 -1
  35. package/dist/utils/IPFSClient.d.ts +3 -1
  36. package/dist/utils/IPFSClient.d.ts.map +1 -1
  37. package/dist/utils/IPFSClient.js +27 -7
  38. package/dist/utils/IPFSClient.js.map +1 -1
  39. package/dist/wallet/AutoWalletProvider.d.ts.map +1 -1
  40. package/dist/wallet/AutoWalletProvider.js +52 -18
  41. package/dist/wallet/AutoWalletProvider.js.map +1 -1
  42. package/dist/wallet/SmartWalletRouter.d.ts +116 -0
  43. package/dist/wallet/SmartWalletRouter.d.ts.map +1 -0
  44. package/dist/wallet/SmartWalletRouter.js +212 -0
  45. package/dist/wallet/SmartWalletRouter.js.map +1 -0
  46. package/dist/wallet/aa/DualNonceManager.d.ts +19 -0
  47. package/dist/wallet/aa/DualNonceManager.d.ts.map +1 -1
  48. package/dist/wallet/aa/DualNonceManager.js +100 -5
  49. package/dist/wallet/aa/DualNonceManager.js.map +1 -1
  50. package/package.json +3 -6
  51. package/src/ACTPClient.ts +0 -1579
  52. package/src/abi/ACTPKernel.json +0 -1356
  53. package/src/abi/AgentRegistry.json +0 -915
  54. package/src/abi/ERC20.json +0 -40
  55. package/src/abi/EscrowVault.json +0 -134
  56. package/src/abi/IdentityRegistry.json +0 -316
  57. package/src/adapters/AdapterRegistry.ts +0 -173
  58. package/src/adapters/AdapterRouter.ts +0 -416
  59. package/src/adapters/BaseAdapter.ts +0 -498
  60. package/src/adapters/BasicAdapter.ts +0 -514
  61. package/src/adapters/IAdapter.ts +0 -292
  62. package/src/adapters/StandardAdapter.ts +0 -555
  63. package/src/adapters/X402Adapter.ts +0 -731
  64. package/src/adapters/index.ts +0 -60
  65. package/src/builders/DeliveryProofBuilder.ts +0 -327
  66. package/src/builders/QuoteBuilder.ts +0 -483
  67. package/src/builders/index.ts +0 -17
  68. package/src/cli/commands/balance.ts +0 -110
  69. package/src/cli/commands/batch.ts +0 -487
  70. package/src/cli/commands/config.ts +0 -231
  71. package/src/cli/commands/deploy-check.ts +0 -364
  72. package/src/cli/commands/deploy-env.ts +0 -120
  73. package/src/cli/commands/diff.ts +0 -141
  74. package/src/cli/commands/init.ts +0 -469
  75. package/src/cli/commands/mint.ts +0 -116
  76. package/src/cli/commands/pay.ts +0 -113
  77. package/src/cli/commands/publish.ts +0 -475
  78. package/src/cli/commands/pull.ts +0 -124
  79. package/src/cli/commands/register.ts +0 -247
  80. package/src/cli/commands/simulate.ts +0 -345
  81. package/src/cli/commands/time.ts +0 -302
  82. package/src/cli/commands/tx.ts +0 -448
  83. package/src/cli/commands/watch.ts +0 -211
  84. package/src/cli/index.ts +0 -134
  85. package/src/cli/utils/client.ts +0 -251
  86. package/src/cli/utils/config.ts +0 -389
  87. package/src/cli/utils/output.ts +0 -465
  88. package/src/cli/utils/wallet.ts +0 -109
  89. package/src/config/agirailsmd.ts +0 -262
  90. package/src/config/networks.ts +0 -275
  91. package/src/config/pendingPublish.ts +0 -237
  92. package/src/config/publishPipeline.ts +0 -359
  93. package/src/config/syncOperations.ts +0 -279
  94. package/src/erc8004/ERC8004Bridge.ts +0 -462
  95. package/src/erc8004/ReputationReporter.ts +0 -468
  96. package/src/erc8004/index.ts +0 -61
  97. package/src/errors/index.ts +0 -427
  98. package/src/index.ts +0 -364
  99. package/src/level0/Provider.ts +0 -117
  100. package/src/level0/ServiceDirectory.ts +0 -131
  101. package/src/level0/index.ts +0 -10
  102. package/src/level0/provide.ts +0 -132
  103. package/src/level0/request.ts +0 -432
  104. package/src/level1/Agent.ts +0 -1426
  105. package/src/level1/index.ts +0 -10
  106. package/src/level1/pricing/PriceCalculator.ts +0 -255
  107. package/src/level1/pricing/PricingStrategy.ts +0 -198
  108. package/src/level1/types/Job.ts +0 -179
  109. package/src/level1/types/Options.ts +0 -291
  110. package/src/level1/types/index.ts +0 -8
  111. package/src/protocol/ACTPKernel.ts +0 -808
  112. package/src/protocol/AgentRegistry.ts +0 -559
  113. package/src/protocol/DIDManager.ts +0 -629
  114. package/src/protocol/DIDResolver.ts +0 -554
  115. package/src/protocol/EASHelper.ts +0 -378
  116. package/src/protocol/EscrowVault.ts +0 -255
  117. package/src/protocol/EventMonitor.ts +0 -204
  118. package/src/protocol/MessageSigner.ts +0 -510
  119. package/src/protocol/ProofGenerator.ts +0 -339
  120. package/src/protocol/QuoteBuilder.ts +0 -15
  121. package/src/registry/AgentRegistryClient.ts +0 -202
  122. package/src/runtime/BlockchainRuntime.ts +0 -1015
  123. package/src/runtime/IACTPRuntime.ts +0 -306
  124. package/src/runtime/MockRuntime.ts +0 -1298
  125. package/src/runtime/MockStateManager.ts +0 -576
  126. package/src/runtime/index.ts +0 -25
  127. package/src/runtime/types/MockState.ts +0 -237
  128. package/src/storage/ArchiveBundleBuilder.ts +0 -561
  129. package/src/storage/ArweaveClient.ts +0 -946
  130. package/src/storage/FilebaseClient.ts +0 -790
  131. package/src/storage/index.ts +0 -96
  132. package/src/storage/types.ts +0 -348
  133. package/src/types/adapter.ts +0 -310
  134. package/src/types/agent.ts +0 -79
  135. package/src/types/did.ts +0 -223
  136. package/src/types/eip712.ts +0 -175
  137. package/src/types/erc8004.ts +0 -293
  138. package/src/types/escrow.ts +0 -27
  139. package/src/types/index.ts +0 -17
  140. package/src/types/message.ts +0 -145
  141. package/src/types/state.ts +0 -87
  142. package/src/types/transaction.ts +0 -69
  143. package/src/types/x402.ts +0 -251
  144. package/src/utils/ErrorRecoveryGuide.ts +0 -676
  145. package/src/utils/Helpers.ts +0 -688
  146. package/src/utils/IPFSClient.ts +0 -368
  147. package/src/utils/Logger.ts +0 -484
  148. package/src/utils/NonceManager.ts +0 -591
  149. package/src/utils/RateLimiter.ts +0 -534
  150. package/src/utils/ReceivedNonceTracker.ts +0 -567
  151. package/src/utils/SDKLifecycle.ts +0 -416
  152. package/src/utils/SecureNonce.ts +0 -78
  153. package/src/utils/Semaphore.ts +0 -276
  154. package/src/utils/UsedAttestationTracker.ts +0 -385
  155. package/src/utils/canonicalJson.ts +0 -38
  156. package/src/utils/circuitBreaker.ts +0 -324
  157. package/src/utils/computeTypeHash.ts +0 -48
  158. package/src/utils/fsSafe.ts +0 -80
  159. package/src/utils/index.ts +0 -80
  160. package/src/utils/retry.ts +0 -364
  161. package/src/utils/security.ts +0 -418
  162. package/src/utils/validation.ts +0 -540
  163. package/src/wallet/AutoWalletProvider.ts +0 -299
  164. package/src/wallet/EOAWalletProvider.ts +0 -69
  165. package/src/wallet/IWalletProvider.ts +0 -135
  166. package/src/wallet/aa/BundlerClient.ts +0 -274
  167. package/src/wallet/aa/DualNonceManager.ts +0 -173
  168. package/src/wallet/aa/PaymasterClient.ts +0 -174
  169. package/src/wallet/aa/TransactionBatcher.ts +0 -353
  170. package/src/wallet/aa/UserOpBuilder.ts +0 -246
  171. package/src/wallet/aa/constants.ts +0 -60
  172. package/src/wallet/keystore.ts +0 -240
@@ -1,514 +0,0 @@
1
- /**
2
- * BasicAdapter - High-level, opinionated API for simple use cases
3
- *
4
- * Provides the simplest possible interface for creating and checking transactions.
5
- * Designed for developers who want to "just make it work" without deep protocol knowledge.
6
- *
7
- * Key Features:
8
- * - Smart defaults (24h deadline, 2-day dispute window)
9
- * - Inferred requester (from constructor)
10
- * - User-friendly input (strings, no BigInt)
11
- * - User-friendly output (formatted amounts, ISO dates)
12
- *
13
- * @module adapters/BasicAdapter
14
- */
15
-
16
- import { BaseAdapter, ValidationError } from './BaseAdapter';
17
- import { IACTPRuntime } from '../runtime/IACTPRuntime';
18
- import { EASHelper } from '../protocol/EASHelper';
19
- import { IAdapter, TransactionStatus } from './IAdapter';
20
- import {
21
- AdapterMetadata,
22
- UnifiedPayParams,
23
- UnifiedPayResult,
24
- } from '../types/adapter';
25
- import { IWalletProvider } from '../wallet/IWalletProvider';
26
- import { SmartWalletCall } from '../wallet/aa/constants';
27
- import { ethers } from 'ethers';
28
-
29
- /**
30
- * Interface for lazy publish activation call provider.
31
- * ACTPClient implements this to avoid circular dependency.
32
- */
33
- export interface IActivationCallProvider {
34
- getActivationCalls(): { calls: SmartWalletCall[]; onSuccess: () => void };
35
- }
36
-
37
- /**
38
- * Parameters for creating a simple payment.
39
- *
40
- * This is the most user-friendly interface - minimal required fields.
41
- */
42
- export interface BasicPayParams {
43
- /** Recipient address (provider) */
44
- to: string;
45
-
46
- /** Amount in user-friendly format ("100", "100.50", "100 USDC", "$100") */
47
- amount: string | number;
48
-
49
- /** Optional: Deadline as relative time ("+24h") or Unix timestamp. Defaults to +24h */
50
- deadline?: string | number;
51
-
52
- /** Optional: Dispute window in seconds. Defaults to 172800 (2 days) */
53
- disputeWindow?: number;
54
- }
55
-
56
- /**
57
- * Result of creating a payment.
58
- *
59
- * Provides user-friendly formatted data (not raw protocol types).
60
- */
61
- export interface BasicPayResult {
62
- /** Transaction ID (bytes32 hex string) */
63
- txId: string;
64
-
65
- /** Provider address */
66
- provider: string;
67
-
68
- /** Requester address (caller) */
69
- requester: string;
70
-
71
- /** Amount in USDC (human-readable, e.g., "100.00 USDC") */
72
- amount: string;
73
-
74
- /** Deadline as ISO 8601 timestamp */
75
- deadline: string;
76
-
77
- /** Transaction state */
78
- state: string;
79
- }
80
-
81
- /**
82
- * BasicAdapter - High-level API for simple payment flows.
83
- *
84
- * This adapter provides the simplest possible interface:
85
- * - `pay()` - Create and fund a transaction in one call
86
- * - `checkStatus()` - Get transaction status with action hints
87
- *
88
- * All complexity is hidden behind smart defaults.
89
- *
90
- * Implements IAdapter for router integration.
91
- *
92
- * @example
93
- * ```typescript
94
- * const client = await ACTPClient.create({ mode: 'mock' });
95
- *
96
- * // Simple payment (all defaults)
97
- * const result = await client.basic.pay({
98
- * to: '0xProvider123',
99
- * amount: '100',
100
- * });
101
- * console.log('Transaction ID:', result.txId);
102
- * console.log('Amount:', result.amount); // "100.00 USDC"
103
- *
104
- * // Check status
105
- * const status = await client.basic.checkStatus(result.txId);
106
- * if (status.canAccept) {
107
- * console.log('Provider can accept this transaction');
108
- * }
109
- * ```
110
- */
111
- export class BasicAdapter extends BaseAdapter implements IAdapter {
112
- /**
113
- * Adapter metadata for router selection.
114
- */
115
- public readonly metadata: AdapterMetadata = {
116
- id: 'basic',
117
- name: 'Basic Adapter',
118
- usesEscrow: true,
119
- supportsDisputes: true,
120
- requiresIdentity: false,
121
- settlementMode: 'timed', // Auto-release after dispute window
122
- priority: 50, // Default priority
123
- };
124
- /**
125
- * Creates a new BasicAdapter instance.
126
- *
127
- * @param runtime - ACTP runtime implementation (MockRuntime or BlockchainRuntime)
128
- * @param requesterAddress - The requester's Ethereum address
129
- * @param easHelper - Optional EAS helper for attestation verification (SECURITY FIX C-4)
130
- * @param walletProvider - Optional wallet provider for AA batched payments
131
- * @param contractAddresses - Optional contract addresses for batched payment encoding
132
- */
133
- constructor(
134
- private runtime: IACTPRuntime,
135
- requesterAddress: string,
136
- private easHelper?: EASHelper,
137
- private walletProvider?: IWalletProvider,
138
- private contractAddresses?: { usdc: string; actpKernel: string; escrowVault: string },
139
- private activationProvider?: IActivationCallProvider,
140
- ) {
141
- super(requesterAddress);
142
- }
143
-
144
- /**
145
- * Create a payment transaction with smart defaults.
146
- *
147
- * This is the simplest way to create a transaction - just specify
148
- * recipient and amount. All other parameters use sensible defaults.
149
- *
150
- * Smart defaults:
151
- * - Requester: Inferred from constructor
152
- * - Deadline: 24 hours from now
153
- * - Dispute window: 2 days (172800 seconds)
154
- *
155
- * Validations performed:
156
- * - Address format (0x-prefixed hex)
157
- * - Amount format (positive number)
158
- * - Deadline in future
159
- * - Cannot pay yourself
160
- *
161
- * @param params - Payment parameters
162
- * @param agentId - Optional ERC-8004 agent ID (for reputation reporting)
163
- * @returns User-friendly payment result
164
- * @throws {ValidationError} If inputs are invalid
165
- *
166
- * @example
167
- * ```typescript
168
- * const result = await adapter.payBasic({
169
- * to: '0xProvider123',
170
- * amount: '100.50',
171
- * deadline: '+7d', // Optional: 7 days from now
172
- * });
173
- * ```
174
- */
175
- async payBasic(params: BasicPayParams, agentId?: string): Promise<BasicPayResult> {
176
- // Validate and parse inputs
177
- const provider = this.validateAddress(params.to, 'to');
178
- const amount = this.parseAmount(params.amount);
179
- const currentTime = this.runtime.time.now();
180
- const deadline = this.parseDeadline(params.deadline, currentTime);
181
- // SECURITY FIX (L-1): Validate dispute window bounds
182
- const disputeWindow = this.validateDisputeWindow(params.disputeWindow);
183
-
184
- const requester = this.requesterAddress;
185
-
186
- // Additional validations
187
- if (requester.toLowerCase() === provider.toLowerCase()) {
188
- throw new ValidationError('Cannot pay yourself (requester equals provider)');
189
- }
190
-
191
- if (deadline <= currentTime) {
192
- throw new ValidationError('Deadline must be in the future');
193
- }
194
-
195
- // SECURITY: Enforce transaction amount limit on unaudited mainnet contracts
196
- const maxAmount = this.runtime.maxTransactionAmount;
197
- const amountInUsdc = Number(amount) / 1_000_000; // Convert from wei to USDC
198
- if (maxAmount !== undefined && amountInUsdc > maxAmount) {
199
- throw new ValidationError(
200
- `Transaction amount $${amountInUsdc.toFixed(2)} exceeds maximum allowed $${maxAmount}. ` +
201
- `This limit exists because contracts have not been formally audited. ` +
202
- `For larger amounts, please contact support@agirails.io.`
203
- );
204
- }
205
-
206
- // ====================================================================
207
- // AIP-12: Batched payment via AA wallet (1 UserOp = N on-chain calls)
208
- // With lazy publish: activation calls prepended to first payment.
209
- // ====================================================================
210
- if (this.walletProvider?.payACTPBatched && this.contractAddresses) {
211
- const serviceHash = ethers.ZeroHash;
212
-
213
- // Get lazy publish activation calls (if any)
214
- let prependCalls: SmartWalletCall[] = [];
215
- let onActivationSuccess: (() => void) | undefined;
216
-
217
- if (this.activationProvider) {
218
- const activation = this.activationProvider.getActivationCalls();
219
- prependCalls = activation.calls;
220
- if (prependCalls.length > 0) {
221
- onActivationSuccess = activation.onSuccess;
222
- }
223
- }
224
-
225
- const result = await this.walletProvider.payACTPBatched(
226
- {
227
- provider,
228
- requester,
229
- amount: amount.toString(),
230
- deadline,
231
- disputeWindow,
232
- serviceHash,
233
- agentId: agentId || '0',
234
- contracts: this.contractAddresses,
235
- },
236
- prependCalls.length > 0 ? prependCalls : undefined,
237
- );
238
-
239
- if (!result.success) {
240
- throw new Error(`Batched payment UserOp failed: ${result.hash}`);
241
- }
242
-
243
- // Delete pending-publish.json on successful activation (best-effort)
244
- if (onActivationSuccess) {
245
- try {
246
- onActivationSuccess();
247
- } catch {
248
- // Best-effort: activation succeeded, don't crash over cleanup
249
- }
250
- }
251
-
252
- return {
253
- txId: result.txId,
254
- provider,
255
- requester,
256
- amount: this.formatAmount(amount),
257
- deadline: new Date(deadline * 1000).toISOString(),
258
- state: 'COMMITTED',
259
- };
260
- }
261
-
262
- // ====================================================================
263
- // Legacy flow: sequential on-chain calls (EOA / mock)
264
- // ====================================================================
265
-
266
- // Create transaction
267
- const txId = await this.runtime.createTransaction({
268
- provider,
269
- requester,
270
- amount: amount.toString(),
271
- deadline,
272
- disputeWindow,
273
- agentId, // ERC-8004 agent ID for reputation reporting
274
- });
275
-
276
- // Link escrow (auto-transitions to COMMITTED)
277
- await this.runtime.linkEscrow(txId, amount.toString());
278
-
279
- // Fetch transaction details for user-friendly response
280
- const tx = await this.runtime.getTransaction(txId);
281
-
282
- if (!tx) {
283
- throw new Error(`Transaction ${txId} not found after creation`);
284
- }
285
-
286
- return {
287
- txId,
288
- provider,
289
- requester,
290
- amount: this.formatAmount(amount),
291
- deadline: new Date(deadline * 1000).toISOString(),
292
- state: tx.state,
293
- };
294
- }
295
-
296
- /**
297
- * Check payment status by transaction ID.
298
- *
299
- * Returns current state plus action hints (what can be done next).
300
- *
301
- * Action hints:
302
- * - `canAccept`: Provider can accept (INITIATED state, before deadline)
303
- * - `canComplete`: Provider can mark as delivered (COMMITTED state)
304
- * - `canDispute`: Requester can dispute (DELIVERED state, within dispute window)
305
- *
306
- * @param txId - Transaction ID to check
307
- * @returns Status with action hints
308
- * @throws {Error} If transaction not found
309
- *
310
- * @example
311
- * ```typescript
312
- * const status = await adapter.checkStatus(txId);
313
- * console.log('State:', status.state); // "COMMITTED"
314
- * if (status.canComplete) {
315
- * // Provider can deliver now
316
- * }
317
- * ```
318
- */
319
- async checkStatus(txId: string): Promise<{
320
- state: string;
321
- canAccept: boolean;
322
- canComplete: boolean;
323
- canDispute: boolean;
324
- }> {
325
- const tx = await this.runtime.getTransaction(txId);
326
-
327
- if (!tx) {
328
- throw new Error(`Transaction ${txId} not found`);
329
- }
330
-
331
- const now = this.runtime.time.now();
332
-
333
- return {
334
- state: tx.state,
335
- canAccept: tx.state === 'INITIATED' && tx.deadline > now,
336
- canComplete: tx.state === 'COMMITTED' || tx.state === 'IN_PROGRESS',
337
- canDispute: tx.state === 'DELIVERED' && tx.completedAt !== null && tx.completedAt + tx.disputeWindow > now,
338
- };
339
- }
340
-
341
- // ==========================================================================
342
- // IAdapter Implementation
343
- // ==========================================================================
344
-
345
- /**
346
- * Execute payment through this adapter.
347
- *
348
- * This is the IAdapter-compatible pay() method that returns UnifiedPayResult.
349
- * For the legacy BasicPayResult API, use payBasic().
350
- *
351
- * @param params - Unified payment parameters
352
- * @returns Promise resolving to unified payment result
353
- */
354
- async pay(params: UnifiedPayParams): Promise<UnifiedPayResult> {
355
- // Validate using IAdapter validate()
356
- this.validate(params);
357
-
358
- // Map to BasicPayParams
359
- const basicParams: BasicPayParams = {
360
- to: params.to,
361
- amount: params.amount,
362
- deadline: params.deadline,
363
- disputeWindow: params.disputeWindow,
364
- };
365
-
366
- // Call existing payBasic() with optional agentId
367
- const result = await this.payBasic(basicParams, params.erc8004AgentId);
368
-
369
- // Map to UnifiedPayResult
370
- return {
371
- txId: result.txId,
372
- escrowId: result.txId, // In ACTP, escrowId === txId
373
- adapter: this.metadata.id,
374
- state: 'COMMITTED',
375
- success: true,
376
- amount: result.amount,
377
- releaseRequired: true, // ACTP requires explicit release()
378
- provider: result.provider,
379
- requester: result.requester,
380
- deadline: result.deadline,
381
- erc8004AgentId: params.erc8004AgentId,
382
- };
383
- }
384
-
385
- /**
386
- * Check if this adapter can handle the given parameters.
387
- *
388
- * BasicAdapter can handle any Ethereum address recipient.
389
- *
390
- * @param params - Payment parameters to check
391
- * @returns True if params have a valid Ethereum address
392
- */
393
- canHandle(params: UnifiedPayParams): boolean {
394
- // BasicAdapter handles Ethereum addresses only
395
- if (typeof params.to !== 'string') {
396
- return false;
397
- }
398
-
399
- // Check if it's an Ethereum address (0x-prefixed hex)
400
- return /^0x[a-fA-F0-9]{40}$/.test(params.to);
401
- }
402
-
403
- /**
404
- * Validate parameters before execution.
405
- *
406
- * @param params - Parameters to validate
407
- * @throws {ValidationError} If params are invalid
408
- */
409
- validate(params: UnifiedPayParams): void {
410
- // Validate address
411
- this.validateAddress(params.to, 'to');
412
-
413
- // Validate amount (will throw if invalid)
414
- this.parseAmount(params.amount);
415
-
416
- // Validate deadline if provided
417
- if (params.deadline !== undefined) {
418
- this.parseDeadline(params.deadline);
419
- }
420
-
421
- // Validate dispute window if provided
422
- if (params.disputeWindow !== undefined) {
423
- this.validateDisputeWindow(params.disputeWindow);
424
- }
425
- }
426
-
427
- /**
428
- * Get transaction status by ID.
429
- *
430
- * Returns TransactionStatus with action hints.
431
- *
432
- * @param txId - Transaction ID
433
- * @returns Promise resolving to transaction status
434
- */
435
- async getStatus(txId: string): Promise<TransactionStatus> {
436
- const tx = await this.runtime.getTransaction(txId);
437
-
438
- if (!tx) {
439
- throw new Error(`Transaction ${txId} not found`);
440
- }
441
-
442
- const now = this.runtime.time.now();
443
- const disputeWindowEnds = tx.completedAt
444
- ? tx.completedAt + tx.disputeWindow
445
- : undefined;
446
-
447
- return {
448
- state: tx.state as TransactionStatus['state'],
449
- canStartWork: tx.state === 'COMMITTED',
450
- canDeliver: tx.state === 'IN_PROGRESS',
451
- canRelease:
452
- tx.state === 'DELIVERED' &&
453
- disputeWindowEnds !== undefined &&
454
- now >= disputeWindowEnds,
455
- canDispute:
456
- tx.state === 'DELIVERED' &&
457
- disputeWindowEnds !== undefined &&
458
- now < disputeWindowEnds,
459
- amount: this.formatAmount(tx.amount),
460
- deadline: new Date(tx.deadline * 1000).toISOString(),
461
- disputeWindowEnds: disputeWindowEnds
462
- ? new Date(disputeWindowEnds * 1000).toISOString()
463
- : undefined,
464
- provider: tx.provider,
465
- requester: tx.requester,
466
- };
467
- }
468
-
469
- /**
470
- * Transition to IN_PROGRESS state (provider starts work).
471
- *
472
- * @param txId - Transaction ID
473
- */
474
- async startWork(txId: string): Promise<void> {
475
- await this.runtime.transitionState(txId, 'IN_PROGRESS');
476
- }
477
-
478
- /**
479
- * Transition to DELIVERED state (provider completes work).
480
- *
481
- * When no proof is provided, fetches the transaction's actual disputeWindow
482
- * and encodes it as proof. This ensures consistency with the dispute window
483
- * specified at transaction creation time.
484
- *
485
- * @param txId - Transaction ID
486
- * @param proof - Optional delivery proof (ABI-encoded dispute window).
487
- * If not provided, uses transaction's disputeWindow.
488
- */
489
- async deliver(txId: string, proof?: string): Promise<void> {
490
- let deliveryProof = proof;
491
-
492
- if (!deliveryProof) {
493
- // Fetch transaction to get its actual disputeWindow
494
- const tx = await this.runtime.getTransaction(txId);
495
- if (!tx) {
496
- throw new Error(`Transaction ${txId} not found`);
497
- }
498
- // Use transaction's disputeWindow, not a default
499
- deliveryProof = this.encodeDisputeWindowProof(tx.disputeWindow);
500
- }
501
-
502
- await this.runtime.transitionState(txId, 'DELIVERED', deliveryProof);
503
- }
504
-
505
- /**
506
- * Release escrow funds (EXPLICIT settlement).
507
- *
508
- * @param escrowId - Escrow ID (usually same as txId)
509
- * @param attestationUID - Optional attestation UID for verification
510
- */
511
- async release(escrowId: string, attestationUID?: string): Promise<void> {
512
- await this.runtime.releaseEscrow(escrowId, attestationUID);
513
- }
514
- }