@agirails/sdk 2.0.3 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (151) hide show
  1. package/README.md +536 -87
  2. package/dist/adapters/BaseAdapter.js +2 -2
  3. package/dist/adapters/BaseAdapter.js.map +1 -1
  4. package/dist/adapters/BasicAdapter.d.ts.map +1 -1
  5. package/dist/adapters/BasicAdapter.js +8 -0
  6. package/dist/adapters/BasicAdapter.js.map +1 -1
  7. package/dist/adapters/StandardAdapter.d.ts +10 -5
  8. package/dist/adapters/StandardAdapter.d.ts.map +1 -1
  9. package/dist/adapters/StandardAdapter.js +19 -6
  10. package/dist/adapters/StandardAdapter.js.map +1 -1
  11. package/dist/builders/QuoteBuilder.js +1 -1
  12. package/dist/builders/QuoteBuilder.js.map +1 -1
  13. package/dist/cli/commands/config.js +1 -1
  14. package/dist/cli/commands/config.js.map +1 -1
  15. package/dist/cli/commands/simulate.js.map +1 -1
  16. package/dist/cli/commands/time.d.ts.map +1 -1
  17. package/dist/cli/commands/time.js.map +1 -1
  18. package/dist/config/networks.d.ts +9 -0
  19. package/dist/config/networks.d.ts.map +1 -1
  20. package/dist/config/networks.js +25 -10
  21. package/dist/config/networks.js.map +1 -1
  22. package/dist/index.d.ts +6 -1
  23. package/dist/index.d.ts.map +1 -1
  24. package/dist/index.js +31 -1
  25. package/dist/index.js.map +1 -1
  26. package/dist/level0/provide.d.ts.map +1 -1
  27. package/dist/level0/provide.js +2 -1
  28. package/dist/level0/provide.js.map +1 -1
  29. package/dist/level0/request.d.ts.map +1 -1
  30. package/dist/level0/request.js +1 -2
  31. package/dist/level0/request.js.map +1 -1
  32. package/dist/level1/Agent.d.ts.map +1 -1
  33. package/dist/level1/Agent.js +11 -3
  34. package/dist/level1/Agent.js.map +1 -1
  35. package/dist/level1/pricing/PriceCalculator.js +1 -1
  36. package/dist/level1/pricing/PriceCalculator.js.map +1 -1
  37. package/dist/level1/types/Options.d.ts.map +1 -1
  38. package/dist/protocol/ACTPKernel.d.ts.map +1 -1
  39. package/dist/protocol/ACTPKernel.js +7 -5
  40. package/dist/protocol/ACTPKernel.js.map +1 -1
  41. package/dist/protocol/DIDResolver.js +1 -1
  42. package/dist/protocol/DIDResolver.js.map +1 -1
  43. package/dist/protocol/EASHelper.d.ts.map +1 -1
  44. package/dist/protocol/EASHelper.js +2 -3
  45. package/dist/protocol/EASHelper.js.map +1 -1
  46. package/dist/protocol/MessageSigner.d.ts.map +1 -1
  47. package/dist/protocol/MessageSigner.js +9 -9
  48. package/dist/protocol/MessageSigner.js.map +1 -1
  49. package/dist/protocol/ProofGenerator.d.ts.map +1 -1
  50. package/dist/protocol/ProofGenerator.js +1 -0
  51. package/dist/protocol/ProofGenerator.js.map +1 -1
  52. package/dist/runtime/BlockchainRuntime.d.ts +10 -3
  53. package/dist/runtime/BlockchainRuntime.d.ts.map +1 -1
  54. package/dist/runtime/BlockchainRuntime.js +41 -25
  55. package/dist/runtime/BlockchainRuntime.js.map +1 -1
  56. package/dist/runtime/IACTPRuntime.d.ts +15 -0
  57. package/dist/runtime/IACTPRuntime.d.ts.map +1 -1
  58. package/dist/runtime/MockRuntime.d.ts +7 -0
  59. package/dist/runtime/MockRuntime.d.ts.map +1 -1
  60. package/dist/runtime/MockRuntime.js +15 -4
  61. package/dist/runtime/MockRuntime.js.map +1 -1
  62. package/dist/runtime/types/MockState.d.ts +5 -2
  63. package/dist/runtime/types/MockState.d.ts.map +1 -1
  64. package/dist/runtime/types/MockState.js.map +1 -1
  65. package/dist/storage/ArchiveBundleBuilder.d.ts +150 -0
  66. package/dist/storage/ArchiveBundleBuilder.d.ts.map +1 -0
  67. package/dist/storage/ArchiveBundleBuilder.js +468 -0
  68. package/dist/storage/ArchiveBundleBuilder.js.map +1 -0
  69. package/dist/storage/ArweaveClient.d.ts +271 -0
  70. package/dist/storage/ArweaveClient.d.ts.map +1 -0
  71. package/dist/storage/ArweaveClient.js +761 -0
  72. package/dist/storage/ArweaveClient.js.map +1 -0
  73. package/dist/storage/FilebaseClient.d.ts +193 -0
  74. package/dist/storage/FilebaseClient.d.ts.map +1 -0
  75. package/dist/storage/FilebaseClient.js +643 -0
  76. package/dist/storage/FilebaseClient.js.map +1 -0
  77. package/dist/storage/index.d.ts +47 -0
  78. package/dist/storage/index.d.ts.map +1 -0
  79. package/dist/storage/index.js +64 -0
  80. package/dist/storage/index.js.map +1 -0
  81. package/dist/storage/types.d.ts +291 -0
  82. package/dist/storage/types.d.ts.map +1 -0
  83. package/dist/storage/types.js +18 -0
  84. package/dist/storage/types.js.map +1 -0
  85. package/dist/types/state.d.ts +5 -4
  86. package/dist/types/state.d.ts.map +1 -1
  87. package/dist/types/state.js +10 -9
  88. package/dist/types/state.js.map +1 -1
  89. package/dist/utils/ErrorRecoveryGuide.d.ts.map +1 -1
  90. package/dist/utils/ErrorRecoveryGuide.js +1 -2
  91. package/dist/utils/ErrorRecoveryGuide.js.map +1 -1
  92. package/dist/utils/IPFSClient.d.ts.map +1 -1
  93. package/dist/utils/IPFSClient.js +5 -2
  94. package/dist/utils/IPFSClient.js.map +1 -1
  95. package/dist/utils/NonceManager.d.ts.map +1 -1
  96. package/dist/utils/NonceManager.js +3 -2
  97. package/dist/utils/NonceManager.js.map +1 -1
  98. package/dist/utils/UsedAttestationTracker.d.ts +1 -1
  99. package/dist/utils/UsedAttestationTracker.d.ts.map +1 -1
  100. package/dist/utils/UsedAttestationTracker.js +4 -4
  101. package/dist/utils/UsedAttestationTracker.js.map +1 -1
  102. package/dist/utils/circuitBreaker.d.ts +136 -0
  103. package/dist/utils/circuitBreaker.d.ts.map +1 -0
  104. package/dist/utils/circuitBreaker.js +253 -0
  105. package/dist/utils/circuitBreaker.js.map +1 -0
  106. package/dist/utils/retry.d.ts +120 -0
  107. package/dist/utils/retry.d.ts.map +1 -0
  108. package/dist/utils/retry.js +260 -0
  109. package/dist/utils/retry.js.map +1 -0
  110. package/dist/utils/validation.d.ts +100 -0
  111. package/dist/utils/validation.d.ts.map +1 -1
  112. package/dist/utils/validation.js +248 -1
  113. package/dist/utils/validation.js.map +1 -1
  114. package/package.json +14 -2
  115. package/src/adapters/BaseAdapter.ts +2 -2
  116. package/src/adapters/BasicAdapter.ts +12 -2
  117. package/src/adapters/StandardAdapter.ts +27 -7
  118. package/src/builders/QuoteBuilder.ts +1 -1
  119. package/src/cli/commands/config.ts +1 -1
  120. package/src/cli/commands/simulate.ts +1 -1
  121. package/src/cli/commands/time.ts +1 -2
  122. package/src/config/networks.ts +34 -10
  123. package/src/index.ts +54 -0
  124. package/src/level0/provide.ts +2 -1
  125. package/src/level0/request.ts +1 -2
  126. package/src/level1/Agent.ts +15 -5
  127. package/src/level1/pricing/PriceCalculator.ts +1 -1
  128. package/src/level1/types/Options.ts +1 -1
  129. package/src/protocol/ACTPKernel.ts +7 -5
  130. package/src/protocol/DIDResolver.ts +1 -1
  131. package/src/protocol/EASHelper.ts +2 -5
  132. package/src/protocol/MessageSigner.ts +9 -15
  133. package/src/protocol/ProofGenerator.ts +1 -0
  134. package/src/runtime/BlockchainRuntime.ts +42 -48
  135. package/src/runtime/IACTPRuntime.ts +16 -0
  136. package/src/runtime/MockRuntime.ts +16 -6
  137. package/src/runtime/types/MockState.ts +5 -2
  138. package/src/storage/ArchiveBundleBuilder.ts +563 -0
  139. package/src/storage/ArweaveClient.ts +945 -0
  140. package/src/storage/FilebaseClient.ts +790 -0
  141. package/src/storage/index.ts +96 -0
  142. package/src/storage/types.ts +348 -0
  143. package/src/types/state.ts +10 -9
  144. package/src/utils/ErrorRecoveryGuide.ts +1 -2
  145. package/src/utils/IPFSClient.ts +5 -4
  146. package/src/utils/NonceManager.ts +3 -2
  147. package/src/utils/UsedAttestationTracker.ts +4 -6
  148. package/src/utils/circuitBreaker.ts +324 -0
  149. package/src/utils/fsSafe.ts +5 -0
  150. package/src/utils/retry.ts +365 -0
  151. package/src/utils/validation.ts +295 -1
@@ -0,0 +1,96 @@
1
+ /**
2
+ * Storage Module - Hybrid Storage Architecture (AIP-7 §4)
3
+ *
4
+ * Two-tier storage model:
5
+ * - Tier 1: IPFS (Filebase) for hot storage
6
+ * - Tier 2: Arweave (Irys) for permanent archive
7
+ *
8
+ * @module storage
9
+ *
10
+ * @example
11
+ * ```typescript
12
+ * import {
13
+ * FilebaseClient,
14
+ * ArweaveClient,
15
+ * ArchiveBundleBuilder
16
+ * } from '@agirails/sdk/storage';
17
+ *
18
+ * // IPFS hot storage
19
+ * const ipfs = new FilebaseClient({
20
+ * accessKey: process.env.FILEBASE_ACCESS_KEY!,
21
+ * secretKey: process.env.FILEBASE_SECRET_KEY!
22
+ * });
23
+ *
24
+ * // Arweave permanent storage
25
+ * const arweave = await ArweaveClient.create({
26
+ * privateKey: process.env.ARCHIVE_KEY!,
27
+ * rpcUrl: process.env.BASE_RPC!
28
+ * });
29
+ *
30
+ * // Build archive bundle
31
+ * const bundle = new ArchiveBundleBuilder()
32
+ * .setTransactionId(txId)
33
+ * .setChainId(8453)
34
+ * // ... other fields
35
+ * .build();
36
+ *
37
+ * // Upload to Arweave
38
+ * const result = await arweave.uploadBundle(bundle);
39
+ * console.log('Archived at:', result.txId);
40
+ * ```
41
+ */
42
+
43
+ // ============================================================================
44
+ // Clients
45
+ // ============================================================================
46
+
47
+ export { FilebaseClient } from './FilebaseClient';
48
+ export { ArweaveClient } from './ArweaveClient';
49
+
50
+ // ============================================================================
51
+ // Builders
52
+ // ============================================================================
53
+
54
+ export {
55
+ ArchiveBundleBuilder,
56
+ computeContentHash,
57
+ validateArchiveBundle
58
+ } from './ArchiveBundleBuilder';
59
+
60
+ // ============================================================================
61
+ // Types
62
+ // ============================================================================
63
+
64
+ export type {
65
+ // Filebase
66
+ FilebaseConfig,
67
+
68
+ // Arweave
69
+ ArweaveConfig,
70
+ IrysCurrency,
71
+ IrysNetwork,
72
+
73
+ // Archive Bundle
74
+ ArchiveBundle,
75
+ ArchiveChainId,
76
+ ArchiveFinalState,
77
+ ArchiveParticipants,
78
+ ArchiveReferences,
79
+ ArchiveHashes,
80
+ ArchiveSignatures,
81
+ ArchiveAttestation,
82
+ ArchiveSettlement,
83
+ EscrowRelease,
84
+ ArchiveTags,
85
+
86
+ // Results
87
+ IPFSUploadResult,
88
+ ArweaveUploadResult,
89
+ DownloadResult
90
+ } from './types';
91
+
92
+ // ============================================================================
93
+ // Constants
94
+ // ============================================================================
95
+
96
+ export { ARCHIVE_BUNDLE_TYPE } from './types';
@@ -0,0 +1,348 @@
1
+ /**
2
+ * Storage Types (AIP-7 §4)
3
+ *
4
+ * Type definitions for the AGIRAILS hybrid storage architecture:
5
+ * - Tier 1: IPFS (Filebase) for hot storage
6
+ * - Tier 2: Arweave (Irys) for permanent archive
7
+ */
8
+
9
+ // ============================================================================
10
+ // Filebase Configuration
11
+ // ============================================================================
12
+
13
+ /**
14
+ * Configuration for Filebase S3-compatible IPFS client
15
+ */
16
+ export interface FilebaseConfig {
17
+ /**
18
+ * Filebase access key ID
19
+ * Get from: https://console.filebase.com/keys
20
+ */
21
+ accessKey: string;
22
+
23
+ /**
24
+ * Filebase secret access key
25
+ * SECURITY: Store in environment variable, never in code
26
+ */
27
+ secretKey: string;
28
+
29
+ /**
30
+ * Filebase bucket name
31
+ * @default 'agirails-storage'
32
+ */
33
+ bucket?: string;
34
+
35
+ /**
36
+ * Filebase S3 endpoint
37
+ * @default 'https://s3.filebase.com'
38
+ */
39
+ endpoint?: string;
40
+
41
+ /**
42
+ * IPFS gateway URL for retrieval
43
+ * @default 'https://ipfs.filebase.io/ipfs/'
44
+ */
45
+ gatewayUrl?: string;
46
+
47
+ /**
48
+ * Request timeout in milliseconds
49
+ * @default 30000 (30 seconds)
50
+ */
51
+ timeout?: number;
52
+
53
+ /**
54
+ * Maximum file size in bytes for uploads
55
+ * @default 104857600 (100MB)
56
+ */
57
+ maxFileSize?: number;
58
+
59
+ /**
60
+ * Maximum download size in bytes (P1-1: DoS protection)
61
+ * Downloads exceeding this limit will be rejected
62
+ * @default 52428800 (50MB)
63
+ */
64
+ maxDownloadSize?: number;
65
+
66
+ /**
67
+ * Circuit breaker configuration for gateway health tracking
68
+ * When enabled, tracks gateway failures and temporarily blocks
69
+ * requests to unhealthy gateways (retry amplification protection)
70
+ */
71
+ circuitBreaker?: {
72
+ /** Enable circuit breaker (default: true) */
73
+ enabled?: boolean;
74
+ /** Number of failures before opening circuit (default: 5) */
75
+ failureThreshold?: number;
76
+ /** Cooldown period in ms before attempting reset (default: 60000) */
77
+ resetTimeoutMs?: number;
78
+ /** Time window in ms for counting failures (default: 300000) */
79
+ failureWindowMs?: number;
80
+ /** Number of successes in half-open to close circuit (default: 2) */
81
+ successThreshold?: number;
82
+ };
83
+ }
84
+
85
+ // ============================================================================
86
+ // Arweave Configuration
87
+ // ============================================================================
88
+
89
+ /**
90
+ * Supported Irys payment tokens
91
+ * @see https://docs.irys.xyz/build/d/features/supported-tokens
92
+ */
93
+ export type IrysCurrency =
94
+ | 'base-eth' // RECOMMENDED: Base ETH (native to AGIRAILS)
95
+ | 'ethereum' // Ethereum mainnet ETH
96
+ | 'matic' // Polygon MATIC
97
+ | 'arbitrum' // Arbitrum ETH
98
+ | 'usdc-eth' // USDC on Ethereum
99
+ | 'usdc-polygon'; // USDC on Polygon
100
+
101
+ /**
102
+ * Irys network
103
+ */
104
+ export type IrysNetwork = 'mainnet' | 'devnet';
105
+
106
+ /**
107
+ * Configuration for Arweave client via Irys
108
+ */
109
+ export interface ArweaveConfig {
110
+ /**
111
+ * Private key for signing transactions
112
+ * SECURITY: Store in environment variable, never in code
113
+ */
114
+ privateKey: string;
115
+
116
+ /**
117
+ * RPC URL for the payment chain
118
+ * Required for blockchain operations
119
+ */
120
+ rpcUrl: string;
121
+
122
+ /**
123
+ * Payment currency/token
124
+ * @default 'base-eth'
125
+ */
126
+ currency?: IrysCurrency;
127
+
128
+ /**
129
+ * Irys network (mainnet or devnet)
130
+ * @default 'mainnet'
131
+ */
132
+ network?: IrysNetwork;
133
+
134
+ /**
135
+ * Request timeout in milliseconds
136
+ * @default 60000 (60 seconds)
137
+ */
138
+ timeout?: number;
139
+
140
+ /**
141
+ * Circuit breaker configuration for gateway health tracking
142
+ * When enabled, tracks gateway failures and temporarily blocks
143
+ * requests to unhealthy gateways (retry amplification protection)
144
+ */
145
+ circuitBreaker?: {
146
+ /** Enable circuit breaker (default: true) */
147
+ enabled?: boolean;
148
+ /** Number of failures before opening circuit (default: 5) */
149
+ failureThreshold?: number;
150
+ /** Cooldown period in ms before attempting reset (default: 60000) */
151
+ resetTimeoutMs?: number;
152
+ /** Time window in ms for counting failures (default: 300000) */
153
+ failureWindowMs?: number;
154
+ /** Number of successes in half-open to close circuit (default: 2) */
155
+ successThreshold?: number;
156
+ };
157
+ }
158
+
159
+ // ============================================================================
160
+ // Archive Bundle Types (AIP-7 §4.4)
161
+ // ============================================================================
162
+
163
+ /**
164
+ * Archive bundle type identifier
165
+ */
166
+ export const ARCHIVE_BUNDLE_TYPE = 'actp.archive.v1.minimal' as const;
167
+
168
+ /**
169
+ * Supported chain IDs for archive bundles
170
+ */
171
+ export type ArchiveChainId = 8453 | 84532; // Base Mainnet | Base Sepolia
172
+
173
+ /**
174
+ * Final transaction states that can be archived
175
+ */
176
+ export type ArchiveFinalState = 'SETTLED' | 'CANCELLED';
177
+
178
+ /**
179
+ * Transaction participants (addresses only, not full profiles)
180
+ */
181
+ export interface ArchiveParticipants {
182
+ /** Requester Ethereum address */
183
+ requester: string;
184
+ /** Provider Ethereum address */
185
+ provider: string;
186
+ }
187
+
188
+ /**
189
+ * IPFS CID references to full content
190
+ */
191
+ export interface ArchiveReferences {
192
+ /** IPFS CID of AIP-1 request metadata */
193
+ requestCID: string;
194
+ /** IPFS CID of AIP-4 delivery proof */
195
+ deliveryCID: string;
196
+ /** IPFS CID of actual result/output (optional) */
197
+ resultCID?: string;
198
+ }
199
+
200
+ /**
201
+ * Cryptographic hashes for verification
202
+ */
203
+ export interface ArchiveHashes {
204
+ /** keccak256 of canonical request metadata JSON */
205
+ requestHash: string;
206
+ /** keccak256 of canonical delivery proof JSON */
207
+ deliveryHash: string;
208
+ /** serviceHash from ACTPKernel transaction */
209
+ serviceHash: string;
210
+ }
211
+
212
+ /**
213
+ * Cryptographic signatures for self-verification
214
+ */
215
+ export interface ArchiveSignatures {
216
+ /** EIP-712 signature by provider over deliveryHash */
217
+ providerDeliverySignature: string;
218
+ /** Optional: requester signature authorizing settlement */
219
+ requesterSettlementSignature?: string;
220
+ }
221
+
222
+ /**
223
+ * EAS attestation reference
224
+ */
225
+ export interface ArchiveAttestation {
226
+ /** Ethereum Attestation Service UID */
227
+ easUID: string;
228
+ /** EAS schema UID used for attestation (optional) */
229
+ schemaUID?: string;
230
+ }
231
+
232
+ /**
233
+ * Escrow release details
234
+ */
235
+ export interface EscrowRelease {
236
+ /** Recipient address (provider or requester) */
237
+ to: string;
238
+ /** Released amount (USDC base units, string for BigInt safety) */
239
+ amount: string;
240
+ }
241
+
242
+ /**
243
+ * Settlement information
244
+ */
245
+ export interface ArchiveSettlement {
246
+ /** Settlement timestamp (Unix seconds) */
247
+ settledAt: number;
248
+ /** Final transaction state */
249
+ finalState: ArchiveFinalState;
250
+ /** Escrow release details */
251
+ escrowReleased: EscrowRelease;
252
+ /** Platform fee collected (USDC base units) */
253
+ platformFee: string;
254
+ /** Whether transaction went through dispute */
255
+ wasDisputed: boolean;
256
+ }
257
+
258
+ /**
259
+ * Archive Bundle (AIP-7 §4.4 - Minimal Hash-First)
260
+ *
261
+ * Contains minimal metadata with cryptographic hashes and references.
262
+ * Full content (request metadata, delivery proof) remains on IPFS.
263
+ */
264
+ export interface ArchiveBundle {
265
+ /** AGIRAILS protocol version (e.g., "1.0.0") */
266
+ protocolVersion: string;
267
+ /** Archive bundle schema version (e.g., "1.0.0") */
268
+ archiveSchemaVersion: string;
269
+ /** Archive bundle type identifier */
270
+ type: typeof ARCHIVE_BUNDLE_TYPE;
271
+ /** ACTP transaction ID (bytes32) */
272
+ txId: string;
273
+ /** Blockchain network chain ID */
274
+ chainId: ArchiveChainId;
275
+ /** Archive timestamp (Unix seconds) */
276
+ archivedAt: number;
277
+ /** Transaction participants (addresses only) */
278
+ participants: ArchiveParticipants;
279
+ /** IPFS CID references to full content */
280
+ references: ArchiveReferences;
281
+ /** Cryptographic hashes for verification */
282
+ hashes: ArchiveHashes;
283
+ /** Cryptographic signatures */
284
+ signatures: ArchiveSignatures;
285
+ /** EAS attestation reference (optional for cancelled transactions) */
286
+ attestation?: ArchiveAttestation;
287
+ /** Settlement information */
288
+ settlement: ArchiveSettlement;
289
+ }
290
+
291
+ // ============================================================================
292
+ // Upload/Download Results
293
+ // ============================================================================
294
+
295
+ /**
296
+ * Result of uploading to IPFS
297
+ */
298
+ export interface IPFSUploadResult {
299
+ /** IPFS CID (CIDv1, base32) */
300
+ cid: string;
301
+ /** Size of uploaded content in bytes */
302
+ size: number;
303
+ /** Upload timestamp */
304
+ uploadedAt: Date;
305
+ }
306
+
307
+ /**
308
+ * Result of uploading to Arweave
309
+ */
310
+ export interface ArweaveUploadResult {
311
+ /** Arweave transaction ID */
312
+ txId: string;
313
+ /** Size of uploaded content in bytes */
314
+ size: number;
315
+ /** Upload timestamp */
316
+ uploadedAt: Date;
317
+ /** Cost in the payment currency (wei for ETH) */
318
+ cost: string;
319
+ }
320
+
321
+ /**
322
+ * Result of downloading content
323
+ */
324
+ export interface DownloadResult<T = unknown> {
325
+ /** Downloaded and parsed content */
326
+ data: T;
327
+ /** Size of downloaded content in bytes */
328
+ size: number;
329
+ /** Download timestamp */
330
+ downloadedAt: Date;
331
+ }
332
+
333
+ // ============================================================================
334
+ // Irys Tags
335
+ // ============================================================================
336
+
337
+ /**
338
+ * Arweave/Irys tags for archive bundles
339
+ */
340
+ export interface ArchiveTags {
341
+ 'Content-Type': 'application/json';
342
+ Protocol: 'AGIRAILS';
343
+ Version: string;
344
+ Schema: string;
345
+ Type: typeof ARCHIVE_BUNDLE_TYPE;
346
+ ChainId: string;
347
+ TxId: string;
348
+ }
@@ -18,22 +18,23 @@ export class StateMachine {
18
18
  /**
19
19
  * Valid state transitions per Yellow Paper §3.2.2
20
20
  *
21
- * SECURITY FIX (CRITICAL-1): State machine must match ACTPKernel contract exactly
22
- * Per CLAUDE.md §Architecture Overview - ACTP Protocol State Machine:
23
- * - COMMITTED can transition to IN_PROGRESS, DELIVERED, or CANCELLED
21
+ * SECURITY FIX (AUDIT-2026-02): State machine must match ACTPKernel contract exactly
22
+ *
23
+ * Per on-chain ACTPKernel contract:
24
+ * - COMMITTED must go through IN_PROGRESS before DELIVERED (cannot skip)
25
+ * - DISPUTED can transition to SETTLED or CANCELLED (admin/pauser can cancel disputes)
24
26
  * - IN_PROGRESS can transition to DELIVERED or CANCELLED (not DISPUTED)
25
- * - DISPUTED can only transition to SETTLED (not CANCELLED)
26
27
  */
27
28
  private static readonly TRANSITIONS: Record<State, State[]> = {
28
29
  [State.INITIATED]: [State.QUOTED, State.COMMITTED, State.CANCELLED], // Allow direct INITIATED → COMMITTED (AIP-3)
29
30
  [State.QUOTED]: [State.COMMITTED, State.CANCELLED],
30
- // SECURITY FIX (CRITICAL-1): Add DELIVERED (can skip IN_PROGRESS)
31
- [State.COMMITTED]: [State.IN_PROGRESS, State.DELIVERED, State.CANCELLED],
32
- // SECURITY FIX (CRITICAL-1): Remove DISPUTED, add CANCELLED
31
+ // AUDIT FIX: COMMITTED cannot skip to DELIVERED - must go through IN_PROGRESS first
32
+ [State.COMMITTED]: [State.IN_PROGRESS, State.CANCELLED],
33
+ // IN_PROGRESS can transition to DELIVERED or CANCELLED
33
34
  [State.IN_PROGRESS]: [State.DELIVERED, State.CANCELLED],
34
35
  [State.DELIVERED]: [State.SETTLED, State.DISPUTED],
35
- // SECURITY FIX (CRITICAL-1): Remove CANCELLED (disputes resolve to SETTLED only)
36
- [State.DISPUTED]: [State.SETTLED],
36
+ // AUDIT FIX: DISPUTED can also transition to CANCELLED (admin/pauser emergency cancellation)
37
+ [State.DISPUTED]: [State.SETTLED, State.CANCELLED],
37
38
  [State.SETTLED]: [], // Terminal state
38
39
  [State.CANCELLED]: [] // Terminal state
39
40
  };
@@ -637,14 +637,12 @@ export async function withRecoveryGuidance<T>(
637
637
  ): Promise<T> {
638
638
  const { logGuidance = false, autoRetry = false, onError } = options;
639
639
 
640
- let lastError: unknown;
641
640
  let attempts = 0;
642
641
 
643
642
  do {
644
643
  try {
645
644
  return await operation();
646
645
  } catch (error) {
647
- lastError = error;
648
646
  const recovery = ErrorRecoveryGuide.analyze(error);
649
647
 
650
648
  if (onError) {
@@ -671,5 +669,6 @@ export async function withRecoveryGuidance<T>(
671
669
 
672
670
  throw error;
673
671
  }
672
+ // eslint-disable-next-line no-constant-condition
674
673
  } while (true);
675
674
  }
@@ -4,6 +4,7 @@
4
4
  */
5
5
 
6
6
  import { create, IPFSHTTPClient, Options } from 'kubo-rpc-client';
7
+ import { sdkLogger } from './Logger';
7
8
 
8
9
  /**
9
10
  * IPFS Client Interface (from DeliveryProofBuilder)
@@ -202,10 +203,10 @@ export class IPFSHTTPClientImpl implements IPFSClient {
202
203
 
203
204
  // For remote hosts, require HTTPS
204
205
  if (!isLocalhost && parsed.protocol !== 'https:') {
205
- console.warn(
206
- `[SECURITY WARNING] Using non-HTTPS protocol "${parsed.protocol}" for remote IPFS endpoint "${hostname}". ` +
207
- `This may expose data in transit. Consider using HTTPS.`
208
- );
206
+ sdkLogger.warn('Using non-HTTPS protocol for remote IPFS endpoint - data may be exposed in transit', {
207
+ protocol: parsed.protocol,
208
+ hostname,
209
+ });
209
210
  }
210
211
  }
211
212
 
@@ -10,6 +10,7 @@
10
10
  */
11
11
 
12
12
  import { assertSafeFileForRead, ensureSafeDir, ensureSafeFile } from './fsSafe';
13
+ import { sdkLogger } from './Logger';
13
14
 
14
15
  /**
15
16
  * Maximum allowed nonce value.
@@ -525,7 +526,7 @@ export class FileBasedNonceManager implements NonceManager {
525
526
  this.inMemory.recordNonce(messageType, nonce);
526
527
  // Fire-and-forget to maintain sync interface
527
528
  this.saveToFile().catch((err) => {
528
- console.error('Failed to save nonce manager state:', err);
529
+ sdkLogger.error('Failed to save nonce manager state', { error: err instanceof Error ? err.message : String(err) });
529
530
  });
530
531
  }
531
532
 
@@ -537,7 +538,7 @@ export class FileBasedNonceManager implements NonceManager {
537
538
  this.inMemory.resetNonce(messageType);
538
539
  // Fire-and-forget to maintain sync interface
539
540
  this.saveToFile().catch((err) => {
540
- console.error('Failed to save nonce manager state:', err);
541
+ sdkLogger.error('Failed to save nonce manager state', { error: err instanceof Error ? err.message : String(err) });
541
542
  });
542
543
  }
543
544
 
@@ -12,6 +12,7 @@
12
12
  */
13
13
 
14
14
  import { assertSafeFileForRead, ensureSafeDir, ensureSafeFile } from './fsSafe';
15
+ import { sdkLogger } from './Logger';
15
16
 
16
17
  /**
17
18
  * Interface for tracking used attestations
@@ -202,13 +203,10 @@ export class InMemoryUsedAttestationTracker implements IUsedAttestationTracker {
202
203
  *
203
204
  * @param maxAgeHours - Remove entries older than this many hours
204
205
  */
205
- cleanupOldEntries(maxAgeHours: number): number {
206
+ cleanupOldEntries(_maxAgeHours: number): number {
206
207
  // In-memory tracker doesn't track timestamps
207
208
  // This is a placeholder for future enhancement
208
- console.warn(
209
- 'cleanupOldEntries not implemented for InMemoryUsedAttestationTracker. ' +
210
- 'Consider using FileBasedUsedAttestationTracker for time-based cleanup.'
211
- );
209
+ sdkLogger.warn('cleanupOldEntries not implemented for InMemoryUsedAttestationTracker - use FileBasedUsedAttestationTracker');
212
210
  return 0;
213
211
  }
214
212
  }
@@ -350,7 +348,7 @@ export class FileBasedUsedAttestationTracker implements IUsedAttestationTracker
350
348
  const result = this.inMemory.recordUsageSync(attestationUID, txId);
351
349
  if (result) {
352
350
  this.saveToFile().catch((err) => {
353
- console.error('Failed to save attestation tracker state:', err);
351
+ sdkLogger.error('Failed to save attestation tracker state', { error: err instanceof Error ? err.message : String(err) });
354
352
  });
355
353
  }
356
354
  return result;