@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
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,251 +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
- };
68
-
69
- // Create and return client
70
- return ACTPClient.create(clientConfig);
71
- }
72
-
73
- // ============================================================================
74
- // Error Mapping
75
- // ============================================================================
76
-
77
- /**
78
- * Error codes for CLI errors
79
- */
80
- export const ErrorCode = {
81
- // Configuration errors
82
- NOT_INITIALIZED: 'NOT_INITIALIZED',
83
- CONFIG_CORRUPTED: 'CONFIG_CORRUPTED',
84
- INVALID_CONFIG: 'INVALID_CONFIG',
85
-
86
- // Input validation errors
87
- INVALID_ADDRESS: 'INVALID_ADDRESS',
88
- INVALID_AMOUNT: 'INVALID_AMOUNT',
89
- INVALID_DEADLINE: 'INVALID_DEADLINE',
90
- INVALID_TX_ID: 'INVALID_TX_ID',
91
-
92
- // Transaction errors
93
- TX_NOT_FOUND: 'TX_NOT_FOUND',
94
- INVALID_STATE_TRANSITION: 'INVALID_STATE_TRANSITION',
95
- INSUFFICIENT_BALANCE: 'INSUFFICIENT_BALANCE',
96
- DEADLINE_PASSED: 'DEADLINE_PASSED',
97
- DISPUTE_WINDOW_ACTIVE: 'DISPUTE_WINDOW_ACTIVE',
98
-
99
- // System errors
100
- FILE_LOCK_ERROR: 'FILE_LOCK_ERROR',
101
- NETWORK_ERROR: 'NETWORK_ERROR',
102
- UNKNOWN_ERROR: 'UNKNOWN_ERROR',
103
- } as const;
104
-
105
- export type ErrorCodeValue = (typeof ErrorCode)[keyof typeof ErrorCode];
106
-
107
- /**
108
- * Structured CLI error with code and details
109
- */
110
- export interface StructuredError {
111
- code: ErrorCodeValue;
112
- message: string;
113
- details?: Record<string, unknown>;
114
- }
115
-
116
- /**
117
- * Map SDK errors to CLI-friendly structured errors.
118
- *
119
- * SECURITY: Sanitizes paths and stack traces to prevent information disclosure.
120
- */
121
- export function mapError(error: unknown): StructuredError {
122
- const err = error as Error;
123
- // Sanitize the message to remove full paths
124
- const rawMessage = err?.message || String(error);
125
- const message = sanitizePath(rawMessage);
126
-
127
- // Configuration errors
128
- if (message.includes('not initialized') || message.includes('actp init')) {
129
- return {
130
- code: ErrorCode.NOT_INITIALIZED,
131
- message: 'ACTP not initialized. Run "actp init" first.',
132
- };
133
- }
134
-
135
- if (message.includes('Config file corrupted')) {
136
- return {
137
- code: ErrorCode.CONFIG_CORRUPTED,
138
- message: 'Configuration file is corrupted.',
139
- details: { suggestion: 'Run "actp init --force" to reinitialize.' },
140
- };
141
- }
142
-
143
- // Transaction errors (from SDK error classes)
144
- if (err?.name === 'TransactionNotFoundError' || message.includes('Transaction not found')) {
145
- const txIdMatch = message.match(/Transaction not found: (0x[a-fA-F0-9]+)/);
146
- return {
147
- code: ErrorCode.TX_NOT_FOUND,
148
- message: 'Transaction not found.',
149
- details: txIdMatch ? { txId: txIdMatch[1] } : undefined,
150
- };
151
- }
152
-
153
- if (err?.name === 'InvalidStateTransitionError' || message.includes('Invalid state transition')) {
154
- return {
155
- code: ErrorCode.INVALID_STATE_TRANSITION,
156
- message: 'Invalid state transition.',
157
- // SECURITY: Don't expose original message which may contain sensitive info
158
- };
159
- }
160
-
161
- if (err?.name === 'InsufficientBalanceError' || message.includes('Insufficient balance')) {
162
- return {
163
- code: ErrorCode.INSUFFICIENT_BALANCE,
164
- message: 'Insufficient balance for this operation.',
165
- // SECURITY: Don't expose balance details
166
- };
167
- }
168
-
169
- if (err?.name === 'DeadlinePassedError' || message.includes('Deadline passed')) {
170
- return {
171
- code: ErrorCode.DEADLINE_PASSED,
172
- message: 'Transaction deadline has passed.',
173
- };
174
- }
175
-
176
- if (err?.name === 'DisputeWindowActiveError' || message.includes('Dispute window')) {
177
- return {
178
- code: ErrorCode.DISPUTE_WINDOW_ACTIVE,
179
- message: 'Dispute window is still active.',
180
- // SECURITY: Don't expose window timing details
181
- };
182
- }
183
-
184
- // Validation errors
185
- if (err?.name === 'ValidationError') {
186
- if (message.includes('address')) {
187
- return {
188
- code: ErrorCode.INVALID_ADDRESS,
189
- message: sanitizePath(message),
190
- };
191
- }
192
- if (message.includes('amount') || message.includes('Amount')) {
193
- return {
194
- code: ErrorCode.INVALID_AMOUNT,
195
- message: sanitizePath(message),
196
- };
197
- }
198
- if (message.includes('deadline') || message.includes('Deadline')) {
199
- return {
200
- code: ErrorCode.INVALID_DEADLINE,
201
- message: sanitizePath(message),
202
- };
203
- }
204
- }
205
-
206
- // Lock errors
207
- if (message.includes('lock') || message.includes('ELOCKED')) {
208
- return {
209
- code: ErrorCode.FILE_LOCK_ERROR,
210
- message: 'Could not acquire lock. Another process may be using ACTP.',
211
- details: { suggestion: 'Wait a moment and try again.' },
212
- };
213
- }
214
-
215
- // Default: unknown error
216
- // SECURITY: Do NOT include stack traces in production - they reveal internal paths
217
- return {
218
- code: ErrorCode.UNKNOWN_ERROR,
219
- message: sanitizePath(message) || 'An unknown error occurred.',
220
- // SECURITY FIX: Stack traces removed to prevent information disclosure
221
- // In development mode, errors can be logged separately if needed
222
- };
223
- }
224
-
225
- // ============================================================================
226
- // Utilities
227
- // ============================================================================
228
-
229
- /**
230
- * Validate transaction ID format
231
- */
232
- export function isValidTxId(txId: string): boolean {
233
- return /^0x[a-fA-F0-9]{64}$/.test(txId);
234
- }
235
-
236
- /**
237
- * Format address for display (truncate middle)
238
- */
239
- export function formatAddress(address: string, length: number = 10): string {
240
- if (address.length <= length * 2 + 2) {
241
- return address;
242
- }
243
- return `${address.slice(0, length + 2)}...${address.slice(-length)}`;
244
- }
245
-
246
- /**
247
- * Format transaction ID for display (truncate)
248
- */
249
- export function formatTxId(txId: string, length: number = 8): string {
250
- return `${txId.slice(0, length + 2)}...`;
251
- }