@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.
Files changed (169) hide show
  1. package/dist/ACTPClient.d.ts +18 -0
  2. package/dist/ACTPClient.d.ts.map +1 -1
  3. package/dist/ACTPClient.js +72 -23
  4. package/dist/ACTPClient.js.map +1 -1
  5. package/dist/adapters/BasicAdapter.d.ts +15 -0
  6. package/dist/adapters/BasicAdapter.d.ts.map +1 -1
  7. package/dist/adapters/BasicAdapter.js +33 -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 +90 -12
  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/config/networks.d.ts +10 -2
  20. package/dist/config/networks.d.ts.map +1 -1
  21. package/dist/config/networks.js +31 -22
  22. package/dist/config/networks.js.map +1 -1
  23. package/dist/level0/request.d.ts.map +1 -1
  24. package/dist/level0/request.js +2 -1
  25. package/dist/level0/request.js.map +1 -1
  26. package/dist/runtime/BlockchainRuntime.d.ts.map +1 -1
  27. package/dist/runtime/BlockchainRuntime.js +11 -5
  28. package/dist/runtime/BlockchainRuntime.js.map +1 -1
  29. package/dist/utils/IPFSClient.d.ts +3 -1
  30. package/dist/utils/IPFSClient.d.ts.map +1 -1
  31. package/dist/utils/IPFSClient.js +27 -7
  32. package/dist/utils/IPFSClient.js.map +1 -1
  33. package/dist/wallet/AutoWalletProvider.d.ts +11 -1
  34. package/dist/wallet/AutoWalletProvider.d.ts.map +1 -1
  35. package/dist/wallet/AutoWalletProvider.js +84 -19
  36. package/dist/wallet/AutoWalletProvider.js.map +1 -1
  37. package/dist/wallet/IWalletProvider.d.ts +34 -0
  38. package/dist/wallet/IWalletProvider.d.ts.map +1 -1
  39. package/dist/wallet/SmartWalletRouter.d.ts +128 -0
  40. package/dist/wallet/SmartWalletRouter.d.ts.map +1 -0
  41. package/dist/wallet/SmartWalletRouter.js +248 -0
  42. package/dist/wallet/SmartWalletRouter.js.map +1 -0
  43. package/dist/wallet/aa/DualNonceManager.d.ts +26 -1
  44. package/dist/wallet/aa/DualNonceManager.d.ts.map +1 -1
  45. package/dist/wallet/aa/DualNonceManager.js +140 -6
  46. package/dist/wallet/aa/DualNonceManager.js.map +1 -1
  47. package/package.json +3 -6
  48. package/src/ACTPClient.ts +0 -1579
  49. package/src/abi/ACTPKernel.json +0 -1356
  50. package/src/abi/AgentRegistry.json +0 -915
  51. package/src/abi/ERC20.json +0 -40
  52. package/src/abi/EscrowVault.json +0 -134
  53. package/src/abi/IdentityRegistry.json +0 -316
  54. package/src/adapters/AdapterRegistry.ts +0 -173
  55. package/src/adapters/AdapterRouter.ts +0 -416
  56. package/src/adapters/BaseAdapter.ts +0 -498
  57. package/src/adapters/BasicAdapter.ts +0 -514
  58. package/src/adapters/IAdapter.ts +0 -292
  59. package/src/adapters/StandardAdapter.ts +0 -555
  60. package/src/adapters/X402Adapter.ts +0 -731
  61. package/src/adapters/index.ts +0 -60
  62. package/src/builders/DeliveryProofBuilder.ts +0 -327
  63. package/src/builders/QuoteBuilder.ts +0 -483
  64. package/src/builders/index.ts +0 -17
  65. package/src/cli/commands/balance.ts +0 -110
  66. package/src/cli/commands/batch.ts +0 -487
  67. package/src/cli/commands/config.ts +0 -231
  68. package/src/cli/commands/deploy-check.ts +0 -364
  69. package/src/cli/commands/deploy-env.ts +0 -120
  70. package/src/cli/commands/diff.ts +0 -141
  71. package/src/cli/commands/init.ts +0 -469
  72. package/src/cli/commands/mint.ts +0 -116
  73. package/src/cli/commands/pay.ts +0 -113
  74. package/src/cli/commands/publish.ts +0 -475
  75. package/src/cli/commands/pull.ts +0 -124
  76. package/src/cli/commands/register.ts +0 -247
  77. package/src/cli/commands/simulate.ts +0 -345
  78. package/src/cli/commands/time.ts +0 -302
  79. package/src/cli/commands/tx.ts +0 -448
  80. package/src/cli/commands/watch.ts +0 -211
  81. package/src/cli/index.ts +0 -134
  82. package/src/cli/utils/client.ts +0 -252
  83. package/src/cli/utils/config.ts +0 -389
  84. package/src/cli/utils/output.ts +0 -465
  85. package/src/cli/utils/wallet.ts +0 -109
  86. package/src/config/agirailsmd.ts +0 -262
  87. package/src/config/networks.ts +0 -275
  88. package/src/config/pendingPublish.ts +0 -237
  89. package/src/config/publishPipeline.ts +0 -359
  90. package/src/config/syncOperations.ts +0 -279
  91. package/src/erc8004/ERC8004Bridge.ts +0 -462
  92. package/src/erc8004/ReputationReporter.ts +0 -468
  93. package/src/erc8004/index.ts +0 -61
  94. package/src/errors/index.ts +0 -427
  95. package/src/index.ts +0 -364
  96. package/src/level0/Provider.ts +0 -117
  97. package/src/level0/ServiceDirectory.ts +0 -131
  98. package/src/level0/index.ts +0 -10
  99. package/src/level0/provide.ts +0 -132
  100. package/src/level0/request.ts +0 -432
  101. package/src/level1/Agent.ts +0 -1426
  102. package/src/level1/index.ts +0 -10
  103. package/src/level1/pricing/PriceCalculator.ts +0 -255
  104. package/src/level1/pricing/PricingStrategy.ts +0 -198
  105. package/src/level1/types/Job.ts +0 -179
  106. package/src/level1/types/Options.ts +0 -291
  107. package/src/level1/types/index.ts +0 -8
  108. package/src/protocol/ACTPKernel.ts +0 -808
  109. package/src/protocol/AgentRegistry.ts +0 -559
  110. package/src/protocol/DIDManager.ts +0 -629
  111. package/src/protocol/DIDResolver.ts +0 -554
  112. package/src/protocol/EASHelper.ts +0 -378
  113. package/src/protocol/EscrowVault.ts +0 -255
  114. package/src/protocol/EventMonitor.ts +0 -204
  115. package/src/protocol/MessageSigner.ts +0 -510
  116. package/src/protocol/ProofGenerator.ts +0 -339
  117. package/src/protocol/QuoteBuilder.ts +0 -15
  118. package/src/registry/AgentRegistryClient.ts +0 -202
  119. package/src/runtime/BlockchainRuntime.ts +0 -1015
  120. package/src/runtime/IACTPRuntime.ts +0 -306
  121. package/src/runtime/MockRuntime.ts +0 -1298
  122. package/src/runtime/MockStateManager.ts +0 -577
  123. package/src/runtime/index.ts +0 -25
  124. package/src/runtime/types/MockState.ts +0 -237
  125. package/src/storage/ArchiveBundleBuilder.ts +0 -561
  126. package/src/storage/ArweaveClient.ts +0 -946
  127. package/src/storage/FilebaseClient.ts +0 -790
  128. package/src/storage/index.ts +0 -96
  129. package/src/storage/types.ts +0 -348
  130. package/src/types/adapter.ts +0 -310
  131. package/src/types/agent.ts +0 -79
  132. package/src/types/did.ts +0 -223
  133. package/src/types/eip712.ts +0 -175
  134. package/src/types/erc8004.ts +0 -293
  135. package/src/types/escrow.ts +0 -27
  136. package/src/types/index.ts +0 -17
  137. package/src/types/message.ts +0 -145
  138. package/src/types/state.ts +0 -87
  139. package/src/types/transaction.ts +0 -69
  140. package/src/types/x402.ts +0 -251
  141. package/src/utils/ErrorRecoveryGuide.ts +0 -676
  142. package/src/utils/Helpers.ts +0 -688
  143. package/src/utils/IPFSClient.ts +0 -368
  144. package/src/utils/Logger.ts +0 -484
  145. package/src/utils/NonceManager.ts +0 -591
  146. package/src/utils/RateLimiter.ts +0 -534
  147. package/src/utils/ReceivedNonceTracker.ts +0 -567
  148. package/src/utils/SDKLifecycle.ts +0 -416
  149. package/src/utils/SecureNonce.ts +0 -78
  150. package/src/utils/Semaphore.ts +0 -276
  151. package/src/utils/UsedAttestationTracker.ts +0 -385
  152. package/src/utils/canonicalJson.ts +0 -38
  153. package/src/utils/circuitBreaker.ts +0 -324
  154. package/src/utils/computeTypeHash.ts +0 -48
  155. package/src/utils/fsSafe.ts +0 -80
  156. package/src/utils/index.ts +0 -80
  157. package/src/utils/retry.ts +0 -364
  158. package/src/utils/security.ts +0 -418
  159. package/src/utils/validation.ts +0 -540
  160. package/src/wallet/AutoWalletProvider.ts +0 -299
  161. package/src/wallet/EOAWalletProvider.ts +0 -69
  162. package/src/wallet/IWalletProvider.ts +0 -135
  163. package/src/wallet/aa/BundlerClient.ts +0 -274
  164. package/src/wallet/aa/DualNonceManager.ts +0 -173
  165. package/src/wallet/aa/PaymasterClient.ts +0 -174
  166. package/src/wallet/aa/TransactionBatcher.ts +0 -353
  167. package/src/wallet/aa/UserOpBuilder.ts +0 -246
  168. package/src/wallet/aa/constants.ts +0 -60
  169. package/src/wallet/keystore.ts +0 -240
package/src/cli/index.ts DELETED
@@ -1,134 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * ACTP CLI - Agent Commerce Transaction Protocol Command Line Interface
4
- *
5
- * The ACTP CLI is designed for AI agents - not humans clicking buttons.
6
- * Key differentiators:
7
- *
8
- * 1. **Machine-readable output**: JSON by default for scripting
9
- * 2. **Pipe-friendly**: Commands output just what you need
10
- * 3. **Structured exit codes**: 0=success, 1=error, 2=pending
11
- * 4. **Agent-first features**: watch, simulate, batch
12
- *
13
- * @module cli
14
- * @see https://docs.agirails.io/cli
15
- */
16
-
17
- import { Command } from 'commander';
18
- import { readFileSync } from 'fs';
19
- import { join } from 'path';
20
-
21
- // Read version from package.json (works in both src and dist)
22
- function getVersion(): string {
23
- try {
24
- // Try dist location first (when running compiled)
25
- const distPath = join(__dirname, '../../package.json');
26
- const pkg = JSON.parse(readFileSync(distPath, 'utf-8'));
27
- return pkg.version;
28
- } catch {
29
- try {
30
- // Fallback to src location (when running ts-node)
31
- const srcPath = join(__dirname, '../../../package.json');
32
- const pkg = JSON.parse(readFileSync(srcPath, 'utf-8'));
33
- return pkg.version;
34
- } catch {
35
- return '0.0.0'; // Fallback if package.json not found
36
- }
37
- }
38
- }
39
-
40
- // Import commands
41
- import { createInitCommand } from './commands/init';
42
- import { createPayCommand } from './commands/pay';
43
- import { createTxCommand } from './commands/tx';
44
- import { createBalanceCommand } from './commands/balance';
45
- import { createMintCommand } from './commands/mint';
46
- import { createConfigCommand } from './commands/config';
47
- import { createWatchCommand } from './commands/watch';
48
- import { createSimulateCommand } from './commands/simulate';
49
- import { createBatchCommand } from './commands/batch';
50
- import { createTimeCommand } from './commands/time';
51
- import { createPublishCommand } from './commands/publish';
52
- import { createPullCommand } from './commands/pull';
53
- import { createDiffCommand } from './commands/diff';
54
- import { createRegisterCommand } from './commands/register';
55
- import { createDeployEnvCommand } from './commands/deploy-env';
56
- import { createDeployCheckCommand } from './commands/deploy-check';
57
-
58
- // ============================================================================
59
- // Program Setup
60
- // ============================================================================
61
-
62
- const program = new Command();
63
-
64
- program
65
- .name('actp')
66
- .description(
67
- 'ACTP CLI - Agent Commerce Transaction Protocol\n\n' +
68
- 'The payment layer for AI agents. Create escrow-backed transactions,\n' +
69
- 'track state changes, and settle payments programmatically.\n\n' +
70
- 'Quick Start:\n' +
71
- ' $ actp init Initialize in current directory\n' +
72
- ' $ actp pay 0xProvider 100 Create a payment\n' +
73
- ' $ actp tx status <txId> Check transaction status\n\n' +
74
- 'Output Modes:\n' +
75
- ' --json Machine-readable JSON output\n' +
76
- ' --quiet Minimal output (just the essential value)'
77
- )
78
- .version(getVersion(), '-v, --version', 'Output the version number')
79
- .helpOption('-h, --help', 'Display help for command');
80
-
81
- // ============================================================================
82
- // Register Commands
83
- // ============================================================================
84
-
85
- // Core commands (most used)
86
- program.addCommand(createInitCommand());
87
- program.addCommand(createPayCommand());
88
- program.addCommand(createTxCommand());
89
- program.addCommand(createBalanceCommand());
90
- program.addCommand(createMintCommand());
91
- program.addCommand(createConfigCommand());
92
-
93
- // Agent-first features
94
- program.addCommand(createWatchCommand());
95
- program.addCommand(createSimulateCommand());
96
- program.addCommand(createBatchCommand());
97
-
98
- // Mock mode utilities
99
- program.addCommand(createTimeCommand());
100
-
101
- // Config sync commands (AGIRAILS.md as source of truth)
102
- program.addCommand(createPublishCommand());
103
- program.addCommand(createPullCommand());
104
- program.addCommand(createDiffCommand());
105
-
106
- // AIP-12: Gas-free registration
107
- program.addCommand(createRegisterCommand());
108
-
109
- // AIP-13: Deployment security
110
- program.addCommand(createDeployEnvCommand());
111
- program.addCommand(createDeployCheckCommand());
112
-
113
- // ============================================================================
114
- // Error Handling
115
- // ============================================================================
116
-
117
- // Handle unknown commands
118
- program.on('command:*', (operands) => {
119
- console.error(`Error: Unknown command '${operands[0]}'`);
120
- console.error('');
121
- console.error('Run "actp --help" for available commands.');
122
- process.exit(1);
123
- });
124
-
125
- // ============================================================================
126
- // Parse & Execute
127
- // ============================================================================
128
-
129
- program.parse(process.argv);
130
-
131
- // If no arguments, show help
132
- if (process.argv.length === 2) {
133
- program.outputHelp();
134
- }
@@ -1,252 +0,0 @@
1
- /**
2
- * SDK Client Factory for CLI
3
- *
4
- * Creates and manages ACTPClient instances based on CLI configuration.
5
- * Handles mode-specific initialization and error mapping.
6
- *
7
- * SECURITY: Error messages are sanitized to prevent information disclosure.
8
- *
9
- * @module cli/utils/client
10
- */
11
-
12
- import * as os from 'os';
13
- import { ACTPClient, ACTPClientConfig } from '../../ACTPClient';
14
- import { loadConfig } from './config';
15
-
16
- // ============================================================================
17
- // Security: Path Sanitization
18
- // ============================================================================
19
-
20
- /**
21
- * Sanitize a file path for safe display in error messages.
22
- *
23
- * SECURITY: Replaces home directory with ~ to prevent disclosure of:
24
- * - Full home directory paths
25
- * - Usernames embedded in paths
26
- * - System-specific directory structures
27
- *
28
- * @param fullPath - The full file path to sanitize
29
- * @returns Sanitized path safe for display
30
- */
31
- function sanitizePath(fullPath: string): string {
32
- const home = os.homedir();
33
- // Replace home directory with ~ to avoid disclosing username/path
34
- return fullPath.replace(home, '~');
35
- }
36
-
37
- // ============================================================================
38
- // Client Factory
39
- // ============================================================================
40
-
41
- /**
42
- * Create an ACTPClient instance from CLI configuration
43
- *
44
- * Reads configuration from .actp/config.json and creates
45
- * an appropriate client instance for the configured mode.
46
- *
47
- * @param projectRoot - Project root directory (defaults to cwd)
48
- * @returns Initialized ACTPClient
49
- * @throws Error if config invalid or client creation fails
50
- */
51
- export async function createClient(
52
- projectRoot: string = process.cwd()
53
- ): Promise<ACTPClient> {
54
- // Load configuration
55
- const config = loadConfig(projectRoot);
56
-
57
- // NOTE: We intentionally do NOT call validateConfigForMode() here.
58
- // ACTPClient.create() handles keystore resolution (AIP-13) and provides
59
- // proper error messages if no credentials are found. Premature validation
60
- // would block keystore/env-var-based auth flows.
61
-
62
- // Build client config
63
- const clientConfig: ACTPClientConfig = {
64
- mode: config.mode,
65
- requesterAddress: config.address,
66
- stateDirectory: projectRoot,
67
- wallet: config.wallet === 'auto' ? 'auto' : undefined,
68
- };
69
-
70
- // Create and return client
71
- return ACTPClient.create(clientConfig);
72
- }
73
-
74
- // ============================================================================
75
- // Error Mapping
76
- // ============================================================================
77
-
78
- /**
79
- * Error codes for CLI errors
80
- */
81
- export const ErrorCode = {
82
- // Configuration errors
83
- NOT_INITIALIZED: 'NOT_INITIALIZED',
84
- CONFIG_CORRUPTED: 'CONFIG_CORRUPTED',
85
- INVALID_CONFIG: 'INVALID_CONFIG',
86
-
87
- // Input validation errors
88
- INVALID_ADDRESS: 'INVALID_ADDRESS',
89
- INVALID_AMOUNT: 'INVALID_AMOUNT',
90
- INVALID_DEADLINE: 'INVALID_DEADLINE',
91
- INVALID_TX_ID: 'INVALID_TX_ID',
92
-
93
- // Transaction errors
94
- TX_NOT_FOUND: 'TX_NOT_FOUND',
95
- INVALID_STATE_TRANSITION: 'INVALID_STATE_TRANSITION',
96
- INSUFFICIENT_BALANCE: 'INSUFFICIENT_BALANCE',
97
- DEADLINE_PASSED: 'DEADLINE_PASSED',
98
- DISPUTE_WINDOW_ACTIVE: 'DISPUTE_WINDOW_ACTIVE',
99
-
100
- // System errors
101
- FILE_LOCK_ERROR: 'FILE_LOCK_ERROR',
102
- NETWORK_ERROR: 'NETWORK_ERROR',
103
- UNKNOWN_ERROR: 'UNKNOWN_ERROR',
104
- } as const;
105
-
106
- export type ErrorCodeValue = (typeof ErrorCode)[keyof typeof ErrorCode];
107
-
108
- /**
109
- * Structured CLI error with code and details
110
- */
111
- export interface StructuredError {
112
- code: ErrorCodeValue;
113
- message: string;
114
- details?: Record<string, unknown>;
115
- }
116
-
117
- /**
118
- * Map SDK errors to CLI-friendly structured errors.
119
- *
120
- * SECURITY: Sanitizes paths and stack traces to prevent information disclosure.
121
- */
122
- export function mapError(error: unknown): StructuredError {
123
- const err = error as Error;
124
- // Sanitize the message to remove full paths
125
- const rawMessage = err?.message || String(error);
126
- const message = sanitizePath(rawMessage);
127
-
128
- // Configuration errors
129
- if (message.includes('not initialized') || message.includes('actp init')) {
130
- return {
131
- code: ErrorCode.NOT_INITIALIZED,
132
- message: 'ACTP not initialized. Run "actp init" first.',
133
- };
134
- }
135
-
136
- if (message.includes('Config file corrupted')) {
137
- return {
138
- code: ErrorCode.CONFIG_CORRUPTED,
139
- message: 'Configuration file is corrupted.',
140
- details: { suggestion: 'Run "actp init --force" to reinitialize.' },
141
- };
142
- }
143
-
144
- // Transaction errors (from SDK error classes)
145
- if (err?.name === 'TransactionNotFoundError' || message.includes('Transaction not found')) {
146
- const txIdMatch = message.match(/Transaction not found: (0x[a-fA-F0-9]+)/);
147
- return {
148
- code: ErrorCode.TX_NOT_FOUND,
149
- message: 'Transaction not found.',
150
- details: txIdMatch ? { txId: txIdMatch[1] } : undefined,
151
- };
152
- }
153
-
154
- if (err?.name === 'InvalidStateTransitionError' || message.includes('Invalid state transition')) {
155
- return {
156
- code: ErrorCode.INVALID_STATE_TRANSITION,
157
- message: 'Invalid state transition.',
158
- // SECURITY: Don't expose original message which may contain sensitive info
159
- };
160
- }
161
-
162
- if (err?.name === 'InsufficientBalanceError' || message.includes('Insufficient balance')) {
163
- return {
164
- code: ErrorCode.INSUFFICIENT_BALANCE,
165
- message: 'Insufficient balance for this operation.',
166
- // SECURITY: Don't expose balance details
167
- };
168
- }
169
-
170
- if (err?.name === 'DeadlinePassedError' || message.includes('Deadline passed')) {
171
- return {
172
- code: ErrorCode.DEADLINE_PASSED,
173
- message: 'Transaction deadline has passed.',
174
- };
175
- }
176
-
177
- if (err?.name === 'DisputeWindowActiveError' || message.includes('Dispute window')) {
178
- return {
179
- code: ErrorCode.DISPUTE_WINDOW_ACTIVE,
180
- message: 'Dispute window is still active.',
181
- // SECURITY: Don't expose window timing details
182
- };
183
- }
184
-
185
- // Validation errors
186
- if (err?.name === 'ValidationError') {
187
- if (message.includes('address')) {
188
- return {
189
- code: ErrorCode.INVALID_ADDRESS,
190
- message: sanitizePath(message),
191
- };
192
- }
193
- if (message.includes('amount') || message.includes('Amount')) {
194
- return {
195
- code: ErrorCode.INVALID_AMOUNT,
196
- message: sanitizePath(message),
197
- };
198
- }
199
- if (message.includes('deadline') || message.includes('Deadline')) {
200
- return {
201
- code: ErrorCode.INVALID_DEADLINE,
202
- message: sanitizePath(message),
203
- };
204
- }
205
- }
206
-
207
- // Lock errors
208
- if (message.includes('lock') || message.includes('ELOCKED')) {
209
- return {
210
- code: ErrorCode.FILE_LOCK_ERROR,
211
- message: 'Could not acquire lock. Another process may be using ACTP.',
212
- details: { suggestion: 'Wait a moment and try again.' },
213
- };
214
- }
215
-
216
- // Default: unknown error
217
- // SECURITY: Do NOT include stack traces in production - they reveal internal paths
218
- return {
219
- code: ErrorCode.UNKNOWN_ERROR,
220
- message: sanitizePath(message) || 'An unknown error occurred.',
221
- // SECURITY FIX: Stack traces removed to prevent information disclosure
222
- // In development mode, errors can be logged separately if needed
223
- };
224
- }
225
-
226
- // ============================================================================
227
- // Utilities
228
- // ============================================================================
229
-
230
- /**
231
- * Validate transaction ID format
232
- */
233
- export function isValidTxId(txId: string): boolean {
234
- return /^0x[a-fA-F0-9]{64}$/.test(txId);
235
- }
236
-
237
- /**
238
- * Format address for display (truncate middle)
239
- */
240
- export function formatAddress(address: string, length: number = 10): string {
241
- if (address.length <= length * 2 + 2) {
242
- return address;
243
- }
244
- return `${address.slice(0, length + 2)}...${address.slice(-length)}`;
245
- }
246
-
247
- /**
248
- * Format transaction ID for display (truncate)
249
- */
250
- export function formatTxId(txId: string, length: number = 8): string {
251
- return `${txId.slice(0, length + 2)}...`;
252
- }