@agirails/sdk 2.5.3 → 2.5.5
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.
- package/dist/ACTPClient.d.ts +18 -0
- package/dist/ACTPClient.d.ts.map +1 -1
- package/dist/ACTPClient.js +72 -23
- package/dist/ACTPClient.js.map +1 -1
- package/dist/adapters/BasicAdapter.d.ts +15 -0
- package/dist/adapters/BasicAdapter.d.ts.map +1 -1
- package/dist/adapters/BasicAdapter.js +33 -4
- package/dist/adapters/BasicAdapter.js.map +1 -1
- package/dist/adapters/StandardAdapter.d.ts +20 -3
- package/dist/adapters/StandardAdapter.d.ts.map +1 -1
- package/dist/adapters/StandardAdapter.js +90 -12
- package/dist/adapters/StandardAdapter.js.map +1 -1
- package/dist/cli/commands/publish.js +16 -4
- package/dist/cli/commands/publish.js.map +1 -1
- package/dist/cli/commands/register.js +16 -4
- package/dist/cli/commands/register.js.map +1 -1
- package/dist/cli/commands/tx.js +31 -3
- package/dist/cli/commands/tx.js.map +1 -1
- package/dist/config/networks.d.ts +10 -2
- package/dist/config/networks.d.ts.map +1 -1
- package/dist/config/networks.js +31 -22
- package/dist/config/networks.js.map +1 -1
- package/dist/level0/request.d.ts.map +1 -1
- package/dist/level0/request.js +2 -1
- package/dist/level0/request.js.map +1 -1
- package/dist/runtime/BlockchainRuntime.d.ts.map +1 -1
- package/dist/runtime/BlockchainRuntime.js +11 -5
- package/dist/runtime/BlockchainRuntime.js.map +1 -1
- package/dist/utils/IPFSClient.d.ts +3 -1
- package/dist/utils/IPFSClient.d.ts.map +1 -1
- package/dist/utils/IPFSClient.js +27 -7
- package/dist/utils/IPFSClient.js.map +1 -1
- package/dist/wallet/AutoWalletProvider.d.ts +11 -1
- package/dist/wallet/AutoWalletProvider.d.ts.map +1 -1
- package/dist/wallet/AutoWalletProvider.js +84 -19
- package/dist/wallet/AutoWalletProvider.js.map +1 -1
- package/dist/wallet/IWalletProvider.d.ts +34 -0
- package/dist/wallet/IWalletProvider.d.ts.map +1 -1
- package/dist/wallet/SmartWalletRouter.d.ts +128 -0
- package/dist/wallet/SmartWalletRouter.d.ts.map +1 -0
- package/dist/wallet/SmartWalletRouter.js +248 -0
- package/dist/wallet/SmartWalletRouter.js.map +1 -0
- package/dist/wallet/aa/DualNonceManager.d.ts +26 -1
- package/dist/wallet/aa/DualNonceManager.d.ts.map +1 -1
- package/dist/wallet/aa/DualNonceManager.js +140 -6
- package/dist/wallet/aa/DualNonceManager.js.map +1 -1
- package/package.json +3 -6
- package/src/ACTPClient.ts +0 -1579
- package/src/abi/ACTPKernel.json +0 -1356
- package/src/abi/AgentRegistry.json +0 -915
- package/src/abi/ERC20.json +0 -40
- package/src/abi/EscrowVault.json +0 -134
- package/src/abi/IdentityRegistry.json +0 -316
- package/src/adapters/AdapterRegistry.ts +0 -173
- package/src/adapters/AdapterRouter.ts +0 -416
- package/src/adapters/BaseAdapter.ts +0 -498
- package/src/adapters/BasicAdapter.ts +0 -514
- package/src/adapters/IAdapter.ts +0 -292
- package/src/adapters/StandardAdapter.ts +0 -555
- package/src/adapters/X402Adapter.ts +0 -731
- package/src/adapters/index.ts +0 -60
- package/src/builders/DeliveryProofBuilder.ts +0 -327
- package/src/builders/QuoteBuilder.ts +0 -483
- package/src/builders/index.ts +0 -17
- package/src/cli/commands/balance.ts +0 -110
- package/src/cli/commands/batch.ts +0 -487
- package/src/cli/commands/config.ts +0 -231
- package/src/cli/commands/deploy-check.ts +0 -364
- package/src/cli/commands/deploy-env.ts +0 -120
- package/src/cli/commands/diff.ts +0 -141
- package/src/cli/commands/init.ts +0 -469
- package/src/cli/commands/mint.ts +0 -116
- package/src/cli/commands/pay.ts +0 -113
- package/src/cli/commands/publish.ts +0 -475
- package/src/cli/commands/pull.ts +0 -124
- package/src/cli/commands/register.ts +0 -247
- package/src/cli/commands/simulate.ts +0 -345
- package/src/cli/commands/time.ts +0 -302
- package/src/cli/commands/tx.ts +0 -448
- package/src/cli/commands/watch.ts +0 -211
- package/src/cli/index.ts +0 -134
- package/src/cli/utils/client.ts +0 -252
- package/src/cli/utils/config.ts +0 -389
- package/src/cli/utils/output.ts +0 -465
- package/src/cli/utils/wallet.ts +0 -109
- package/src/config/agirailsmd.ts +0 -262
- package/src/config/networks.ts +0 -275
- package/src/config/pendingPublish.ts +0 -237
- package/src/config/publishPipeline.ts +0 -359
- package/src/config/syncOperations.ts +0 -279
- package/src/erc8004/ERC8004Bridge.ts +0 -462
- package/src/erc8004/ReputationReporter.ts +0 -468
- package/src/erc8004/index.ts +0 -61
- package/src/errors/index.ts +0 -427
- package/src/index.ts +0 -364
- package/src/level0/Provider.ts +0 -117
- package/src/level0/ServiceDirectory.ts +0 -131
- package/src/level0/index.ts +0 -10
- package/src/level0/provide.ts +0 -132
- package/src/level0/request.ts +0 -432
- package/src/level1/Agent.ts +0 -1426
- package/src/level1/index.ts +0 -10
- package/src/level1/pricing/PriceCalculator.ts +0 -255
- package/src/level1/pricing/PricingStrategy.ts +0 -198
- package/src/level1/types/Job.ts +0 -179
- package/src/level1/types/Options.ts +0 -291
- package/src/level1/types/index.ts +0 -8
- package/src/protocol/ACTPKernel.ts +0 -808
- package/src/protocol/AgentRegistry.ts +0 -559
- package/src/protocol/DIDManager.ts +0 -629
- package/src/protocol/DIDResolver.ts +0 -554
- package/src/protocol/EASHelper.ts +0 -378
- package/src/protocol/EscrowVault.ts +0 -255
- package/src/protocol/EventMonitor.ts +0 -204
- package/src/protocol/MessageSigner.ts +0 -510
- package/src/protocol/ProofGenerator.ts +0 -339
- package/src/protocol/QuoteBuilder.ts +0 -15
- package/src/registry/AgentRegistryClient.ts +0 -202
- package/src/runtime/BlockchainRuntime.ts +0 -1015
- package/src/runtime/IACTPRuntime.ts +0 -306
- package/src/runtime/MockRuntime.ts +0 -1298
- package/src/runtime/MockStateManager.ts +0 -577
- package/src/runtime/index.ts +0 -25
- package/src/runtime/types/MockState.ts +0 -237
- package/src/storage/ArchiveBundleBuilder.ts +0 -561
- package/src/storage/ArweaveClient.ts +0 -946
- package/src/storage/FilebaseClient.ts +0 -790
- package/src/storage/index.ts +0 -96
- package/src/storage/types.ts +0 -348
- package/src/types/adapter.ts +0 -310
- package/src/types/agent.ts +0 -79
- package/src/types/did.ts +0 -223
- package/src/types/eip712.ts +0 -175
- package/src/types/erc8004.ts +0 -293
- package/src/types/escrow.ts +0 -27
- package/src/types/index.ts +0 -17
- package/src/types/message.ts +0 -145
- package/src/types/state.ts +0 -87
- package/src/types/transaction.ts +0 -69
- package/src/types/x402.ts +0 -251
- package/src/utils/ErrorRecoveryGuide.ts +0 -676
- package/src/utils/Helpers.ts +0 -688
- package/src/utils/IPFSClient.ts +0 -368
- package/src/utils/Logger.ts +0 -484
- package/src/utils/NonceManager.ts +0 -591
- package/src/utils/RateLimiter.ts +0 -534
- package/src/utils/ReceivedNonceTracker.ts +0 -567
- package/src/utils/SDKLifecycle.ts +0 -416
- package/src/utils/SecureNonce.ts +0 -78
- package/src/utils/Semaphore.ts +0 -276
- package/src/utils/UsedAttestationTracker.ts +0 -385
- package/src/utils/canonicalJson.ts +0 -38
- package/src/utils/circuitBreaker.ts +0 -324
- package/src/utils/computeTypeHash.ts +0 -48
- package/src/utils/fsSafe.ts +0 -80
- package/src/utils/index.ts +0 -80
- package/src/utils/retry.ts +0 -364
- package/src/utils/security.ts +0 -418
- package/src/utils/validation.ts +0 -540
- package/src/wallet/AutoWalletProvider.ts +0 -299
- package/src/wallet/EOAWalletProvider.ts +0 -69
- package/src/wallet/IWalletProvider.ts +0 -135
- package/src/wallet/aa/BundlerClient.ts +0 -274
- package/src/wallet/aa/DualNonceManager.ts +0 -173
- package/src/wallet/aa/PaymasterClient.ts +0 -174
- package/src/wallet/aa/TransactionBatcher.ts +0 -353
- package/src/wallet/aa/UserOpBuilder.ts +0 -246
- package/src/wallet/aa/constants.ts +0 -60
- package/src/wallet/keystore.ts +0 -240
|
@@ -1,555 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* StandardAdapter - Balanced API for developers with some protocol knowledge
|
|
3
|
-
*
|
|
4
|
-
* Provides more control than BasicAdapter while still offering convenience:
|
|
5
|
-
* - Explicit transaction lifecycle methods
|
|
6
|
-
* - Direct escrow operations
|
|
7
|
-
* - State transition control
|
|
8
|
-
*
|
|
9
|
-
* Use this adapter when you need fine-grained control but still want
|
|
10
|
-
* user-friendly input parsing and validation.
|
|
11
|
-
*
|
|
12
|
-
* @module adapters/StandardAdapter
|
|
13
|
-
*/
|
|
14
|
-
|
|
15
|
-
import { BaseAdapter, ValidationError } from './BaseAdapter';
|
|
16
|
-
import { IACTPRuntime } from '../runtime/IACTPRuntime';
|
|
17
|
-
import { MockTransaction, TransactionState } from '../runtime/types/MockState';
|
|
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
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Parameters for creating a transaction (standard level).
|
|
28
|
-
*
|
|
29
|
-
* More explicit than BasicPayParams but still with smart defaults.
|
|
30
|
-
*/
|
|
31
|
-
export interface StandardTransactionParams {
|
|
32
|
-
/** Provider's Ethereum address */
|
|
33
|
-
provider: string;
|
|
34
|
-
|
|
35
|
-
/** Amount in user-friendly format ("100", "100.50", "100 USDC") */
|
|
36
|
-
amount: string | number;
|
|
37
|
-
|
|
38
|
-
/** Optional: Deadline as relative time ("+24h") or Unix timestamp. Defaults to +24h */
|
|
39
|
-
deadline?: string | number;
|
|
40
|
-
|
|
41
|
-
/** Optional: Dispute window in seconds. Defaults to 172800 (2 days) */
|
|
42
|
-
disputeWindow?: number;
|
|
43
|
-
|
|
44
|
-
/** Optional: Service description */
|
|
45
|
-
serviceDescription?: string;
|
|
46
|
-
|
|
47
|
-
/** Optional: ERC-8004 agent ID (for reputation reporting) */
|
|
48
|
-
agentId?: string;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* StandardAdapter - Balanced API for transaction lifecycle control.
|
|
53
|
-
*
|
|
54
|
-
* Provides explicit methods for each stage of the ACTP lifecycle:
|
|
55
|
-
* - `createTransaction()` - Create transaction without escrow
|
|
56
|
-
* - `linkEscrow()` - Link escrow (auto-transitions to COMMITTED)
|
|
57
|
-
* - `transitionState()` - Manually transition state
|
|
58
|
-
* - `releaseEscrow()` - Release funds to provider
|
|
59
|
-
* - `getEscrowBalance()` - Check escrow balance
|
|
60
|
-
* - `getTransaction()` - Get transaction details
|
|
61
|
-
*
|
|
62
|
-
* @example
|
|
63
|
-
* ```typescript
|
|
64
|
-
* const client = await ACTPClient.create({ mode: 'mock' });
|
|
65
|
-
*
|
|
66
|
-
* // Create transaction (INITIATED state)
|
|
67
|
-
* const txId = await client.standard.createTransaction({
|
|
68
|
-
* provider: '0xProvider123',
|
|
69
|
-
* amount: '100',
|
|
70
|
-
* deadline: '+7d',
|
|
71
|
-
* });
|
|
72
|
-
*
|
|
73
|
-
* // Link escrow (auto-transitions to COMMITTED)
|
|
74
|
-
* await client.standard.linkEscrow(txId, '100');
|
|
75
|
-
*
|
|
76
|
-
* // Provider delivers
|
|
77
|
-
* await client.standard.transitionState(txId, 'DELIVERED');
|
|
78
|
-
*
|
|
79
|
-
* // Release funds after dispute window
|
|
80
|
-
* await client.standard.releaseEscrow(escrowId);
|
|
81
|
-
* ```
|
|
82
|
-
*/
|
|
83
|
-
export class StandardAdapter extends BaseAdapter implements IAdapter {
|
|
84
|
-
/**
|
|
85
|
-
* Adapter metadata for router selection.
|
|
86
|
-
*/
|
|
87
|
-
public readonly metadata: AdapterMetadata = {
|
|
88
|
-
id: 'standard',
|
|
89
|
-
name: 'Standard Adapter',
|
|
90
|
-
usesEscrow: true,
|
|
91
|
-
supportsDisputes: true,
|
|
92
|
-
requiresIdentity: false,
|
|
93
|
-
settlementMode: 'timed', // Auto-release after dispute window
|
|
94
|
-
priority: 60, // Higher priority than basic (preferred when escrow required)
|
|
95
|
-
};
|
|
96
|
-
|
|
97
|
-
/**
|
|
98
|
-
* Creates a new StandardAdapter instance.
|
|
99
|
-
*
|
|
100
|
-
* @param runtime - ACTP runtime implementation (MockRuntime or BlockchainRuntime)
|
|
101
|
-
* @param requesterAddress - The requester's Ethereum address
|
|
102
|
-
* @param easHelper - Optional EAS helper for attestation verification (SECURITY FIX C-4)
|
|
103
|
-
*/
|
|
104
|
-
constructor(
|
|
105
|
-
private runtime: IACTPRuntime,
|
|
106
|
-
requesterAddress: string,
|
|
107
|
-
private easHelper?: EASHelper
|
|
108
|
-
) {
|
|
109
|
-
super(requesterAddress);
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
/**
|
|
113
|
-
* Create a transaction (INITIATED state, no escrow yet).
|
|
114
|
-
*
|
|
115
|
-
* Unlike `basic.pay()`, this only creates the transaction
|
|
116
|
-
* without linking escrow. You must call `linkEscrow()` separately.
|
|
117
|
-
*
|
|
118
|
-
* @param params - Transaction parameters
|
|
119
|
-
* @returns Transaction ID
|
|
120
|
-
* @throws {ValidationError} If inputs are invalid
|
|
121
|
-
*
|
|
122
|
-
* @example
|
|
123
|
-
* ```typescript
|
|
124
|
-
* const txId = await adapter.createTransaction({
|
|
125
|
-
* provider: '0xProvider123',
|
|
126
|
-
* amount: '100',
|
|
127
|
-
* deadline: '+24h',
|
|
128
|
-
* });
|
|
129
|
-
* ```
|
|
130
|
-
*/
|
|
131
|
-
async createTransaction(params: StandardTransactionParams): Promise<string> {
|
|
132
|
-
const provider = this.validateAddress(params.provider, 'provider');
|
|
133
|
-
const amount = this.parseAmount(params.amount);
|
|
134
|
-
const currentTime = this.runtime.time.now();
|
|
135
|
-
const deadline = this.parseDeadline(params.deadline, currentTime);
|
|
136
|
-
// SECURITY FIX (L-1): Validate dispute window bounds
|
|
137
|
-
const disputeWindow = this.validateDisputeWindow(params.disputeWindow);
|
|
138
|
-
|
|
139
|
-
const requester = this.requesterAddress;
|
|
140
|
-
|
|
141
|
-
// Validation
|
|
142
|
-
if (requester.toLowerCase() === provider.toLowerCase()) {
|
|
143
|
-
throw new ValidationError('Cannot create transaction with yourself as provider');
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
if (deadline <= currentTime) {
|
|
147
|
-
throw new ValidationError('Deadline must be in the future');
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
// SECURITY: Enforce transaction amount limit on unaudited mainnet contracts
|
|
151
|
-
const maxAmount = this.runtime.maxTransactionAmount;
|
|
152
|
-
const amountInUsdc = Number(amount) / 1_000_000; // Convert from wei to USDC
|
|
153
|
-
if (maxAmount !== undefined && amountInUsdc > maxAmount) {
|
|
154
|
-
throw new ValidationError(
|
|
155
|
-
`Transaction amount $${amountInUsdc.toFixed(2)} exceeds maximum allowed $${maxAmount}. ` +
|
|
156
|
-
`This limit exists because contracts have not been formally audited. ` +
|
|
157
|
-
`For larger amounts, please contact support@agirails.io.`
|
|
158
|
-
);
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
return this.runtime.createTransaction({
|
|
162
|
-
provider,
|
|
163
|
-
requester,
|
|
164
|
-
amount: amount.toString(),
|
|
165
|
-
deadline,
|
|
166
|
-
disputeWindow,
|
|
167
|
-
serviceDescription: params.serviceDescription,
|
|
168
|
-
agentId: params.agentId, // ERC-8004 agent ID for reputation reporting
|
|
169
|
-
});
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
/**
|
|
173
|
-
* Link escrow to a transaction.
|
|
174
|
-
*
|
|
175
|
-
* Automatically transitions INITIATED or QUOTED → COMMITTED.
|
|
176
|
-
* Deducts funds from requester and locks in escrow.
|
|
177
|
-
*
|
|
178
|
-
* @param txId - Transaction ID
|
|
179
|
-
* @returns Escrow ID
|
|
180
|
-
* @throws {Error} If transaction not found or in wrong state
|
|
181
|
-
*
|
|
182
|
-
* @example
|
|
183
|
-
* ```typescript
|
|
184
|
-
* const escrowId = await adapter.linkEscrow(txId);
|
|
185
|
-
* ```
|
|
186
|
-
*/
|
|
187
|
-
async linkEscrow(txId: string): Promise<string> {
|
|
188
|
-
const tx = await this.runtime.getTransaction(txId);
|
|
189
|
-
|
|
190
|
-
if (!tx) {
|
|
191
|
-
throw new Error(`Transaction ${txId} not found`);
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
// Use the transaction's amount (already in correct format)
|
|
195
|
-
return this.runtime.linkEscrow(txId, tx.amount);
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
/**
|
|
199
|
-
* Transition transaction to a new state.
|
|
200
|
-
*
|
|
201
|
-
* Validates the transition against the ACTP 8-state machine.
|
|
202
|
-
*
|
|
203
|
-
* Valid transitions:
|
|
204
|
-
* - INITIATED → QUOTED, COMMITTED, CANCELLED
|
|
205
|
-
* - QUOTED → COMMITTED, CANCELLED
|
|
206
|
-
* - COMMITTED → IN_PROGRESS, CANCELLED
|
|
207
|
-
* - IN_PROGRESS → DELIVERED, CANCELLED
|
|
208
|
-
* - DELIVERED → SETTLED, DISPUTED
|
|
209
|
-
* - DISPUTED → SETTLED, CANCELLED (admin/pauser)
|
|
210
|
-
*
|
|
211
|
-
* @param txId - Transaction ID
|
|
212
|
-
* @param newState - Target state
|
|
213
|
-
* @param proof - Optional proof data (required for DELIVERED transition with dispute window)
|
|
214
|
-
* @throws {Error} If transition is invalid
|
|
215
|
-
*
|
|
216
|
-
* @example
|
|
217
|
-
* ```typescript
|
|
218
|
-
* // Provider starts work
|
|
219
|
-
* await adapter.transitionState(txId, 'IN_PROGRESS');
|
|
220
|
-
*
|
|
221
|
-
* // Provider marks work as delivered (with dispute window proof)
|
|
222
|
-
* const disputeWindowProof = ethers.AbiCoder.defaultAbiCoder().encode(['uint256'], [7200]);
|
|
223
|
-
* await adapter.transitionState(txId, 'DELIVERED', disputeWindowProof);
|
|
224
|
-
* ```
|
|
225
|
-
*/
|
|
226
|
-
async transitionState(
|
|
227
|
-
txId: string,
|
|
228
|
-
newState: TransactionState,
|
|
229
|
-
proof?: string
|
|
230
|
-
): Promise<void> {
|
|
231
|
-
return this.runtime.transitionState(txId, newState, proof);
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
/**
|
|
235
|
-
* Release escrow funds to the provider.
|
|
236
|
-
*
|
|
237
|
-
* Can only be called when transaction is in DELIVERED state
|
|
238
|
-
* and dispute window has expired.
|
|
239
|
-
*
|
|
240
|
-
* SECURITY FIX (C-4 + HIGH-5): MANDATORY attestation verification before release.
|
|
241
|
-
* When EASHelper is available (testnet/mainnet modes), attestation verification
|
|
242
|
-
* is REQUIRED - not optional. This prevents releasing funds without proper
|
|
243
|
-
* delivery proof.
|
|
244
|
-
*
|
|
245
|
-
* Verifications performed:
|
|
246
|
-
* - Attestation exists and is not revoked
|
|
247
|
-
* - Attestation belongs to this transaction (prevents replay attacks)
|
|
248
|
-
* - Attestation has not been used for a different transaction
|
|
249
|
-
*
|
|
250
|
-
* @param escrowId - Escrow ID
|
|
251
|
-
* @param attestationParams - Attestation verification params (REQUIRED when EASHelper available)
|
|
252
|
-
* @param attestationParams.txId - Transaction ID (bytes32)
|
|
253
|
-
* @param attestationParams.attestationUID - Attestation UID (bytes32)
|
|
254
|
-
* @throws {Error} If escrow not found or dispute window active
|
|
255
|
-
* @throws {Error} If EASHelper is available but attestationParams not provided (HIGH-5)
|
|
256
|
-
* @throws {Error} If attestation verification fails
|
|
257
|
-
*
|
|
258
|
-
* @example
|
|
259
|
-
* ```typescript
|
|
260
|
-
* // With attestation verification (REQUIRED in testnet/mainnet)
|
|
261
|
-
* await adapter.releaseEscrow(escrowId, {
|
|
262
|
-
* txId: '0x...',
|
|
263
|
-
* attestationUID: '0x...'
|
|
264
|
-
* });
|
|
265
|
-
*
|
|
266
|
-
* // Mock mode only (no attestation required)
|
|
267
|
-
* await adapter.releaseEscrow(escrowId);
|
|
268
|
-
* ```
|
|
269
|
-
*/
|
|
270
|
-
async releaseEscrow(
|
|
271
|
-
escrowId: string,
|
|
272
|
-
attestationParams?: { txId: string; attestationUID: string }
|
|
273
|
-
): Promise<void> {
|
|
274
|
-
// Determine whether the underlying runtime requires attestation.
|
|
275
|
-
// BlockchainRuntime exposes isAttestationRequired(), but it's not part of the generic interface.
|
|
276
|
-
const runtimeAny = this.runtime as any;
|
|
277
|
-
const runtimeSupportsAttestationFlag =
|
|
278
|
-
typeof runtimeAny?.isAttestationRequired === 'function';
|
|
279
|
-
|
|
280
|
-
const attestationRequired: boolean = runtimeSupportsAttestationFlag
|
|
281
|
-
? Boolean(runtimeAny.isAttestationRequired())
|
|
282
|
-
: Boolean(this.easHelper);
|
|
283
|
-
|
|
284
|
-
if (attestationRequired && !attestationParams) {
|
|
285
|
-
throw new Error(
|
|
286
|
-
'Attestation verification is REQUIRED for escrow release. ' +
|
|
287
|
-
'Provide attestationParams: { txId: string, attestationUID: string }.'
|
|
288
|
-
);
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
// If caller provided attestation params, ensure they match the escrow/tx being released.
|
|
292
|
-
if (attestationParams) {
|
|
293
|
-
// Support legacy escrowId format "escrow-{txId}-{timestamp}".
|
|
294
|
-
// Standard is escrowId === txId.
|
|
295
|
-
const legacyMatch = escrowId.match(/^escrow-(.+)-\d+$/);
|
|
296
|
-
const txIdFromEscrowId = legacyMatch ? legacyMatch[1] : escrowId;
|
|
297
|
-
|
|
298
|
-
if (txIdFromEscrowId.toLowerCase() !== attestationParams.txId.toLowerCase()) {
|
|
299
|
-
throw new Error(
|
|
300
|
-
`Attestation txId (${attestationParams.txId}) does not match escrow/txId (${txIdFromEscrowId}). ` +
|
|
301
|
-
`Refusing to release escrow with mismatched attestation.`
|
|
302
|
-
);
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
// If runtime does NOT handle attestation internally but EASHelper exists, verify here.
|
|
306
|
-
// Otherwise, pass attestationUID down so BlockchainRuntime can enforce/record.
|
|
307
|
-
if (!runtimeSupportsAttestationFlag && this.easHelper) {
|
|
308
|
-
await this.easHelper.verifyAndRecordForRelease(
|
|
309
|
-
attestationParams.txId,
|
|
310
|
-
attestationParams.attestationUID
|
|
311
|
-
);
|
|
312
|
-
}
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
return this.runtime.releaseEscrow(
|
|
316
|
-
escrowId,
|
|
317
|
-
attestationParams?.attestationUID
|
|
318
|
-
);
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
/**
|
|
322
|
-
* Get escrow balance.
|
|
323
|
-
*
|
|
324
|
-
* Returns formatted balance string (e.g., "100.00 USDC").
|
|
325
|
-
*
|
|
326
|
-
* @param escrowId - Escrow ID
|
|
327
|
-
* @returns Formatted balance
|
|
328
|
-
* @throws {Error} If escrow not found
|
|
329
|
-
*
|
|
330
|
-
* @example
|
|
331
|
-
* ```typescript
|
|
332
|
-
* const balance = await adapter.getEscrowBalance(escrowId);
|
|
333
|
-
* console.log(balance); // "100.00 USDC"
|
|
334
|
-
* ```
|
|
335
|
-
*/
|
|
336
|
-
async getEscrowBalance(escrowId: string): Promise<string> {
|
|
337
|
-
const balance = await this.runtime.getEscrowBalance(escrowId);
|
|
338
|
-
return this.formatAmount(balance);
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
/**
|
|
342
|
-
* Get transaction details.
|
|
343
|
-
*
|
|
344
|
-
* Returns the full transaction object from the runtime.
|
|
345
|
-
*
|
|
346
|
-
* @param txId - Transaction ID
|
|
347
|
-
* @returns Transaction object or null if not found
|
|
348
|
-
*
|
|
349
|
-
* @example
|
|
350
|
-
* ```typescript
|
|
351
|
-
* const tx = await adapter.getTransaction(txId);
|
|
352
|
-
* console.log('State:', tx?.state);
|
|
353
|
-
* console.log('Amount:', tx?.amount);
|
|
354
|
-
* ```
|
|
355
|
-
*/
|
|
356
|
-
async getTransaction(txId: string): Promise<MockTransaction | null> {
|
|
357
|
-
return this.runtime.getTransaction(txId);
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
// ==========================================================================
|
|
361
|
-
// IAdapter Implementation
|
|
362
|
-
// ==========================================================================
|
|
363
|
-
|
|
364
|
-
/**
|
|
365
|
-
* Unified pay method for IAdapter interface.
|
|
366
|
-
*
|
|
367
|
-
* Creates transaction AND links escrow in one call.
|
|
368
|
-
*
|
|
369
|
-
* @param params - Unified payment parameters
|
|
370
|
-
* @returns Promise resolving to unified payment result
|
|
371
|
-
*/
|
|
372
|
-
async pay(params: UnifiedPayParams): Promise<UnifiedPayResult> {
|
|
373
|
-
// Validate using IAdapter validate()
|
|
374
|
-
this.validate(params);
|
|
375
|
-
|
|
376
|
-
// Map to StandardTransactionParams
|
|
377
|
-
const standardParams: StandardTransactionParams = {
|
|
378
|
-
provider: params.to,
|
|
379
|
-
amount: params.amount,
|
|
380
|
-
deadline: params.deadline,
|
|
381
|
-
disputeWindow: params.disputeWindow,
|
|
382
|
-
serviceDescription: params.description,
|
|
383
|
-
agentId: params.erc8004AgentId, // Pass ERC-8004 agent ID
|
|
384
|
-
};
|
|
385
|
-
|
|
386
|
-
// Create transaction
|
|
387
|
-
const txId = await this.createTransaction(standardParams);
|
|
388
|
-
|
|
389
|
-
// Link escrow (auto-transitions to COMMITTED)
|
|
390
|
-
await this.linkEscrow(txId);
|
|
391
|
-
|
|
392
|
-
// Fetch transaction for response
|
|
393
|
-
const tx = await this.runtime.getTransaction(txId);
|
|
394
|
-
if (!tx) {
|
|
395
|
-
throw new Error(`Transaction ${txId} not found after creation`);
|
|
396
|
-
}
|
|
397
|
-
|
|
398
|
-
const provider = this.validateAddress(params.to, 'to');
|
|
399
|
-
const deadline = tx.deadline;
|
|
400
|
-
|
|
401
|
-
return {
|
|
402
|
-
txId,
|
|
403
|
-
escrowId: txId,
|
|
404
|
-
adapter: this.metadata.id,
|
|
405
|
-
state: 'COMMITTED',
|
|
406
|
-
success: true,
|
|
407
|
-
amount: this.formatAmount(tx.amount),
|
|
408
|
-
releaseRequired: true, // ACTP requires explicit release()
|
|
409
|
-
provider,
|
|
410
|
-
requester: this.requesterAddress,
|
|
411
|
-
deadline: new Date(deadline * 1000).toISOString(),
|
|
412
|
-
erc8004AgentId: params.erc8004AgentId, // Return agent ID
|
|
413
|
-
};
|
|
414
|
-
}
|
|
415
|
-
|
|
416
|
-
/**
|
|
417
|
-
* Check if this adapter can handle the given parameters.
|
|
418
|
-
*
|
|
419
|
-
* StandardAdapter can handle any Ethereum address recipient.
|
|
420
|
-
*
|
|
421
|
-
* @param params - Payment parameters to check
|
|
422
|
-
* @returns True if params have a valid Ethereum address
|
|
423
|
-
*/
|
|
424
|
-
canHandle(params: UnifiedPayParams): boolean {
|
|
425
|
-
// StandardAdapter handles Ethereum addresses only
|
|
426
|
-
if (typeof params.to !== 'string') {
|
|
427
|
-
return false;
|
|
428
|
-
}
|
|
429
|
-
|
|
430
|
-
// Check if it's an Ethereum address (0x-prefixed hex)
|
|
431
|
-
return /^0x[a-fA-F0-9]{40}$/.test(params.to);
|
|
432
|
-
}
|
|
433
|
-
|
|
434
|
-
/**
|
|
435
|
-
* Validate parameters before execution.
|
|
436
|
-
*
|
|
437
|
-
* @param params - Parameters to validate
|
|
438
|
-
* @throws {ValidationError} If params are invalid
|
|
439
|
-
*/
|
|
440
|
-
validate(params: UnifiedPayParams): void {
|
|
441
|
-
// Validate address
|
|
442
|
-
this.validateAddress(params.to, 'to');
|
|
443
|
-
|
|
444
|
-
// Validate amount (will throw if invalid)
|
|
445
|
-
this.parseAmount(params.amount);
|
|
446
|
-
|
|
447
|
-
// Validate deadline if provided
|
|
448
|
-
if (params.deadline !== undefined) {
|
|
449
|
-
this.parseDeadline(params.deadline);
|
|
450
|
-
}
|
|
451
|
-
|
|
452
|
-
// Validate dispute window if provided
|
|
453
|
-
if (params.disputeWindow !== undefined) {
|
|
454
|
-
this.validateDisputeWindow(params.disputeWindow);
|
|
455
|
-
}
|
|
456
|
-
}
|
|
457
|
-
|
|
458
|
-
/**
|
|
459
|
-
* Get transaction status by ID.
|
|
460
|
-
*
|
|
461
|
-
* Returns TransactionStatus with action hints.
|
|
462
|
-
*
|
|
463
|
-
* @param txId - Transaction ID
|
|
464
|
-
* @returns Promise resolving to transaction status
|
|
465
|
-
*/
|
|
466
|
-
async getStatus(txId: string): Promise<TransactionStatus> {
|
|
467
|
-
const tx = await this.runtime.getTransaction(txId);
|
|
468
|
-
|
|
469
|
-
if (!tx) {
|
|
470
|
-
throw new Error(`Transaction ${txId} not found`);
|
|
471
|
-
}
|
|
472
|
-
|
|
473
|
-
const now = this.runtime.time.now();
|
|
474
|
-
const disputeWindowEnds = tx.completedAt
|
|
475
|
-
? tx.completedAt + tx.disputeWindow
|
|
476
|
-
: undefined;
|
|
477
|
-
|
|
478
|
-
return {
|
|
479
|
-
state: tx.state as TransactionStatus['state'],
|
|
480
|
-
canStartWork: tx.state === 'COMMITTED',
|
|
481
|
-
canDeliver: tx.state === 'IN_PROGRESS',
|
|
482
|
-
canRelease:
|
|
483
|
-
tx.state === 'DELIVERED' &&
|
|
484
|
-
disputeWindowEnds !== undefined &&
|
|
485
|
-
now >= disputeWindowEnds,
|
|
486
|
-
canDispute:
|
|
487
|
-
tx.state === 'DELIVERED' &&
|
|
488
|
-
disputeWindowEnds !== undefined &&
|
|
489
|
-
now < disputeWindowEnds,
|
|
490
|
-
amount: this.formatAmount(tx.amount),
|
|
491
|
-
deadline: new Date(tx.deadline * 1000).toISOString(),
|
|
492
|
-
disputeWindowEnds: disputeWindowEnds
|
|
493
|
-
? new Date(disputeWindowEnds * 1000).toISOString()
|
|
494
|
-
: undefined,
|
|
495
|
-
provider: tx.provider,
|
|
496
|
-
requester: tx.requester,
|
|
497
|
-
};
|
|
498
|
-
}
|
|
499
|
-
|
|
500
|
-
/**
|
|
501
|
-
* Transition to IN_PROGRESS state (provider starts work).
|
|
502
|
-
*
|
|
503
|
-
* @param txId - Transaction ID
|
|
504
|
-
*/
|
|
505
|
-
async startWork(txId: string): Promise<void> {
|
|
506
|
-
await this.runtime.transitionState(txId, 'IN_PROGRESS');
|
|
507
|
-
}
|
|
508
|
-
|
|
509
|
-
/**
|
|
510
|
-
* Transition to DELIVERED state (provider completes work).
|
|
511
|
-
*
|
|
512
|
-
* When no proof is provided, fetches the transaction's actual disputeWindow
|
|
513
|
-
* and encodes it as proof. This ensures consistency with the dispute window
|
|
514
|
-
* specified at transaction creation time.
|
|
515
|
-
*
|
|
516
|
-
* @param txId - Transaction ID
|
|
517
|
-
* @param proof - Optional delivery proof (ABI-encoded dispute window).
|
|
518
|
-
* If not provided, uses transaction's disputeWindow.
|
|
519
|
-
*/
|
|
520
|
-
async deliver(txId: string, proof?: string): Promise<void> {
|
|
521
|
-
let deliveryProof = proof;
|
|
522
|
-
|
|
523
|
-
if (!deliveryProof) {
|
|
524
|
-
// Fetch transaction to get its actual disputeWindow
|
|
525
|
-
const tx = await this.runtime.getTransaction(txId);
|
|
526
|
-
if (!tx) {
|
|
527
|
-
throw new Error(`Transaction ${txId} not found`);
|
|
528
|
-
}
|
|
529
|
-
// Use transaction's disputeWindow, not a default
|
|
530
|
-
deliveryProof = this.encodeDisputeWindowProof(tx.disputeWindow);
|
|
531
|
-
}
|
|
532
|
-
|
|
533
|
-
await this.runtime.transitionState(txId, 'DELIVERED', deliveryProof);
|
|
534
|
-
}
|
|
535
|
-
|
|
536
|
-
/**
|
|
537
|
-
* Release escrow funds (EXPLICIT settlement).
|
|
538
|
-
*
|
|
539
|
-
* Wrapper around releaseEscrow() for IAdapter interface.
|
|
540
|
-
*
|
|
541
|
-
* @param escrowId - Escrow ID (usually same as txId)
|
|
542
|
-
* @param attestationUID - Optional attestation UID for verification
|
|
543
|
-
*/
|
|
544
|
-
async release(escrowId: string, attestationUID?: string): Promise<void> {
|
|
545
|
-
// Find txId from escrowId (they're usually the same)
|
|
546
|
-
const legacyMatch = escrowId.match(/^escrow-(.+)-\d+$/);
|
|
547
|
-
const txId = legacyMatch ? legacyMatch[1] : escrowId;
|
|
548
|
-
|
|
549
|
-
if (attestationUID) {
|
|
550
|
-
await this.releaseEscrow(escrowId, { txId, attestationUID });
|
|
551
|
-
} else {
|
|
552
|
-
await this.releaseEscrow(escrowId);
|
|
553
|
-
}
|
|
554
|
-
}
|
|
555
|
-
}
|