@naculus/connect-core 0.1.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.
- package/LICENSE +21 -0
- package/dist/index.cjs +19 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +3884 -0
- package/dist/index.d.ts +3884 -0
- package/dist/index.js +19 -0
- package/dist/index.js.map +1 -0
- package/package.json +29 -0
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,3884 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Error types for Account Abstraction (ERC-4337) operations.
|
|
3
|
+
*
|
|
4
|
+
* Independent error class — core package does not depend on wallet-engine.
|
|
5
|
+
*/
|
|
6
|
+
type AAErrorCode = "aa_unsupported_chain" | "aa_no_bundler" | "aa_no_paymaster" | "aa_no_entry_point" | "aa_no_factory" | "aa_account_not_deployed" | "aa_account_already_deployed" | "aa_invalid_owner" | "aa_user_op_failed" | "aa_user_op_rejected" | "aa_estimation_failed" | "aa_signature_failed" | "aa_rpc_error" | "aa_invalid_input" | "aa_unknown_account_type" | "aa_no_calls" | "aa_encode_error" | "aa_paymaster_rejected" | "aa_receipt_timeout" | "aa_unknown_error";
|
|
7
|
+
/** Human-readable messages for each error code */
|
|
8
|
+
declare const AA_ERROR_MESSAGES: Record<AAErrorCode, string>;
|
|
9
|
+
declare class AccountAbstractionError extends Error {
|
|
10
|
+
readonly code: AAErrorCode;
|
|
11
|
+
readonly cause?: unknown | undefined;
|
|
12
|
+
constructor(code: AAErrorCode, message?: string, cause?: unknown | undefined);
|
|
13
|
+
hasCode(code: AAErrorCode): boolean;
|
|
14
|
+
}
|
|
15
|
+
/** Type guard */
|
|
16
|
+
declare function isAAError(e: unknown): e is AccountAbstractionError;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* ERC-4337 Account Abstraction Types
|
|
20
|
+
*
|
|
21
|
+
* Defines the type hierarchy for Smart Contract Wallet management,
|
|
22
|
+
* UserOperation construction, Paymaster integration, and batch transactions.
|
|
23
|
+
*
|
|
24
|
+
* @see docs/features/account-abstraction.md
|
|
25
|
+
*/
|
|
26
|
+
type Address = `0x${string}`;
|
|
27
|
+
type Hex = `0x${string}`;
|
|
28
|
+
/**
|
|
29
|
+
* ERC-4337 UserOperation structure.
|
|
30
|
+
* Follows the v0.7 spec: accountGasLimits replaces separate callGasLimit/verificationGasLimit,
|
|
31
|
+
* and paymasterPostOpGasLimit is bundled into paymasterData.
|
|
32
|
+
*/
|
|
33
|
+
interface UserOperation {
|
|
34
|
+
sender: Address;
|
|
35
|
+
nonce: bigint;
|
|
36
|
+
initCode: Hex;
|
|
37
|
+
callData: Hex;
|
|
38
|
+
/** ABI-encoded callGasLimit + verificationGasLimit (v0.7) */
|
|
39
|
+
accountGasLimits: Hex;
|
|
40
|
+
preVerificationGas: bigint;
|
|
41
|
+
maxFeePerGas: bigint;
|
|
42
|
+
maxPriorityFeePerGas: bigint;
|
|
43
|
+
/** ABI-encoded paymaster + paymasterVerificationGasLimit + paymasterPostOpGasLimit + paymasterData */
|
|
44
|
+
paymasterAndData: Hex;
|
|
45
|
+
signature: Hex;
|
|
46
|
+
}
|
|
47
|
+
interface Call {
|
|
48
|
+
/** Target contract address */
|
|
49
|
+
to: Address;
|
|
50
|
+
/** Value in wei (0n for pure function calls) */
|
|
51
|
+
value: bigint;
|
|
52
|
+
/** Encoded calldata */
|
|
53
|
+
data: Hex;
|
|
54
|
+
}
|
|
55
|
+
type AccountType = "simple" | "light" | "kernel" | "safe";
|
|
56
|
+
interface SmartAccountConfig {
|
|
57
|
+
/** Owner address (typically an EOA) */
|
|
58
|
+
owner: Address;
|
|
59
|
+
/** Optional salt for CREATE2 deterministic address */
|
|
60
|
+
salt?: bigint;
|
|
61
|
+
/** Account implementation type */
|
|
62
|
+
accountType: AccountType;
|
|
63
|
+
/** ERC-4337 EntryPoint contract address */
|
|
64
|
+
entryPoint: Address;
|
|
65
|
+
/** Chain ID (CAIP-2 format, e.g. "eip155:1") */
|
|
66
|
+
chainId: string;
|
|
67
|
+
}
|
|
68
|
+
interface SmartAccountInfo {
|
|
69
|
+
/** Deterministic counterfactual address */
|
|
70
|
+
address: Address;
|
|
71
|
+
/** Whether the contract is deployed on-chain */
|
|
72
|
+
isDeployed: boolean;
|
|
73
|
+
/** Account type */
|
|
74
|
+
accountType: AccountType;
|
|
75
|
+
/** Owner address */
|
|
76
|
+
owner: Address;
|
|
77
|
+
}
|
|
78
|
+
interface BundlerClient {
|
|
79
|
+
/** RPC endpoint URL */
|
|
80
|
+
url: string;
|
|
81
|
+
/** Optional API key for authenticated bundler services */
|
|
82
|
+
apiKey?: string;
|
|
83
|
+
}
|
|
84
|
+
interface UserOperationResponse {
|
|
85
|
+
/** UserOp hash (returned by eth_sendUserOperation) */
|
|
86
|
+
userOpHash: Hex;
|
|
87
|
+
/** Smart account sender address */
|
|
88
|
+
sender: Address;
|
|
89
|
+
/** UserOp nonce */
|
|
90
|
+
nonce: bigint;
|
|
91
|
+
}
|
|
92
|
+
interface UserOperationReceipt {
|
|
93
|
+
userOpHash: Hex;
|
|
94
|
+
entryPoint: Address;
|
|
95
|
+
sender: Address;
|
|
96
|
+
nonce: bigint;
|
|
97
|
+
paymaster?: Address;
|
|
98
|
+
actualGasUsed: bigint;
|
|
99
|
+
actualGasCost: bigint;
|
|
100
|
+
success: boolean;
|
|
101
|
+
/** Transaction receipt of the HandleOps bundle */
|
|
102
|
+
transactionHash: Hex;
|
|
103
|
+
/** Array of logs emitted during execution */
|
|
104
|
+
logs: Log[];
|
|
105
|
+
}
|
|
106
|
+
interface Log {
|
|
107
|
+
address: Address;
|
|
108
|
+
topics: Hex[];
|
|
109
|
+
data: Hex;
|
|
110
|
+
}
|
|
111
|
+
interface UserOperationGasEstimate {
|
|
112
|
+
callGasLimit: bigint;
|
|
113
|
+
verificationGasLimit: bigint;
|
|
114
|
+
preVerificationGas: bigint;
|
|
115
|
+
/** v0.7 bundlers may return accountGasLimits */
|
|
116
|
+
accountGasLimits?: Hex;
|
|
117
|
+
}
|
|
118
|
+
type PaymasterType = "verifying" | "token" | "sponsor" | "custom";
|
|
119
|
+
interface PaymasterConfig {
|
|
120
|
+
type: PaymasterType;
|
|
121
|
+
/** Paymaster RPC URL */
|
|
122
|
+
url: string;
|
|
123
|
+
/** Optional policy configuration */
|
|
124
|
+
policy?: {
|
|
125
|
+
/** Whitelisted dApp origins */
|
|
126
|
+
allowedDapps?: string[];
|
|
127
|
+
/** ERC-20 token address for token paymaster */
|
|
128
|
+
token?: Address;
|
|
129
|
+
/** Maximum gas per UserOperation */
|
|
130
|
+
maxGasPerUserOp?: bigint;
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
interface PaymasterData {
|
|
134
|
+
/** The paymasterAndData hex to inject into UserOperation */
|
|
135
|
+
paymasterAndData: Hex;
|
|
136
|
+
/** Human-readable sponsorship info */
|
|
137
|
+
sponsorInfo?: string;
|
|
138
|
+
}
|
|
139
|
+
interface Paymaster {
|
|
140
|
+
/** Get paymaster data for a UserOperation */
|
|
141
|
+
getPaymasterData(userOp: Partial<UserOperation>): Promise<PaymasterData>;
|
|
142
|
+
/** Verify if a UserOperation is eligible for sponsorship */
|
|
143
|
+
isSponsored(userOp: Partial<UserOperation>): Promise<boolean>;
|
|
144
|
+
}
|
|
145
|
+
interface SendUserOpOptions {
|
|
146
|
+
/** Optional gas overrides */
|
|
147
|
+
gasOverrides?: {
|
|
148
|
+
callGasLimit?: bigint;
|
|
149
|
+
verificationGasLimit?: bigint;
|
|
150
|
+
preVerificationGas?: bigint;
|
|
151
|
+
maxFeePerGas?: bigint;
|
|
152
|
+
maxPriorityFeePerGas?: bigint;
|
|
153
|
+
};
|
|
154
|
+
/** Optional paymaster configuration */
|
|
155
|
+
paymaster?: PaymasterConfig;
|
|
156
|
+
/** Whether to skip deploy (for already deployed accounts) */
|
|
157
|
+
skipDeploy?: boolean;
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* ERC-4337 EntryPoint v0.6 contract addresses.
|
|
161
|
+
* https://github.com/eth-infinitism/account-abstraction
|
|
162
|
+
*/
|
|
163
|
+
declare const ENTRY_POINT_V0_6: Address;
|
|
164
|
+
/**
|
|
165
|
+
* ERC-4337 EntryPoint v0.7 contract address (same on all chains).
|
|
166
|
+
*/
|
|
167
|
+
declare const ENTRY_POINT_V0_7: Address;
|
|
168
|
+
/**
|
|
169
|
+
* Default EntryPoint address (v0.7).
|
|
170
|
+
*/
|
|
171
|
+
declare const DEFAULT_ENTRY_POINT: `0x${string}`;
|
|
172
|
+
/**
|
|
173
|
+
* SimpleAccount Factory address (eth-infinitism).
|
|
174
|
+
* Deployed at the same address on all supported chains via CREATE2.
|
|
175
|
+
*/
|
|
176
|
+
declare const SIMPLE_ACCOUNT_FACTORY: Address;
|
|
177
|
+
/** Default call gas limit for UserOperations */
|
|
178
|
+
declare const DEFAULT_CALL_GAS_LIMIT = 100000n;
|
|
179
|
+
/** Default verification gas limit for UserOperations */
|
|
180
|
+
declare const DEFAULT_VERIFICATION_GAS_LIMIT = 100000n;
|
|
181
|
+
/** Default pre-verification gas for UserOperations */
|
|
182
|
+
declare const DEFAULT_PRE_VERIFICATION_GAS = 50000n;
|
|
183
|
+
/**
|
|
184
|
+
* Chains known to support ERC-4337 AA (EntryPoint deployed).
|
|
185
|
+
* Keyed by CAIP-2 chain ID.
|
|
186
|
+
*/
|
|
187
|
+
declare const AA_SUPPORTED_CHAINS: Record<string, {
|
|
188
|
+
entryPoint: Address;
|
|
189
|
+
factory: Address;
|
|
190
|
+
}>;
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Paymaster Integration for ERC-4337
|
|
194
|
+
*
|
|
195
|
+
* Provides Paymaster abstractions for gas sponsorship:
|
|
196
|
+
* - Paymaster interface (pluggable)
|
|
197
|
+
* - VerifyingPaymaster: API-based sponsorship via paymaster RPC
|
|
198
|
+
* - PaymasterService: orchestrator for paymaster data injection
|
|
199
|
+
*
|
|
200
|
+
* @see docs/features/account-abstraction.md
|
|
201
|
+
*/
|
|
202
|
+
|
|
203
|
+
interface PaymasterServiceConfig {
|
|
204
|
+
/** Paymaster RPC URL */
|
|
205
|
+
url: string;
|
|
206
|
+
/** Paymaster type */
|
|
207
|
+
type: PaymasterType;
|
|
208
|
+
/** Optional policy configuration */
|
|
209
|
+
policy?: {
|
|
210
|
+
allowedDapps?: string[];
|
|
211
|
+
token?: Address;
|
|
212
|
+
maxGasPerUserOp?: bigint;
|
|
213
|
+
};
|
|
214
|
+
/** Optional API key for authenticated paymaster */
|
|
215
|
+
apiKey?: string;
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* PaymasterService manages Paymaster interactions for ERC-4337 UserOperations.
|
|
219
|
+
*
|
|
220
|
+
* Supports:
|
|
221
|
+
* - Verifying paymaster (API-based sponsorship approval)
|
|
222
|
+
* - Sponsor paymaster (free gas for whitelisted dApps)
|
|
223
|
+
* - Custom paymaster implementations
|
|
224
|
+
*/
|
|
225
|
+
declare class PaymasterService implements Paymaster {
|
|
226
|
+
private config;
|
|
227
|
+
private _sponsorInfo;
|
|
228
|
+
constructor(config: PaymasterServiceConfig);
|
|
229
|
+
/**
|
|
230
|
+
* Get paymaster data for a UserOperation.
|
|
231
|
+
*
|
|
232
|
+
* For verifying paymasters, this calls the paymaster RPC's
|
|
233
|
+
* pm_sponsorUserOperation method.
|
|
234
|
+
*
|
|
235
|
+
* @param userOp - The UserOperation to sponsor
|
|
236
|
+
* @returns Paymaster data including paymasterAndData hex
|
|
237
|
+
*/
|
|
238
|
+
getPaymasterData(userOp: Partial<UserOperation>): Promise<PaymasterData>;
|
|
239
|
+
/**
|
|
240
|
+
* Check if a UserOperation is eligible for sponsorship.
|
|
241
|
+
*
|
|
242
|
+
* @param userOp - The UserOperation to check
|
|
243
|
+
* @returns true if the paymaster would sponsor this operation
|
|
244
|
+
*/
|
|
245
|
+
isSponsored(userOp: Partial<UserOperation>): Promise<boolean>;
|
|
246
|
+
/**
|
|
247
|
+
* Get human-readable sponsorship info.
|
|
248
|
+
*/
|
|
249
|
+
get sponsorInfo(): string | null;
|
|
250
|
+
/**
|
|
251
|
+
* Get paymaster data using a verifying paymaster.
|
|
252
|
+
* Calls the paymaster RPC's pm_sponsorUserOperation method.
|
|
253
|
+
*/
|
|
254
|
+
private getVerifyingPaymasterData;
|
|
255
|
+
/**
|
|
256
|
+
* Get paymaster data for a simple sponsor paymaster.
|
|
257
|
+
* Uses a static or policy-based sponsorship.
|
|
258
|
+
*/
|
|
259
|
+
private getSponsorPaymasterData;
|
|
260
|
+
/**
|
|
261
|
+
* Get paymaster data for a token paymaster.
|
|
262
|
+
* Requires an ERC-20 token for gas payment.
|
|
263
|
+
*/
|
|
264
|
+
private getTokenPaymasterData;
|
|
265
|
+
/**
|
|
266
|
+
* Get paymaster data using a custom paymaster implementation.
|
|
267
|
+
* Delegates to the configured URL which should implement the paymaster RPC.
|
|
268
|
+
*/
|
|
269
|
+
private getCustomPaymasterData;
|
|
270
|
+
/**
|
|
271
|
+
* Serialize a partial UserOperation for paymaster RPC calls.
|
|
272
|
+
* Converts bigint fields to hex strings.
|
|
273
|
+
*/
|
|
274
|
+
private serializeForPaymaster;
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* Create a PaymasterService from a PaymasterConfig.
|
|
278
|
+
*
|
|
279
|
+
* @param config - Paymaster configuration
|
|
280
|
+
* @returns PaymasterService instance
|
|
281
|
+
*/
|
|
282
|
+
declare function createPaymasterService(config: PaymasterConfig): PaymasterService;
|
|
283
|
+
|
|
284
|
+
/**
|
|
285
|
+
* Smart Account Manager
|
|
286
|
+
*
|
|
287
|
+
* Manages ERC-4337 Smart Contract Wallet lifecycle:
|
|
288
|
+
* - Counterfactual address computation (CREATE2)
|
|
289
|
+
* - Account deployment via factory contract
|
|
290
|
+
* - Deploy-and-execute (merge deploy into first UserOperation)
|
|
291
|
+
*
|
|
292
|
+
* Supports SimpleAccount (eth-infinitism) with EntryPoint v0.7.
|
|
293
|
+
*
|
|
294
|
+
* @see docs/features/account-abstraction.md
|
|
295
|
+
*/
|
|
296
|
+
|
|
297
|
+
interface SmartAccountManagerConfig {
|
|
298
|
+
/** RPC URL for the target chain */
|
|
299
|
+
rpcUrl: string;
|
|
300
|
+
/** Bundler client configuration */
|
|
301
|
+
bundlerClient: BundlerClient;
|
|
302
|
+
/** Optional paymaster service */
|
|
303
|
+
paymaster?: PaymasterService;
|
|
304
|
+
/** Default paymaster configuration (used if no paymaster instance provided) */
|
|
305
|
+
defaultPaymasterConfig?: PaymasterConfig;
|
|
306
|
+
/** Chain ID in CAIP-2 format */
|
|
307
|
+
chainId: string;
|
|
308
|
+
}
|
|
309
|
+
declare class SmartAccountManager {
|
|
310
|
+
private config;
|
|
311
|
+
constructor(config: SmartAccountManagerConfig);
|
|
312
|
+
/**
|
|
313
|
+
* Check if ERC-4337 is supported on the configured chain.
|
|
314
|
+
*/
|
|
315
|
+
isAASupported(chainId?: string): boolean;
|
|
316
|
+
/**
|
|
317
|
+
* Compute the counterfactual address for a smart account.
|
|
318
|
+
* The account does not need to be deployed yet.
|
|
319
|
+
*
|
|
320
|
+
* Uses the factory's createAccount to compute the address via eth_call.
|
|
321
|
+
*
|
|
322
|
+
* @param config - Smart account configuration
|
|
323
|
+
* @returns The deterministic smart account address
|
|
324
|
+
*/
|
|
325
|
+
getAccountAddress(config: SmartAccountConfig): Promise<Address>;
|
|
326
|
+
/**
|
|
327
|
+
* Create a SmartAccountManager instance for a given smart account.
|
|
328
|
+
* Computes the address but does not deploy.
|
|
329
|
+
*
|
|
330
|
+
* @param config - Smart account configuration
|
|
331
|
+
* @returns Smart account info
|
|
332
|
+
*/
|
|
333
|
+
createAccount(config: SmartAccountConfig): Promise<SmartAccountInfo>;
|
|
334
|
+
/**
|
|
335
|
+
* Deploy a smart account to the blockchain.
|
|
336
|
+
*
|
|
337
|
+
* Sends a raw transaction to the factory contract with the createAccount call.
|
|
338
|
+
*
|
|
339
|
+
* @param config - Smart account configuration
|
|
340
|
+
* @returns Transaction hash
|
|
341
|
+
*/
|
|
342
|
+
deployAccount(config: SmartAccountConfig): Promise<Hex>;
|
|
343
|
+
/**
|
|
344
|
+
* Deploy using a minimal deployment transaction.
|
|
345
|
+
* For self-custodial setups, the deploy is a simple eth_call via the factory.
|
|
346
|
+
*/
|
|
347
|
+
getDeployCallData(config: SmartAccountConfig): Promise<{
|
|
348
|
+
to: Address;
|
|
349
|
+
data: Hex;
|
|
350
|
+
value: bigint;
|
|
351
|
+
}>;
|
|
352
|
+
/**
|
|
353
|
+
* Send a UserOperation to the bundler.
|
|
354
|
+
*
|
|
355
|
+
* @param config - Smart account config
|
|
356
|
+
* @param calls - Array of calls to execute
|
|
357
|
+
* @param options - Optional overrides (gas, paymaster)
|
|
358
|
+
* @returns UserOperation response
|
|
359
|
+
*/
|
|
360
|
+
sendUserOperation(config: SmartAccountConfig, calls: Call[], options?: SendUserOpOptions): Promise<UserOperationResponse>;
|
|
361
|
+
/**
|
|
362
|
+
* Get the nonce for a smart account from the EntryPoint.
|
|
363
|
+
*/
|
|
364
|
+
getNonce(entryPoint: Address, sender: Address): Promise<bigint>;
|
|
365
|
+
/**
|
|
366
|
+
* Estimate gas for a UserOperation via the bundler's eth_estimateUserOperationGas.
|
|
367
|
+
*/
|
|
368
|
+
estimateUserOperationGas(entryPoint: Address, partialUserOp: Partial<UserOperation>): Promise<UserOperationGasEstimate>;
|
|
369
|
+
/**
|
|
370
|
+
* Send a signed UserOperation to the bundler.
|
|
371
|
+
* Returns the userOpHash which can be used to track the operation.
|
|
372
|
+
*/
|
|
373
|
+
sendUserOpToBundler(userOp: UserOperation): Promise<Hex>;
|
|
374
|
+
/**
|
|
375
|
+
* Poll for a UserOperation receipt.
|
|
376
|
+
*/
|
|
377
|
+
getUserOperationReceipt(userOpHash: Hex, maxRetries?: number, intervalMs?: number): Promise<UserOperationReceipt | null>;
|
|
378
|
+
/**
|
|
379
|
+
* Send a batch of calls in a single UserOperation.
|
|
380
|
+
*
|
|
381
|
+
* @param config - Smart account config
|
|
382
|
+
* @param calls - Array of calls to batch
|
|
383
|
+
* @param options - Optional overrides
|
|
384
|
+
* @returns UserOperation response
|
|
385
|
+
*/
|
|
386
|
+
sendBatch(config: SmartAccountConfig, calls: Call[], options?: SendUserOpOptions): Promise<UserOperationResponse>;
|
|
387
|
+
/**
|
|
388
|
+
* Get the latest base fee per gas.
|
|
389
|
+
*/
|
|
390
|
+
getBaseFee(): Promise<bigint>;
|
|
391
|
+
/**
|
|
392
|
+
* Get the recommended priority fee.
|
|
393
|
+
*/
|
|
394
|
+
getPriorityFee(): Promise<bigint>;
|
|
395
|
+
private getEntryPoint;
|
|
396
|
+
private getFactory;
|
|
397
|
+
}
|
|
398
|
+
/**
|
|
399
|
+
* Encode account gas limits as a packed 32-byte value (v0.7).
|
|
400
|
+
* High 16 bytes = verificationGasLimit
|
|
401
|
+
* Low 16 bytes = callGasLimit
|
|
402
|
+
*/
|
|
403
|
+
declare function encodeGasLimits(verificationGasLimit: bigint, callGasLimit: bigint): Hex;
|
|
404
|
+
/**
|
|
405
|
+
* Decode account gas limits from packed 32-byte value (v0.7).
|
|
406
|
+
*/
|
|
407
|
+
declare function decodeGasLimits(accountGasLimits: Hex): {
|
|
408
|
+
verificationGasLimit: bigint;
|
|
409
|
+
callGasLimit: bigint;
|
|
410
|
+
};
|
|
411
|
+
|
|
412
|
+
/**
|
|
413
|
+
* UserOperation Builder & Signer
|
|
414
|
+
*
|
|
415
|
+
* Provides utilities for constructing, signing, and sending ERC-4337
|
|
416
|
+
* UserOperations without depending on @account-abstraction/sdk.
|
|
417
|
+
*
|
|
418
|
+
* @see docs/features/account-abstraction.md
|
|
419
|
+
*/
|
|
420
|
+
|
|
421
|
+
/**
|
|
422
|
+
* Build a partial UserOperation from the given fields.
|
|
423
|
+
*
|
|
424
|
+
* @param params - UserOperation fields
|
|
425
|
+
* @returns UserOperation with defaults applied for any missing fields
|
|
426
|
+
*/
|
|
427
|
+
declare function buildUserOperation(params: Partial<UserOperation>): UserOperation;
|
|
428
|
+
/**
|
|
429
|
+
* Build the callData for a UserOperation from one or more calls.
|
|
430
|
+
*
|
|
431
|
+
* For a single call, encodes as execute(to, value, data).
|
|
432
|
+
* For multiple calls, encodes as executeBatch(to[], value[], data[]).
|
|
433
|
+
*
|
|
434
|
+
* @param calls - Array of calls to include
|
|
435
|
+
* @returns Encoded calldata
|
|
436
|
+
*/
|
|
437
|
+
declare function buildCallData(calls: Call[]): Hex;
|
|
438
|
+
declare function hashUserOperation(userOp: UserOperation, entryPoint: Address, chainId: number): Hex;
|
|
439
|
+
/**
|
|
440
|
+
* Sign a UserOperation using EIP-191 or EIP-712.
|
|
441
|
+
*
|
|
442
|
+
* For SimpleAccount, the signature is a standard ECDSA signature.
|
|
443
|
+
*
|
|
444
|
+
* @param userOp - The UserOperation to sign (without signature)
|
|
445
|
+
* @param signer - A function that signs arbitrary data (e.g. personal_sign)
|
|
446
|
+
* @param entryPoint - EntryPoint contract address
|
|
447
|
+
* @param chainId - EVM chain ID
|
|
448
|
+
* @returns The UserOperation with signature field filled
|
|
449
|
+
*/
|
|
450
|
+
declare function signUserOperation(userOp: UserOperation, signer: (hash: Hex) => Promise<Hex> | Hex, entryPoint: Address, chainId: number): Promise<UserOperation>;
|
|
451
|
+
/**
|
|
452
|
+
* Send a UserOperation to a bundler RPC endpoint.
|
|
453
|
+
*
|
|
454
|
+
* @param userOp - The signed UserOperation
|
|
455
|
+
* @param bundlerUrl - Bundler RPC URL
|
|
456
|
+
* @param entryPoint - EntryPoint contract address
|
|
457
|
+
* @returns UserOperation response with userOpHash
|
|
458
|
+
*/
|
|
459
|
+
declare function sendUserOperation(userOp: UserOperation, bundlerUrl: string, entryPoint: Address): Promise<UserOperationResponse>;
|
|
460
|
+
/**
|
|
461
|
+
* Estimate gas for a UserOperation via the bundler's eth_estimateUserOperationGas.
|
|
462
|
+
*
|
|
463
|
+
* @param userOp - Partial UserOperation (signature not required)
|
|
464
|
+
* @param entryPoint - EntryPoint contract address
|
|
465
|
+
* @param bundlerUrl - Bundler RPC URL
|
|
466
|
+
* @returns Gas estimates (callGasLimit, verificationGasLimit, preVerificationGas)
|
|
467
|
+
*/
|
|
468
|
+
declare function estimateUserOperationGas(userOp: Partial<UserOperation>, entryPoint: Address, bundlerUrl: string): Promise<UserOperationGasEstimate>;
|
|
469
|
+
|
|
470
|
+
/**
|
|
471
|
+
* Address validation helpers.
|
|
472
|
+
*
|
|
473
|
+
* Minimal set — enough to prevent blackhole transfers.
|
|
474
|
+
*/
|
|
475
|
+
/** True for `0x0000…0000` (zero/burn address on all EVM chains) */
|
|
476
|
+
declare function isZeroAddress(address: string): boolean;
|
|
477
|
+
/** True if the address contains known burn-indicating hex prefixes */
|
|
478
|
+
declare function isBurnAddress(address: string): boolean;
|
|
479
|
+
/**
|
|
480
|
+
* Returns true if the string is a valid address for the given chain namespace.
|
|
481
|
+
* For EVM chains: 0x + 40 hex chars (checksum optional).
|
|
482
|
+
* Solana / XRPL: basic format check (length & prefix).
|
|
483
|
+
*/
|
|
484
|
+
declare function isValidAddress(address: string, chainNamespace?: string): boolean;
|
|
485
|
+
|
|
486
|
+
type Namespace = "eip155" | "solana" | string;
|
|
487
|
+
interface NamespaceCapabilities {
|
|
488
|
+
atomicBatch?: {
|
|
489
|
+
supported: boolean;
|
|
490
|
+
maxBatchSize?: number;
|
|
491
|
+
};
|
|
492
|
+
paymasterService?: {
|
|
493
|
+
supported: boolean;
|
|
494
|
+
};
|
|
495
|
+
permissions?: boolean;
|
|
496
|
+
serverSigning?: boolean;
|
|
497
|
+
[key: string]: unknown;
|
|
498
|
+
}
|
|
499
|
+
interface SessionNamespace {
|
|
500
|
+
chains: string[];
|
|
501
|
+
accounts: string[];
|
|
502
|
+
methods: string[];
|
|
503
|
+
events: string[];
|
|
504
|
+
capabilities?: NamespaceCapabilities;
|
|
505
|
+
}
|
|
506
|
+
interface UniversalWalletSession {
|
|
507
|
+
id: string;
|
|
508
|
+
topic?: string;
|
|
509
|
+
walletId: string;
|
|
510
|
+
walletType: "walletconnect" | "eip6963" | "xrpl" | string;
|
|
511
|
+
namespaces: Record<Namespace, SessionNamespace>;
|
|
512
|
+
platform: "desktop-web" | "mobile-web" | "in-app-browser";
|
|
513
|
+
auth?: {
|
|
514
|
+
method: "siwe" | "siws" | "none";
|
|
515
|
+
issuedAt?: string;
|
|
516
|
+
expiresAt?: string;
|
|
517
|
+
};
|
|
518
|
+
createdAt: string;
|
|
519
|
+
updatedAt: string;
|
|
520
|
+
/** Connector-specific identifier, set during session creation */
|
|
521
|
+
connectorId?: string;
|
|
522
|
+
/** Expiry datetime set by session-key manager */
|
|
523
|
+
expiry?: string | number;
|
|
524
|
+
}
|
|
525
|
+
interface SessionStorage {
|
|
526
|
+
load(): Promise<UniversalWalletSession | null>;
|
|
527
|
+
save(session: UniversalWalletSession): Promise<void>;
|
|
528
|
+
clear(): Promise<void>;
|
|
529
|
+
}
|
|
530
|
+
interface CreateEmptySessionInput {
|
|
531
|
+
id: string;
|
|
532
|
+
walletId: string;
|
|
533
|
+
walletType: UniversalWalletSession["walletType"];
|
|
534
|
+
namespaces: Record<Namespace, SessionNamespace>;
|
|
535
|
+
platform: UniversalWalletSession["platform"];
|
|
536
|
+
topic?: string;
|
|
537
|
+
auth?: UniversalWalletSession["auth"];
|
|
538
|
+
createdAt?: string;
|
|
539
|
+
updatedAt?: string;
|
|
540
|
+
}
|
|
541
|
+
declare function createEmptySession(input: CreateEmptySessionInput): UniversalWalletSession;
|
|
542
|
+
declare function updateSession(session: UniversalWalletSession, patch: Partial<UniversalWalletSession>): UniversalWalletSession;
|
|
543
|
+
declare function isSessionExpired(session: UniversalWalletSession, now: Date): boolean;
|
|
544
|
+
/**
|
|
545
|
+
* Session storage backed by localStorage via the unified StorageAdapter.
|
|
546
|
+
*
|
|
547
|
+
* Resolves the "dual storage system" tech debt: instead of directly
|
|
548
|
+
* calling localStorage.getItem/setItem, this delegates to
|
|
549
|
+
* LocalStorageAdapter which provides prefix support, availability
|
|
550
|
+
* detection, quota error handling, and typed parse-error reporting.
|
|
551
|
+
*/
|
|
552
|
+
declare class LocalStorageSessionStorage implements SessionStorage {
|
|
553
|
+
private readonly adapter;
|
|
554
|
+
private readonly innerKey;
|
|
555
|
+
/**
|
|
556
|
+
* @param key - localStorage key used to store the session blob.
|
|
557
|
+
* Defaults to "naculus_web3_session".
|
|
558
|
+
*/
|
|
559
|
+
constructor(key?: string);
|
|
560
|
+
/**
|
|
561
|
+
* Return whether localStorage is available in the current environment.
|
|
562
|
+
* Useful for consumers that want to check before calling load/save.
|
|
563
|
+
*/
|
|
564
|
+
isAvailable(): boolean;
|
|
565
|
+
load(): Promise<UniversalWalletSession | null>;
|
|
566
|
+
save(session: UniversalWalletSession): Promise<void>;
|
|
567
|
+
clear(): Promise<void>;
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
/**
|
|
571
|
+
* Auto-Reconnect Manager
|
|
572
|
+
*
|
|
573
|
+
* Handles automatic reconnection to previously connected wallets
|
|
574
|
+
* with configurable retry strategies.
|
|
575
|
+
*/
|
|
576
|
+
|
|
577
|
+
interface AutoReconnectConfig {
|
|
578
|
+
enabled: boolean;
|
|
579
|
+
maxRetries: number;
|
|
580
|
+
retryDelay: number;
|
|
581
|
+
onReconnecting?: () => void;
|
|
582
|
+
onReconnected?: () => void;
|
|
583
|
+
onFailed?: (error: Error) => void;
|
|
584
|
+
}
|
|
585
|
+
interface ReconnectState<T = UniversalWalletSession> {
|
|
586
|
+
lastSession: T | null;
|
|
587
|
+
retryCount: number;
|
|
588
|
+
isReconnecting: boolean;
|
|
589
|
+
}
|
|
590
|
+
declare class AutoReconnectManager<T = UniversalWalletSession> {
|
|
591
|
+
private config;
|
|
592
|
+
private state;
|
|
593
|
+
private retryTimeout;
|
|
594
|
+
constructor(config?: Partial<AutoReconnectConfig>);
|
|
595
|
+
setLastSession(session: T): void;
|
|
596
|
+
getState(): ReconnectState<T>;
|
|
597
|
+
needsReconnect(): boolean;
|
|
598
|
+
reconnect(reconnectFn: (session: T) => Promise<unknown>): Promise<boolean>;
|
|
599
|
+
private handleReconnectError;
|
|
600
|
+
cancel(): void;
|
|
601
|
+
clearSession(): void;
|
|
602
|
+
updateConfig(config: Partial<AutoReconnectConfig>): void;
|
|
603
|
+
reset(): void;
|
|
604
|
+
}
|
|
605
|
+
declare function createAutoReconnectManager<T = UniversalWalletSession>(config?: Partial<AutoReconnectConfig>): AutoReconnectManager<T>;
|
|
606
|
+
|
|
607
|
+
/**
|
|
608
|
+
* Chain Abstraction Types
|
|
609
|
+
*
|
|
610
|
+
* Core type definitions for cross-chain intent routing (Chain Abstraction).
|
|
611
|
+
* Defines Quote, RouteExecution, CostComparison, and supporting types
|
|
612
|
+
* for the Route Engine and Bridge Providers.
|
|
613
|
+
*
|
|
614
|
+
* @see docs/features/chain-abstraction.md
|
|
615
|
+
*/
|
|
616
|
+
/** Bridge provider identifier */
|
|
617
|
+
type BridgeProviderId = "lifi" | "axelar" | "socket" | "across";
|
|
618
|
+
/**
|
|
619
|
+
* Route step within a cross-chain route.
|
|
620
|
+
* Cross-chain routes typically decompose into:
|
|
621
|
+
* 1. Approve (optional) on source chain
|
|
622
|
+
* 2. Swap on source chain (optional)
|
|
623
|
+
* 3. Cross-chain bridge transfer
|
|
624
|
+
* 4. Swap on destination chain (optional)
|
|
625
|
+
*/
|
|
626
|
+
interface RouteStep {
|
|
627
|
+
type: "approve" | "swap" | "cross-chain";
|
|
628
|
+
chain: string;
|
|
629
|
+
token: string;
|
|
630
|
+
contractAddress: string;
|
|
631
|
+
data?: string;
|
|
632
|
+
/** EIP-1559 formatted gas estimate (bigint serialized as string) */
|
|
633
|
+
estimatedGas: string;
|
|
634
|
+
}
|
|
635
|
+
/** Gas cost estimate for a single chain in a cross-chain route */
|
|
636
|
+
interface GasEstimate {
|
|
637
|
+
/** Max fee per gas in wei (serialized bigint) */
|
|
638
|
+
maxFeePerGas: string;
|
|
639
|
+
/** Max priority fee in wei (serialized bigint) */
|
|
640
|
+
maxPriorityFeePerGas: string;
|
|
641
|
+
/** Estimated gas units */
|
|
642
|
+
gasLimit: string;
|
|
643
|
+
/** Total estimated gas cost in wei */
|
|
644
|
+
totalCostWei: string;
|
|
645
|
+
/** Total estimated gas cost in USD string */
|
|
646
|
+
totalCostUsd: string;
|
|
647
|
+
}
|
|
648
|
+
/**
|
|
649
|
+
* A discovered cross-chain route returned by a bridge provider.
|
|
650
|
+
*/
|
|
651
|
+
interface Route {
|
|
652
|
+
/** Unique route identifier */
|
|
653
|
+
id: string;
|
|
654
|
+
/** The bridge provider that discovered this route */
|
|
655
|
+
provider: BridgeProviderId;
|
|
656
|
+
/** Source chain CAIP-2 identifier */
|
|
657
|
+
fromChain: string;
|
|
658
|
+
/** Destination chain CAIP-2 identifier */
|
|
659
|
+
toChain: string;
|
|
660
|
+
/** Source token contract address (or native token symbol for ETH/MATIC/SOL) */
|
|
661
|
+
fromToken: string;
|
|
662
|
+
/** Destination token contract address */
|
|
663
|
+
toToken: string;
|
|
664
|
+
/** Input amount in raw form (smallest unit, e.g. wei) */
|
|
665
|
+
fromAmount: string;
|
|
666
|
+
/** Expected output amount in raw form */
|
|
667
|
+
toAmount: string;
|
|
668
|
+
/** Minimum guaranteed output amount (accounting for slippage) */
|
|
669
|
+
toAmountMin: string;
|
|
670
|
+
/** Gas cost breakdown for each chain involved */
|
|
671
|
+
gasCosts: {
|
|
672
|
+
fromChain: GasEstimate;
|
|
673
|
+
toChain: GasEstimate;
|
|
674
|
+
totalUsd: string;
|
|
675
|
+
};
|
|
676
|
+
/** Estimated time in seconds */
|
|
677
|
+
estimatedTime: number;
|
|
678
|
+
/** Decomposition of this route into individual steps */
|
|
679
|
+
steps: RouteStep[];
|
|
680
|
+
/** Fee breakdown */
|
|
681
|
+
fee: {
|
|
682
|
+
protocolFee: string;
|
|
683
|
+
integrationFee?: string;
|
|
684
|
+
};
|
|
685
|
+
/** Human-readable summary of the route */
|
|
686
|
+
summary: string;
|
|
687
|
+
}
|
|
688
|
+
/** Sorting options for quote aggregation */
|
|
689
|
+
type QuoteSortBy = "netReceive" | "fastest" | "cheapest";
|
|
690
|
+
interface QuoteOptions {
|
|
691
|
+
/** Slippage tolerance in percent (default 0.5) */
|
|
692
|
+
slippage?: number;
|
|
693
|
+
/** Preferred bridge providers */
|
|
694
|
+
preferredBridges?: BridgeProviderId[];
|
|
695
|
+
/** Bridge providers to exclude */
|
|
696
|
+
excludeBridges?: BridgeProviderId[];
|
|
697
|
+
/** Sort order for returned quotes */
|
|
698
|
+
sortBy?: QuoteSortBy;
|
|
699
|
+
}
|
|
700
|
+
/**
|
|
701
|
+
* A unified cross-chain quote ready for display and execution.
|
|
702
|
+
* Aggregates data from a Route with formatting and cost metadata.
|
|
703
|
+
*/
|
|
704
|
+
interface Quote {
|
|
705
|
+
/** Reference to the originating route ID */
|
|
706
|
+
routeId: string;
|
|
707
|
+
/** Bridge provider */
|
|
708
|
+
provider: BridgeProviderId;
|
|
709
|
+
/** Source chain CAIP-2 */
|
|
710
|
+
fromChain: string;
|
|
711
|
+
/** Destination chain CAIP-2 */
|
|
712
|
+
toChain: string;
|
|
713
|
+
/** Source token symbol (e.g. "USDC") */
|
|
714
|
+
fromTokenSymbol: string;
|
|
715
|
+
/** Destination token symbol */
|
|
716
|
+
toTokenSymbol: string;
|
|
717
|
+
/** Source amount, formatted for display (e.g. "100.00") */
|
|
718
|
+
fromAmountFormatted: string;
|
|
719
|
+
/** Destination amount, formatted for display */
|
|
720
|
+
toAmountFormatted: string;
|
|
721
|
+
/** Minimum guaranteed output, formatted */
|
|
722
|
+
toAmountMinFormatted: string;
|
|
723
|
+
/** Effective exchange rate (1 fromToken = ? toToken) */
|
|
724
|
+
exchangeRate: string;
|
|
725
|
+
/** Price impact percentage */
|
|
726
|
+
priceImpact: string;
|
|
727
|
+
/** Total gas cost in USD */
|
|
728
|
+
totalGasCostUsd: string;
|
|
729
|
+
/** Total protocol and integration fees in USD */
|
|
730
|
+
totalFeeUsd: string;
|
|
731
|
+
/** Net receive amount after gas + fees, formatted */
|
|
732
|
+
netReceiveFormatted: string;
|
|
733
|
+
/** Estimated arrival time as human-readable string */
|
|
734
|
+
estimatedArrival: string;
|
|
735
|
+
/** Estimated arrival in seconds */
|
|
736
|
+
estimatedArrivalSeconds: number;
|
|
737
|
+
/** Human-readable step summary */
|
|
738
|
+
summary: string;
|
|
739
|
+
/** Whether this quote requires an approve transaction before execution */
|
|
740
|
+
needsApprove: boolean;
|
|
741
|
+
/** Approve target address (token contract to approve) */
|
|
742
|
+
approveTarget?: string;
|
|
743
|
+
/** Approve spender address (bridge contract) */
|
|
744
|
+
approveSpender?: string;
|
|
745
|
+
/** Approve amount in raw form */
|
|
746
|
+
approveAmount?: string;
|
|
747
|
+
/** Timestamp when this quote expires (ms) */
|
|
748
|
+
expiresAt: number;
|
|
749
|
+
}
|
|
750
|
+
type RouteStatusValue = "pending" | "bridging" | "completed" | "failed";
|
|
751
|
+
interface RouteStatus {
|
|
752
|
+
status: RouteStatusValue;
|
|
753
|
+
fromTxHash?: string;
|
|
754
|
+
toTxHash?: string;
|
|
755
|
+
currentStep?: string;
|
|
756
|
+
/** Progress percentage 0-100 */
|
|
757
|
+
progress?: number;
|
|
758
|
+
/** Estimated completion timestamp (epoch ms) */
|
|
759
|
+
estimatedCompletionAt?: number;
|
|
760
|
+
/** Error message if status === "failed" */
|
|
761
|
+
error?: string;
|
|
762
|
+
}
|
|
763
|
+
interface ExecuteOptions {
|
|
764
|
+
/** Recipient address on the destination chain */
|
|
765
|
+
recipient?: string;
|
|
766
|
+
/** Whether to automatically handle approve transactions */
|
|
767
|
+
autoApprove?: boolean;
|
|
768
|
+
/** Custom approve amount in raw form (overrides default) */
|
|
769
|
+
approveAmount?: string;
|
|
770
|
+
}
|
|
771
|
+
interface ExecuteRouteResult {
|
|
772
|
+
/** Source chain transaction hash */
|
|
773
|
+
fromTxHash: string;
|
|
774
|
+
/** Source chain CAIP-2 */
|
|
775
|
+
fromChain: string;
|
|
776
|
+
/** Destination chain transaction hash (populated once bridging completes) */
|
|
777
|
+
toTxHash?: string;
|
|
778
|
+
/** Destination chain CAIP-2 */
|
|
779
|
+
toChain: string;
|
|
780
|
+
/** Current execution status */
|
|
781
|
+
status: RouteStatusValue;
|
|
782
|
+
/** Bridge provider reference ID (for status polling) */
|
|
783
|
+
bridgeReference?: string;
|
|
784
|
+
/** Estimated completion timestamp (epoch ms) */
|
|
785
|
+
estimatedCompletionAt?: number;
|
|
786
|
+
/** Error message if status === "failed" */
|
|
787
|
+
error?: string;
|
|
788
|
+
}
|
|
789
|
+
type CostComparisonOperation = "send_native" | "send_erc20" | "swap" | "cross_chain_transfer";
|
|
790
|
+
interface CostComparisonOptions {
|
|
791
|
+
/** Token contract address relevant to the operation */
|
|
792
|
+
token?: string;
|
|
793
|
+
/** Amount in raw form */
|
|
794
|
+
amount?: string;
|
|
795
|
+
/** Include cross-chain fees in comparison */
|
|
796
|
+
includeCrossChain?: boolean;
|
|
797
|
+
}
|
|
798
|
+
interface CostComparison {
|
|
799
|
+
/** Chain CAIP-2 identifier */
|
|
800
|
+
chain: string;
|
|
801
|
+
/** Human-readable chain name */
|
|
802
|
+
chainName: string;
|
|
803
|
+
/** Gas cost in USD */
|
|
804
|
+
gasCost: string;
|
|
805
|
+
/** Protocol/bridge fees in USD */
|
|
806
|
+
fee: string;
|
|
807
|
+
/** Total cost (gas + fees) in USD */
|
|
808
|
+
totalCost: string;
|
|
809
|
+
/** Estimated time in seconds */
|
|
810
|
+
time: number;
|
|
811
|
+
/** Congestion level (optional) */
|
|
812
|
+
congestionLevel?: "low" | "medium" | "high";
|
|
813
|
+
}
|
|
814
|
+
interface ChainAbstractionConfig {
|
|
815
|
+
/** Senderpay backend URL (for proxy-based route discovery) */
|
|
816
|
+
backendUrl?: string;
|
|
817
|
+
/** Quote cache TTL in ms (default 30000) */
|
|
818
|
+
quoteCacheTtl?: number;
|
|
819
|
+
/** Status polling interval in ms (default 2000) */
|
|
820
|
+
statusPollInterval?: number;
|
|
821
|
+
/** Default slippage in percent (default 0.5) */
|
|
822
|
+
defaultSlippage?: number;
|
|
823
|
+
/** LiFi SDK API key (optional, for direct SDK usage) */
|
|
824
|
+
lifiApiKey?: string;
|
|
825
|
+
/** Axelar API key / config (optional, for direct SDK usage) */
|
|
826
|
+
axelarConfig?: {
|
|
827
|
+
apiUrl?: string;
|
|
828
|
+
};
|
|
829
|
+
}
|
|
830
|
+
/**
|
|
831
|
+
* Abstract interface for a cross-chain bridge provider.
|
|
832
|
+
* Each provider (LiFi, Axelar, Socket, Across) implements this
|
|
833
|
+
* to be registered with the RouteEngine.
|
|
834
|
+
*/
|
|
835
|
+
interface BridgeProvider {
|
|
836
|
+
/** Unique provider identifier */
|
|
837
|
+
readonly id: BridgeProviderId;
|
|
838
|
+
/** Human-readable provider name */
|
|
839
|
+
readonly name: string;
|
|
840
|
+
/**
|
|
841
|
+
* Discover available routes for a cross-chain transfer.
|
|
842
|
+
*
|
|
843
|
+
* @param fromChain - Source chain CAIP-2
|
|
844
|
+
* @param toChain - Destination chain CAIP-2
|
|
845
|
+
* @param fromToken - Source token address/symbol
|
|
846
|
+
* @param toToken - Destination token address/symbol
|
|
847
|
+
* @param amount - Amount in raw form (smallest unit)
|
|
848
|
+
* @returns Array of discovered routes (empty if no routes found)
|
|
849
|
+
*/
|
|
850
|
+
getRoutes(fromChain: string, toChain: string, fromToken: string, toToken: string, amount: string): Promise<Route[]>;
|
|
851
|
+
/**
|
|
852
|
+
* Build transaction parameters to execute a given route.
|
|
853
|
+
*
|
|
854
|
+
* @param route - The selected route to execute
|
|
855
|
+
* @param sender - Sender address
|
|
856
|
+
* @param recipient - Recipient address on destination chain
|
|
857
|
+
* @returns Transaction parameters for the execution
|
|
858
|
+
*/
|
|
859
|
+
getTransactionParams(route: Route, sender: string, recipient: string): Promise<ProviderTransaction[]>;
|
|
860
|
+
/**
|
|
861
|
+
* Query the current execution status of a cross-chain transfer.
|
|
862
|
+
*
|
|
863
|
+
* @param bridgeReference - Reference ID from the provider
|
|
864
|
+
* @returns Current route status
|
|
865
|
+
*/
|
|
866
|
+
getRouteStatus(bridgeReference: string): Promise<RouteStatus>;
|
|
867
|
+
/**
|
|
868
|
+
* Check whether this provider supports a given chain pair.
|
|
869
|
+
*
|
|
870
|
+
* @param fromChain - Source chain CAIP-2
|
|
871
|
+
* @param toChain - Destination chain CAIP-2
|
|
872
|
+
* @returns true if the chain pair is supported
|
|
873
|
+
*/
|
|
874
|
+
supportsChainPair(fromChain: string, toChain: string): boolean;
|
|
875
|
+
/**
|
|
876
|
+
* Check whether this provider supports a given token on a chain.
|
|
877
|
+
*
|
|
878
|
+
* @param chain - Chain CAIP-2
|
|
879
|
+
* @param token - Token contract address or symbol
|
|
880
|
+
* @returns true if the token is supported
|
|
881
|
+
*/
|
|
882
|
+
supportsToken(chain: string, token: string): boolean;
|
|
883
|
+
}
|
|
884
|
+
interface ProviderTransaction {
|
|
885
|
+
type: "approve" | "cross-chain";
|
|
886
|
+
chainId: string;
|
|
887
|
+
to: string;
|
|
888
|
+
data: string;
|
|
889
|
+
value: string;
|
|
890
|
+
}
|
|
891
|
+
type ChainAbstractionErrorCode = "chain_pair_not_supported" | "token_not_supported" | "route_expired" | "insufficient_balance" | "approve_needed" | "approve_rejected" | "transaction_failed" | "backend_unavailable" | "invalid_config" | "no_routes_available" | "provider_unavailable" | "execution_failed";
|
|
892
|
+
declare class ChainAbstractionError extends Error {
|
|
893
|
+
code: ChainAbstractionErrorCode;
|
|
894
|
+
details?: Record<string, unknown>;
|
|
895
|
+
constructor(code: ChainAbstractionErrorCode, message?: string, details?: Record<string, unknown>);
|
|
896
|
+
}
|
|
897
|
+
declare function isChainAbstractionError(e: unknown, code?: ChainAbstractionErrorCode): e is ChainAbstractionError;
|
|
898
|
+
|
|
899
|
+
/**
|
|
900
|
+
* AxelarProvider — Axelar GMP integration for cross-chain transfers.
|
|
901
|
+
*
|
|
902
|
+
* Integrates with the Axelar network for General Message Passing (GMP),
|
|
903
|
+
* enabling cross-chain token transfers and arbitrary contract calls.
|
|
904
|
+
*
|
|
905
|
+
* When configured with a backend URL, proxies through senderpay backend.
|
|
906
|
+
* Otherwise attempts direct Axelar API interaction.
|
|
907
|
+
*
|
|
908
|
+
* @see https://docs.axelar.dev/dev/general-message-passing
|
|
909
|
+
*/
|
|
910
|
+
|
|
911
|
+
interface AxelarProviderConfig {
|
|
912
|
+
/** Axelar API base URL */
|
|
913
|
+
apiUrl?: string;
|
|
914
|
+
/** Backend proxy URL (alternative to direct API) */
|
|
915
|
+
backendUrl?: string;
|
|
916
|
+
}
|
|
917
|
+
declare class AxelarProvider implements BridgeProvider {
|
|
918
|
+
readonly id: BridgeProviderId;
|
|
919
|
+
readonly name = "Axelar";
|
|
920
|
+
private config;
|
|
921
|
+
constructor(config?: AxelarProviderConfig);
|
|
922
|
+
getRoutes(fromChain: string, toChain: string, fromToken: string, toToken: string, amount: string): Promise<Route[]>;
|
|
923
|
+
private getRoutesViaBackend;
|
|
924
|
+
private getRoutesViaDirectAPI;
|
|
925
|
+
getTransactionParams(_route: Route, _sender: string, _recipient: string): Promise<ProviderTransaction[]>;
|
|
926
|
+
getRouteStatus(bridgeReference: string): Promise<RouteStatus>;
|
|
927
|
+
supportsChainPair(fromChain: string, toChain: string): boolean;
|
|
928
|
+
supportsToken(chain: string, token: string): boolean;
|
|
929
|
+
private getAxelarGateway;
|
|
930
|
+
private buildGMPData;
|
|
931
|
+
private mapAxelarStatus;
|
|
932
|
+
}
|
|
933
|
+
|
|
934
|
+
/**
|
|
935
|
+
* LiFiProvider — LI.FI SDK integration for cross-chain swaps.
|
|
936
|
+
*
|
|
937
|
+
* Integrates with the LI.FI API to discover routes and build
|
|
938
|
+
* transaction data for hop-based cross-chain transfers.
|
|
939
|
+
*
|
|
940
|
+
* When a LI.FI API key is configured, queries the LI.FI API directly.
|
|
941
|
+
* Otherwise falls back to a senderpay backend proxy if configured.
|
|
942
|
+
*
|
|
943
|
+
* @see https://apidocs.li.fi/reference
|
|
944
|
+
*/
|
|
945
|
+
|
|
946
|
+
interface LiFiProviderConfig {
|
|
947
|
+
/** LI.FI API key (optional) */
|
|
948
|
+
apiKey?: string;
|
|
949
|
+
/** LI.FI API base URL */
|
|
950
|
+
apiUrl?: string;
|
|
951
|
+
/** Backend proxy URL (alternative to direct API) */
|
|
952
|
+
backendUrl?: string;
|
|
953
|
+
}
|
|
954
|
+
declare class LiFiProvider implements BridgeProvider {
|
|
955
|
+
readonly id: BridgeProviderId;
|
|
956
|
+
readonly name = "LI.FI";
|
|
957
|
+
private config;
|
|
958
|
+
constructor(config?: LiFiProviderConfig);
|
|
959
|
+
getRoutes(fromChain: string, toChain: string, fromToken: string, toToken: string, amount: string): Promise<Route[]>;
|
|
960
|
+
private getRoutesViaBackend;
|
|
961
|
+
private getRoutesViaDirectAPI;
|
|
962
|
+
getTransactionParams(route: Route, sender: string, recipient: string): Promise<ProviderTransaction[]>;
|
|
963
|
+
getRouteStatus(bridgeReference: string): Promise<RouteStatus>;
|
|
964
|
+
supportsChainPair(fromChain: string, toChain: string): boolean;
|
|
965
|
+
supportsToken(chain: string, token: string): boolean;
|
|
966
|
+
private mapLiFiStatus;
|
|
967
|
+
}
|
|
968
|
+
|
|
969
|
+
/**
|
|
970
|
+
* Chain Route Engine
|
|
971
|
+
*
|
|
972
|
+
* Core engine for cross-chain intent routing. Discovers routes across
|
|
973
|
+
* multiple bridge providers, aggregates quotes, and handles execution.
|
|
974
|
+
*
|
|
975
|
+
* Supports a pluggable provider registration mechanism so new bridges
|
|
976
|
+
* (Socket, Across, etc.) can be added without modifying this engine.
|
|
977
|
+
*
|
|
978
|
+
* @see docs/features/chain-abstraction.md §3
|
|
979
|
+
*/
|
|
980
|
+
|
|
981
|
+
declare class RouteEngine {
|
|
982
|
+
private providers;
|
|
983
|
+
private config;
|
|
984
|
+
/** Simple in-memory quote cache (route-level, before formatting) */
|
|
985
|
+
private quoteCache;
|
|
986
|
+
/** Route store: maps routeId → Route for execution lookup */
|
|
987
|
+
private routeStore;
|
|
988
|
+
constructor(config?: ChainAbstractionConfig);
|
|
989
|
+
/**
|
|
990
|
+
* Register a bridge provider with the route engine.
|
|
991
|
+
* Providers can be added at any time; they are discovered
|
|
992
|
+
* on each getQuote() call.
|
|
993
|
+
*/
|
|
994
|
+
registerProvider(provider: BridgeProvider): void;
|
|
995
|
+
/**
|
|
996
|
+
* Unregister a previously registered provider.
|
|
997
|
+
*/
|
|
998
|
+
unregisterProvider(providerId: BridgeProviderId): void;
|
|
999
|
+
/**
|
|
1000
|
+
* Get a registered provider by ID.
|
|
1001
|
+
*/
|
|
1002
|
+
getProvider(providerId: BridgeProviderId): BridgeProvider | undefined;
|
|
1003
|
+
/**
|
|
1004
|
+
* List all registered providers.
|
|
1005
|
+
*/
|
|
1006
|
+
listProviders(): BridgeProvider[];
|
|
1007
|
+
/**
|
|
1008
|
+
* Get cross-chain quotes for a given transfer.
|
|
1009
|
+
*
|
|
1010
|
+
* Discovers routes from all registered providers that support the
|
|
1011
|
+
* requested chain pair and token, then formats them into unified
|
|
1012
|
+
* Quote objects sorted by the specified strategy.
|
|
1013
|
+
*
|
|
1014
|
+
* @param fromChain - Source chain CAIP-2 (e.g. "eip155:1" for Ethereum)
|
|
1015
|
+
* @param toChain - Destination chain CAIP-2
|
|
1016
|
+
* @param token - Token to transfer (symbol or contract address)
|
|
1017
|
+
* @param amount - Amount in raw form (smallest unit)
|
|
1018
|
+
* @param options - Optional quote options (slippage, sort, provider filters)
|
|
1019
|
+
* @returns Sorted array of Quote objects
|
|
1020
|
+
*
|
|
1021
|
+
* @throws {ChainAbstractionError} if no routes are found or providers
|
|
1022
|
+
* are unavailable
|
|
1023
|
+
*/
|
|
1024
|
+
getQuote(fromChain: string, toChain: string, token: string, amount: string, options?: QuoteOptions): Promise<Quote[]>;
|
|
1025
|
+
/**
|
|
1026
|
+
* Execute a cross-chain route from a selected quote.
|
|
1027
|
+
*
|
|
1028
|
+
* Returns transaction hashes and a bridge reference for status tracking.
|
|
1029
|
+
* Actual transaction sending is handled by the caller (e.g., ConnectorManager).
|
|
1030
|
+
*
|
|
1031
|
+
* @param quote - The selected Quote to execute
|
|
1032
|
+
* @param recipient - Recipient address on the destination chain
|
|
1033
|
+
* @param options - Execution options (autoApprove, recipient)
|
|
1034
|
+
* @returns ExecuteRouteResult with transaction tracking info
|
|
1035
|
+
*
|
|
1036
|
+
* @throws {ChainAbstractionError} if the route is expired, provider
|
|
1037
|
+
* is unavailable, or execution fails
|
|
1038
|
+
*/
|
|
1039
|
+
executeRoute(quote: Quote, recipient: string, options?: ExecuteOptions): Promise<ExecuteRouteResult>;
|
|
1040
|
+
/**
|
|
1041
|
+
* Compare costs of performing an operation across multiple chains.
|
|
1042
|
+
*
|
|
1043
|
+
* Useful for helping users decide which chain is cheapest for
|
|
1044
|
+
* a given operation (send, swap, cross-chain transfer).
|
|
1045
|
+
*
|
|
1046
|
+
* @param operation - The operation type to compare
|
|
1047
|
+
* @param chains - Array of CAIP-2 chain IDs to compare
|
|
1048
|
+
* @param options - Optional comparison parameters
|
|
1049
|
+
* @returns Array of CostComparison sorted by total cost ascending
|
|
1050
|
+
*/
|
|
1051
|
+
compareCosts(operation: CostComparisonOperation, chains: string[], options?: CostComparisonOptions): Promise<CostComparison[]>;
|
|
1052
|
+
/**
|
|
1053
|
+
* Poll the current status of a cross-chain route execution.
|
|
1054
|
+
*
|
|
1055
|
+
* @param bridgeReference - The reference ID returned from executeRoute
|
|
1056
|
+
* @returns Current RouteStatus
|
|
1057
|
+
*/
|
|
1058
|
+
getRouteStatus(bridgeReference: string): Promise<RouteStatus>;
|
|
1059
|
+
/**
|
|
1060
|
+
* Get the subset of providers that support the given chain pair and token.
|
|
1061
|
+
* Filters by preferred/excluded bridges if configured.
|
|
1062
|
+
*/
|
|
1063
|
+
private getActiveProviders;
|
|
1064
|
+
/**
|
|
1065
|
+
* Format raw routes into display-ready Quote objects and sort them.
|
|
1066
|
+
*/
|
|
1067
|
+
private formatAndSortQuotes;
|
|
1068
|
+
/**
|
|
1069
|
+
* Sort quotes by the specified strategy.
|
|
1070
|
+
*/
|
|
1071
|
+
private sortQuotes;
|
|
1072
|
+
/**
|
|
1073
|
+
* Resolve a token symbol from a chain and token address.
|
|
1074
|
+
*/
|
|
1075
|
+
private resolveTokenSymbol;
|
|
1076
|
+
/**
|
|
1077
|
+
* Format the total fee (protocol + integration) as a USD string.
|
|
1078
|
+
*/
|
|
1079
|
+
private formatFeeUsd;
|
|
1080
|
+
/**
|
|
1081
|
+
* Format estimated time as human-readable string.
|
|
1082
|
+
*/
|
|
1083
|
+
private formatEstimatedTime;
|
|
1084
|
+
/**
|
|
1085
|
+
* Build a cache key from quote parameters.
|
|
1086
|
+
*/
|
|
1087
|
+
private buildCacheKey;
|
|
1088
|
+
/**
|
|
1089
|
+
* Get cached routes by route ID.
|
|
1090
|
+
*/
|
|
1091
|
+
/**
|
|
1092
|
+
* Clean stale cache entries.
|
|
1093
|
+
*/
|
|
1094
|
+
private cleanCache;
|
|
1095
|
+
/**
|
|
1096
|
+
* Evaluate the cost of an operation on a single chain.
|
|
1097
|
+
*/
|
|
1098
|
+
private evaluateChainCost;
|
|
1099
|
+
/**
|
|
1100
|
+
* Get estimated gas units for a given operation type.
|
|
1101
|
+
*/
|
|
1102
|
+
private getEstimatedGasUnits;
|
|
1103
|
+
/**
|
|
1104
|
+
* Get estimated time in seconds for an operation on a chain.
|
|
1105
|
+
*/
|
|
1106
|
+
private getEstimatedTime;
|
|
1107
|
+
/**
|
|
1108
|
+
* Get a human-readable chain name.
|
|
1109
|
+
*/
|
|
1110
|
+
private getChainName;
|
|
1111
|
+
/**
|
|
1112
|
+
* Get native token price in USD (simplified).
|
|
1113
|
+
*/
|
|
1114
|
+
private getNativeTokenPriceUsd;
|
|
1115
|
+
/**
|
|
1116
|
+
* Get congestion level for a chain.
|
|
1117
|
+
*/
|
|
1118
|
+
private getCongestionLevel;
|
|
1119
|
+
}
|
|
1120
|
+
declare function createRouteEngine(config?: ChainAbstractionConfig): RouteEngine;
|
|
1121
|
+
|
|
1122
|
+
/**
|
|
1123
|
+
* Chain Registry
|
|
1124
|
+
*
|
|
1125
|
+
* Single source of truth for chain names, token addresses, and provider IDs.
|
|
1126
|
+
* Do NOT create new mapping tables elsewhere — use `CHAINS` and `getChainInfo()`.
|
|
1127
|
+
*/
|
|
1128
|
+
interface ChainInfo$1 {
|
|
1129
|
+
name: string;
|
|
1130
|
+
caip2Id: string;
|
|
1131
|
+
nativeCurrency: {
|
|
1132
|
+
symbol: string;
|
|
1133
|
+
decimals: number;
|
|
1134
|
+
};
|
|
1135
|
+
axelarName?: string;
|
|
1136
|
+
usdcAddress?: string;
|
|
1137
|
+
usdcDecimals?: number;
|
|
1138
|
+
usdtAddress?: string;
|
|
1139
|
+
usdtDecimals?: number;
|
|
1140
|
+
entryPoint?: string;
|
|
1141
|
+
factoryAddress?: string;
|
|
1142
|
+
explorerUrl?: string;
|
|
1143
|
+
chainlinkEthUsdFeed?: string;
|
|
1144
|
+
}
|
|
1145
|
+
declare const CHAINS: Record<number, ChainInfo$1>;
|
|
1146
|
+
|
|
1147
|
+
interface ConnectorSupport {
|
|
1148
|
+
desktop: boolean;
|
|
1149
|
+
mobile: boolean;
|
|
1150
|
+
deepLink: boolean;
|
|
1151
|
+
qr: boolean;
|
|
1152
|
+
trustedReconnect: boolean;
|
|
1153
|
+
}
|
|
1154
|
+
interface BatchCall {
|
|
1155
|
+
to: `0x${string}`;
|
|
1156
|
+
value?: string;
|
|
1157
|
+
data?: `0x${string}`;
|
|
1158
|
+
}
|
|
1159
|
+
interface WalletCapabilities {
|
|
1160
|
+
atomicBatch: {
|
|
1161
|
+
supported: boolean;
|
|
1162
|
+
maxBatchSize?: number;
|
|
1163
|
+
};
|
|
1164
|
+
paymasterService?: {
|
|
1165
|
+
supported: boolean;
|
|
1166
|
+
};
|
|
1167
|
+
[key: string]: unknown;
|
|
1168
|
+
}
|
|
1169
|
+
/** EIP-5792: getCallsStatus response */
|
|
1170
|
+
interface CallsStatus {
|
|
1171
|
+
status: "PENDING" | "CONFIRMED";
|
|
1172
|
+
receipts?: Array<{
|
|
1173
|
+
logs: Array<{
|
|
1174
|
+
address: string;
|
|
1175
|
+
data: string;
|
|
1176
|
+
topics: string[];
|
|
1177
|
+
}>;
|
|
1178
|
+
status: "0x1" | "0x0";
|
|
1179
|
+
blockHash: string;
|
|
1180
|
+
blockNumber: string;
|
|
1181
|
+
gasUsed: string;
|
|
1182
|
+
transactionHash: string;
|
|
1183
|
+
}>;
|
|
1184
|
+
}
|
|
1185
|
+
interface UniversalConnector {
|
|
1186
|
+
id: string;
|
|
1187
|
+
name: string;
|
|
1188
|
+
kind: string;
|
|
1189
|
+
namespaces: string[];
|
|
1190
|
+
supports: ConnectorSupport;
|
|
1191
|
+
connect(input?: unknown): Promise<UniversalWalletSession>;
|
|
1192
|
+
reconnect?(session: UniversalWalletSession): Promise<UniversalWalletSession>;
|
|
1193
|
+
disconnect(session: UniversalWalletSession): Promise<void>;
|
|
1194
|
+
getAccounts(session: UniversalWalletSession): Promise<string[]>;
|
|
1195
|
+
signMessage?(session: UniversalWalletSession, input: unknown): Promise<unknown>;
|
|
1196
|
+
signTransaction?(session: UniversalWalletSession, input: unknown): Promise<unknown>;
|
|
1197
|
+
sendTransaction?(session: UniversalWalletSession, input: unknown): Promise<unknown>;
|
|
1198
|
+
switchChain?(session: UniversalWalletSession, chainId: string): Promise<void>;
|
|
1199
|
+
deepLink?(target: string): Promise<void>;
|
|
1200
|
+
sendCalls?(session: UniversalWalletSession, calls: BatchCall[], chainId?: string): Promise<string>;
|
|
1201
|
+
getCapabilities?(session: UniversalWalletSession): Promise<Record<string, WalletCapabilities>>;
|
|
1202
|
+
getCallsStatus?(session: UniversalWalletSession, bundleHash: string): Promise<CallsStatus>;
|
|
1203
|
+
request?(request: {
|
|
1204
|
+
method: string;
|
|
1205
|
+
params: unknown[];
|
|
1206
|
+
}): Promise<unknown>;
|
|
1207
|
+
getBalance?(chainId?: string): Promise<string>;
|
|
1208
|
+
}
|
|
1209
|
+
declare function extractAccounts(namespaces: Record<Namespace, SessionNamespace>): string[];
|
|
1210
|
+
declare function getChainsFromNamespaces(namespaces: Record<Namespace, SessionNamespace>): string[];
|
|
1211
|
+
declare function getMethodsFromNamespaces(namespaces: Record<Namespace, SessionNamespace>): string[];
|
|
1212
|
+
declare function getEventsFromNamespaces(namespaces: Record<Namespace, SessionNamespace>): string[];
|
|
1213
|
+
|
|
1214
|
+
/**
|
|
1215
|
+
* Connector Manager
|
|
1216
|
+
*
|
|
1217
|
+
* Manages multiple wallet connectors and provides a unified interface
|
|
1218
|
+
* for connecting, disconnecting, and managing wallet connections.
|
|
1219
|
+
*/
|
|
1220
|
+
|
|
1221
|
+
type ConnectorId = string;
|
|
1222
|
+
interface ConnectorEntry {
|
|
1223
|
+
id: ConnectorId;
|
|
1224
|
+
connector: UniversalConnector;
|
|
1225
|
+
priority: number;
|
|
1226
|
+
}
|
|
1227
|
+
interface ConnectorManagerConfig {
|
|
1228
|
+
autoSelect?: boolean;
|
|
1229
|
+
preferOrder?: ConnectorId[];
|
|
1230
|
+
}
|
|
1231
|
+
declare class ConnectorManager {
|
|
1232
|
+
private connectors;
|
|
1233
|
+
private entries;
|
|
1234
|
+
private activeConnectorId;
|
|
1235
|
+
private activeSession;
|
|
1236
|
+
private config;
|
|
1237
|
+
/** Prevent concurrent connect() calls from overwriting sessions */
|
|
1238
|
+
private _connecting;
|
|
1239
|
+
constructor(config?: ConnectorManagerConfig);
|
|
1240
|
+
register(id: ConnectorId, connector: UniversalConnector, priority?: number): void;
|
|
1241
|
+
unregister(id: ConnectorId): void;
|
|
1242
|
+
get(id: ConnectorId): UniversalConnector | undefined;
|
|
1243
|
+
getActive(): UniversalConnector | undefined;
|
|
1244
|
+
getActiveSession(): UniversalWalletSession | null;
|
|
1245
|
+
list(): ConnectorEntry[];
|
|
1246
|
+
listBySupport(support: keyof ConnectorSupport): UniversalConnector[];
|
|
1247
|
+
connect(id?: ConnectorId, input?: unknown): Promise<UniversalWalletSession>;
|
|
1248
|
+
reconnect(session: UniversalWalletSession): Promise<UniversalWalletSession>;
|
|
1249
|
+
disconnect(): Promise<void>;
|
|
1250
|
+
getAccounts(): Promise<string[]>;
|
|
1251
|
+
signMessage(input: {
|
|
1252
|
+
message: string;
|
|
1253
|
+
account?: string;
|
|
1254
|
+
}): Promise<unknown>;
|
|
1255
|
+
sendTransaction(input: unknown): Promise<unknown>;
|
|
1256
|
+
switchChain(chainId: string): Promise<void>;
|
|
1257
|
+
request(request: {
|
|
1258
|
+
method: string;
|
|
1259
|
+
params: unknown[];
|
|
1260
|
+
}): Promise<unknown>;
|
|
1261
|
+
getBalance(chainId?: string): Promise<string>;
|
|
1262
|
+
sendCalls(session: UniversalWalletSession, calls: BatchCall[], chainId?: string): Promise<string>;
|
|
1263
|
+
getCapabilities(session: UniversalWalletSession): Promise<Record<string, WalletCapabilities>>;
|
|
1264
|
+
clear(): void;
|
|
1265
|
+
private selectBestConnector;
|
|
1266
|
+
}
|
|
1267
|
+
declare function createConnectorManager(config?: ConnectorManagerConfig): ConnectorManager;
|
|
1268
|
+
|
|
1269
|
+
/**
|
|
1270
|
+
* CAIP-2 Chain Namespace Identifiers
|
|
1271
|
+
*
|
|
1272
|
+
* References:
|
|
1273
|
+
* - CAIP-2: https://namespaces.chainagnostic.org/CAIP-2
|
|
1274
|
+
*/
|
|
1275
|
+
declare const NAMESPACE_EIP155: "eip155";
|
|
1276
|
+
declare const NAMESPACE_SOLANA: "solana";
|
|
1277
|
+
declare const NAMESPACE_XRPL: "xrpl";
|
|
1278
|
+
declare const SUPPORTED_NAMESPACES: readonly ["eip155", "solana", "xrpl"];
|
|
1279
|
+
/**
|
|
1280
|
+
* Common EVM Chain IDs (CAIP-2 format)
|
|
1281
|
+
*/
|
|
1282
|
+
declare const EIP155_MAINNET = "eip155:1";
|
|
1283
|
+
declare const EIP155_GOERLI = "eip155:5";
|
|
1284
|
+
declare const EIP155_SEPOLIA = "eip155:11155111";
|
|
1285
|
+
declare const EIP155_POLYGON = "eip155:137";
|
|
1286
|
+
declare const EIP155_MUMBAI = "eip155:80001";
|
|
1287
|
+
declare const EIP155_ARBITRUM = "eip155:42161";
|
|
1288
|
+
declare const EIP155_ARBITRUM_GOERLI = "eip155:421613";
|
|
1289
|
+
declare const EIP155_OPTIMISM = "eip155:10";
|
|
1290
|
+
declare const EIP155_OPTIMISM_GOERLI = "eip155:420";
|
|
1291
|
+
declare const EIP155_BASE = "eip155:8453";
|
|
1292
|
+
/**
|
|
1293
|
+
* Common Solana Cluster IDs (CAIP-2 format)
|
|
1294
|
+
*/
|
|
1295
|
+
declare const SOLANA_MAINNET = "solana:0";
|
|
1296
|
+
declare const SOLANA_DEVNET = "solana:1";
|
|
1297
|
+
declare const SOLANA_TESTNET = "solana:2";
|
|
1298
|
+
/**
|
|
1299
|
+
* Common XRPL Network IDs (CAIP-2 format)
|
|
1300
|
+
*/
|
|
1301
|
+
declare const XRPL_MAINNET = "xrpl:0";
|
|
1302
|
+
declare const XRPL_TESTNET = "xrpl:1";
|
|
1303
|
+
declare const XRPL_DEVNET = "xrpl:2";
|
|
1304
|
+
/**
|
|
1305
|
+
* Default EVM chain (Ethereum Mainnet)
|
|
1306
|
+
*/
|
|
1307
|
+
declare const DEFAULT_EVM_CHAIN = "eip155:1";
|
|
1308
|
+
/**
|
|
1309
|
+
* Default Solana cluster (Mainnet)
|
|
1310
|
+
*/
|
|
1311
|
+
declare const DEFAULT_SOLANA_CLUSTER = "solana:0";
|
|
1312
|
+
/**
|
|
1313
|
+
* Default XRPL network (Mainnet)
|
|
1314
|
+
*/
|
|
1315
|
+
declare const DEFAULT_XRPL_NETWORK = "xrpl:0";
|
|
1316
|
+
/**
|
|
1317
|
+
* WalletConnect v2 Disconnect Reason Codes
|
|
1318
|
+
*
|
|
1319
|
+
* Reference: WalletConnect v2 Protocol Specification
|
|
1320
|
+
*/
|
|
1321
|
+
declare const WC_DISCONNECT_USER = 6000;
|
|
1322
|
+
declare const WC_DISCONNECT_TIMEOUT = 6001;
|
|
1323
|
+
declare const WC_DISCONNECT_SESSION_EXPIRED = 6002;
|
|
1324
|
+
/**
|
|
1325
|
+
* Storage keys used across connectors
|
|
1326
|
+
*/
|
|
1327
|
+
declare const STORAGE_KEYS: {
|
|
1328
|
+
readonly SESSION: "naculus_web3_session";
|
|
1329
|
+
readonly POCKET: "naculus_pocket";
|
|
1330
|
+
readonly PASSKEYS_CREDENTIAL: "naculus_passkeys_credential";
|
|
1331
|
+
};
|
|
1332
|
+
/**
|
|
1333
|
+
* Nonce configuration
|
|
1334
|
+
*/
|
|
1335
|
+
declare const DEFAULT_NONCE_LENGTH = 16;
|
|
1336
|
+
/**
|
|
1337
|
+
* Session timeout values (in milliseconds)
|
|
1338
|
+
*/
|
|
1339
|
+
declare const SESSION_TIMEOUT_MS: number;
|
|
1340
|
+
declare const AUTO_RECONNECT_TIMEOUT_MS: number;
|
|
1341
|
+
|
|
1342
|
+
declare const CONNECTOR_ERROR_MESSAGES: {
|
|
1343
|
+
readonly SESSION_EXPIRED: "Session expired. Please reconnect your wallet.";
|
|
1344
|
+
readonly NO_ACCOUNT_SIGNING: "No account found for signing. Please reconnect your wallet.";
|
|
1345
|
+
readonly NO_ACCOUNT_TX: "No account found for transaction. Please reconnect your wallet.";
|
|
1346
|
+
readonly NO_ACCOUNTS: "No accounts available. Please reconnect your wallet.";
|
|
1347
|
+
readonly INVALID_INPUT: "Invalid input.";
|
|
1348
|
+
readonly MISSING_TX: "Missing transaction.";
|
|
1349
|
+
readonly MISSING_MESSAGE: "Missing message parameter.";
|
|
1350
|
+
readonly USER_REJECTED: "Operation rejected by user.";
|
|
1351
|
+
readonly TX_FAILED: "Transaction failed.";
|
|
1352
|
+
readonly CHAIN_UNSUPPORTED: "Chain not supported.";
|
|
1353
|
+
readonly METHOD_NOT_ALLOWED: "Method not allowed.";
|
|
1354
|
+
readonly WALLET_UNAVAILABLE: "Wallet not available.";
|
|
1355
|
+
};
|
|
1356
|
+
type WalletErrorCode = "wallet_unavailable" | "user_rejected" | "deeplink_timeout" | "session_expired" | "intent_expired" | "namespace_mismatch" | "chain_unsupported" | "method_not_allowed" | "method_unsupported" | "signature_rejected" | "tx_failed" | "invalid_proposal" | "invalid_input" | "siwx_error" | "no_active_session" | "chain_switch_rejected" | "invalid_chain" | "no_solana_session" | "unsupported_chain" | "fee_rpc_error";
|
|
1357
|
+
declare class WalletError extends Error {
|
|
1358
|
+
code: WalletErrorCode;
|
|
1359
|
+
details?: unknown;
|
|
1360
|
+
constructor(code: WalletErrorCode, message?: string, details?: unknown);
|
|
1361
|
+
}
|
|
1362
|
+
declare function isWalletError(e: unknown, code?: WalletErrorCode): e is WalletError;
|
|
1363
|
+
|
|
1364
|
+
/**
|
|
1365
|
+
* BigInt ↔ String Conversion Utilities
|
|
1366
|
+
*
|
|
1367
|
+
* Provides safe conversion between bigint and string representations
|
|
1368
|
+
* for fee values, integrating with wallet-engine and UI layers.
|
|
1369
|
+
*
|
|
1370
|
+
* @see SRS-001 §6.3
|
|
1371
|
+
*/
|
|
1372
|
+
/**
|
|
1373
|
+
* Convert a bigint fee value to its decimal string representation.
|
|
1374
|
+
*
|
|
1375
|
+
* @param value - Fee value in wei as bigint
|
|
1376
|
+
* @returns Decimal string (e.g., "15000000000" for 15 gwei)
|
|
1377
|
+
*
|
|
1378
|
+
* @example
|
|
1379
|
+
* ```ts
|
|
1380
|
+
* toDecString(15000000000n) // "15000000000"
|
|
1381
|
+
* toDecString(0n) // "0"
|
|
1382
|
+
* ```
|
|
1383
|
+
*/
|
|
1384
|
+
declare function toDecString(value: bigint): string;
|
|
1385
|
+
/**
|
|
1386
|
+
* Parse a decimal string into a bigint.
|
|
1387
|
+
*
|
|
1388
|
+
* @param value - Decimal string (e.g., "15000000000")
|
|
1389
|
+
* @returns bigint representation
|
|
1390
|
+
*
|
|
1391
|
+
* @example
|
|
1392
|
+
* ```ts
|
|
1393
|
+
* parseBigInt("15000000000") // 15000000000n
|
|
1394
|
+
* parseBigInt("0") // 0n
|
|
1395
|
+
* ```
|
|
1396
|
+
*/
|
|
1397
|
+
declare function parseBigInt(value: string): bigint;
|
|
1398
|
+
/**
|
|
1399
|
+
* Convert a bigint to a human-readable string with a label (e.g., "25 gwei").
|
|
1400
|
+
*
|
|
1401
|
+
* @param wei - Value in wei as bigint
|
|
1402
|
+
* @param decimals - Number of decimals for the display unit (default: 9 for gwei)
|
|
1403
|
+
* @param unit - Unit label (default: "gwei")
|
|
1404
|
+
* @returns Human-readable string
|
|
1405
|
+
*
|
|
1406
|
+
* @example
|
|
1407
|
+
* ```ts
|
|
1408
|
+
* toHumanReadable(25000000000n) // "25 gwei"
|
|
1409
|
+
* toHumanReadable(15000000000n, 9, "gwei") // "15 gwei"
|
|
1410
|
+
* toHumanReadable(1000000000000000000n, 18, "ETH") // "1 ETH"
|
|
1411
|
+
* ```
|
|
1412
|
+
*/
|
|
1413
|
+
declare function toHumanReadable(wei: bigint, decimals?: number, unit?: string): string;
|
|
1414
|
+
|
|
1415
|
+
/**
|
|
1416
|
+
* Fee Estimation Error
|
|
1417
|
+
*
|
|
1418
|
+
* Thrown when all fee estimation strategies have failed.
|
|
1419
|
+
*/
|
|
1420
|
+
type FeeEstimationErrorCode = "fee_estimation_failed" | "fee_chain_not_supported" | "fee_rpc_error";
|
|
1421
|
+
declare class FeeEstimationError extends Error {
|
|
1422
|
+
code: FeeEstimationErrorCode;
|
|
1423
|
+
details?: unknown;
|
|
1424
|
+
constructor(code: FeeEstimationErrorCode, message?: string, details?: unknown);
|
|
1425
|
+
}
|
|
1426
|
+
declare function isFeeEstimationError(e: unknown, code?: FeeEstimationErrorCode): e is FeeEstimationError;
|
|
1427
|
+
/** Error message constants */
|
|
1428
|
+
declare const FEE_ERROR_MESSAGES: {
|
|
1429
|
+
readonly ESTIMATION_FAILED: "Fee estimation failed after all strategies exhausted.";
|
|
1430
|
+
readonly CHAIN_NOT_SUPPORTED: "Chain not supported for fee estimation.";
|
|
1431
|
+
readonly RPC_ERROR: "RPC call failed during fee estimation.";
|
|
1432
|
+
};
|
|
1433
|
+
|
|
1434
|
+
/**
|
|
1435
|
+
* EIP-1559 Fee Estimation Types
|
|
1436
|
+
*
|
|
1437
|
+
* Defines the type hierarchy for gas fee estimation following the
|
|
1438
|
+
* viem-style union return type pattern.
|
|
1439
|
+
*
|
|
1440
|
+
* @see SRS-001 §5.1
|
|
1441
|
+
*/
|
|
1442
|
+
/** EIP-1559 (type 2) fee values */
|
|
1443
|
+
interface FeeValuesEIP1559 {
|
|
1444
|
+
type: "eip1559";
|
|
1445
|
+
maxFeePerGas: bigint;
|
|
1446
|
+
maxPriorityFeePerGas: bigint;
|
|
1447
|
+
}
|
|
1448
|
+
/** Legacy (type 0) fee values */
|
|
1449
|
+
interface FeeValuesLegacy {
|
|
1450
|
+
type: "legacy";
|
|
1451
|
+
gasPrice: bigint;
|
|
1452
|
+
}
|
|
1453
|
+
/** Union type for fee estimation return values */
|
|
1454
|
+
type FeeValues = FeeValuesEIP1559 | FeeValuesLegacy;
|
|
1455
|
+
/** Force a specific fee type strategy */
|
|
1456
|
+
type FeeTypeStrategy = "auto" | "eip1559" | "legacy";
|
|
1457
|
+
/** Configuration for the fee estimation */
|
|
1458
|
+
interface FeeEstimationConfig {
|
|
1459
|
+
/** Chain ID in CAIP-2 format (e.g., "eip155:1" for Ethereum mainnet) */
|
|
1460
|
+
chainId?: string;
|
|
1461
|
+
/** Force a specific transaction type strategy */
|
|
1462
|
+
type?: FeeTypeStrategy;
|
|
1463
|
+
/** Override maxPriorityFeePerGas (only used for eip1559) */
|
|
1464
|
+
maxPriorityFeePerGas?: bigint;
|
|
1465
|
+
/** Multiplier applied to base fee for maxFeePerGas (default: 2n) */
|
|
1466
|
+
baseFeeMultiplier?: bigint;
|
|
1467
|
+
/** RPC endpoint URL */
|
|
1468
|
+
rpcUrl: string;
|
|
1469
|
+
}
|
|
1470
|
+
/** Result of checking a chain's EIP-1559 support */
|
|
1471
|
+
interface ChainFeeSupport {
|
|
1472
|
+
/** Whether the chain supports EIP-1559 */
|
|
1473
|
+
eip1559: boolean;
|
|
1474
|
+
/** Latest block's base fee per gas (available when eip1559 is true) */
|
|
1475
|
+
latestBaseFee?: bigint;
|
|
1476
|
+
/** Recommended priority fee (available when eip1559 is true) */
|
|
1477
|
+
recommendedPriorityFee?: bigint;
|
|
1478
|
+
}
|
|
1479
|
+
/** Chain-specific fee estimator override for L2s with custom fee models */
|
|
1480
|
+
interface ChainFeeEstimator {
|
|
1481
|
+
/** CAIP-2 chain identifier (e.g., "eip155:10" for Optimism) */
|
|
1482
|
+
chainId: string;
|
|
1483
|
+
/**
|
|
1484
|
+
* Estimate fees for the chain.
|
|
1485
|
+
* Called before the built-in heuristic logic.
|
|
1486
|
+
*/
|
|
1487
|
+
estimateFees(rpcUrl: string, config?: Partial<FeeEstimationConfig>): Promise<FeeValues>;
|
|
1488
|
+
}
|
|
1489
|
+
|
|
1490
|
+
/**
|
|
1491
|
+
* EIP-1559 Fee Estimation Module
|
|
1492
|
+
*
|
|
1493
|
+
* Provides fee estimation for EVM chains with automatic support detection,
|
|
1494
|
+
* fallback to legacy gas price, and chain-specific estimator registration.
|
|
1495
|
+
*
|
|
1496
|
+
* @see SRS-001 §6.1
|
|
1497
|
+
*/
|
|
1498
|
+
|
|
1499
|
+
/**
|
|
1500
|
+
* Register a chain-specific fee estimator.
|
|
1501
|
+
* Registered estimators take priority over the built-in heuristic logic.
|
|
1502
|
+
*/
|
|
1503
|
+
declare function registerChainFeeEstimator(estimator: ChainFeeEstimator): void;
|
|
1504
|
+
/**
|
|
1505
|
+
* Remove a previously registered chain-specific estimator.
|
|
1506
|
+
*/
|
|
1507
|
+
declare function unregisterChainFeeEstimator(chainId: string): void;
|
|
1508
|
+
/**
|
|
1509
|
+
* Clear all registered chain-specific estimators.
|
|
1510
|
+
*/
|
|
1511
|
+
declare function clearChainFeeEstimators(): void;
|
|
1512
|
+
/**
|
|
1513
|
+
* Fetch the suggested max priority fee via eth_maxPriorityFeePerGas.
|
|
1514
|
+
*
|
|
1515
|
+
* @param rpcUrl - RPC endpoint
|
|
1516
|
+
* @returns The suggested priority fee (in wei), or throws if the method is not supported
|
|
1517
|
+
*/
|
|
1518
|
+
declare function estimateMaxPriorityFeePerGas(rpcUrl: string): Promise<bigint>;
|
|
1519
|
+
/**
|
|
1520
|
+
* Fetch the base fee per gas from the latest block.
|
|
1521
|
+
*
|
|
1522
|
+
* @param rpcUrl - RPC endpoint
|
|
1523
|
+
* @returns Base fee per gas in wei, or null if not available (pre-London fork)
|
|
1524
|
+
*/
|
|
1525
|
+
declare function getLatestBaseFee(rpcUrl: string): Promise<bigint | null>;
|
|
1526
|
+
/**
|
|
1527
|
+
* Fetch legacy gas price via eth_gasPrice.
|
|
1528
|
+
*
|
|
1529
|
+
* @param rpcUrl - RPC endpoint
|
|
1530
|
+
* @returns Current gas price in wei
|
|
1531
|
+
*/
|
|
1532
|
+
declare function getGasPrice(rpcUrl: string): Promise<bigint>;
|
|
1533
|
+
/**
|
|
1534
|
+
* Fetch chain ID via eth_chainId.
|
|
1535
|
+
*
|
|
1536
|
+
* @param rpcUrl - RPC endpoint
|
|
1537
|
+
* @returns Chain ID as a bigint (supports values beyond Number.MAX_SAFE_INTEGER)
|
|
1538
|
+
*/
|
|
1539
|
+
declare function getChainId(rpcUrl: string): Promise<bigint>;
|
|
1540
|
+
/**
|
|
1541
|
+
* Query the chain's EIP-1559 support status and recent base fee.
|
|
1542
|
+
*
|
|
1543
|
+
* Strategy:
|
|
1544
|
+
* 1. Fetch the latest block to check for baseFeePerGas
|
|
1545
|
+
* 2. If present, the chain supports EIP-1559
|
|
1546
|
+
* 3. If absent, the chain uses legacy gas model
|
|
1547
|
+
*
|
|
1548
|
+
* @param rpcUrl - RPC endpoint
|
|
1549
|
+
* @returns ChainFeeSupport with EIP-1559 support status and data
|
|
1550
|
+
*/
|
|
1551
|
+
declare function getFeeData(rpcUrl: string): Promise<ChainFeeSupport>;
|
|
1552
|
+
/**
|
|
1553
|
+
* Estimate fees for a transaction on the given chain.
|
|
1554
|
+
*
|
|
1555
|
+
* The function follows this fallback strategy:
|
|
1556
|
+
* 1. If a chain-specific estimator is registered, use it
|
|
1557
|
+
* 2. Try EIP-1559 flow (eth_maxPriorityFeePerGas + base fee)
|
|
1558
|
+
* 3. Fall back to legacy gas price
|
|
1559
|
+
* 4. All strategies fail → throw FeeEstimationError
|
|
1560
|
+
*
|
|
1561
|
+
* @param config - Fee estimation configuration
|
|
1562
|
+
* @returns FeeValues (eip1559 | legacy)
|
|
1563
|
+
*
|
|
1564
|
+
* @example
|
|
1565
|
+
* ```ts
|
|
1566
|
+
* const fees = await estimateFees({
|
|
1567
|
+
* rpcUrl: "https://eth.llamarpc.com",
|
|
1568
|
+
* chainId: "eip155:1",
|
|
1569
|
+
* });
|
|
1570
|
+
* // => { type: "eip1559", maxFeePerGas: 15000000000n, maxPriorityFeePerGas: 1000000000n }
|
|
1571
|
+
* ```
|
|
1572
|
+
*/
|
|
1573
|
+
declare function estimateFees(config: FeeEstimationConfig): Promise<FeeValues>;
|
|
1574
|
+
|
|
1575
|
+
/**
|
|
1576
|
+
* Configurable Logger
|
|
1577
|
+
*
|
|
1578
|
+
* Replaces raw `console.*` calls across the SDK with a logger that can
|
|
1579
|
+
* be silenced, namespaced, or have custom sinks injected.
|
|
1580
|
+
*
|
|
1581
|
+
* Usage:
|
|
1582
|
+
* import { logger } from "@naculus/connect-core";
|
|
1583
|
+
* logger.warn("core/session", "Failed to save", err);
|
|
1584
|
+
*
|
|
1585
|
+
* At app level:
|
|
1586
|
+
* import { setLogLevel, setLogSink } from "@naculus/connect-core";
|
|
1587
|
+
* setLogLevel("error"); // suppress debug/info/warn
|
|
1588
|
+
* setLogSink((level, ns, args) => myLogger(level, ns, args));
|
|
1589
|
+
*/
|
|
1590
|
+
type LogLevel = "debug" | "info" | "warn" | "error" | "silent";
|
|
1591
|
+
/** Set the minimum log level. Messages below this threshold are suppressed. */
|
|
1592
|
+
declare function setLogLevel(level: LogLevel): void;
|
|
1593
|
+
/** Replace the default console-based sink with a custom handler. */
|
|
1594
|
+
declare function setLogSink(sink: ((level: LogLevel, ns: string, ...args: unknown[]) => void) | null): void;
|
|
1595
|
+
/** Namespace-bound convenience wrapper returned by `logger.for(ns)`. */
|
|
1596
|
+
interface LoggerNamespace {
|
|
1597
|
+
debug(...args: unknown[]): void;
|
|
1598
|
+
info(...args: unknown[]): void;
|
|
1599
|
+
warn(...args: unknown[]): void;
|
|
1600
|
+
error(...args: unknown[]): void;
|
|
1601
|
+
}
|
|
1602
|
+
declare function createNamespace(ns: string): LoggerNamespace;
|
|
1603
|
+
/**
|
|
1604
|
+
* Global logger object.
|
|
1605
|
+
* logger.warn("my-ns", "message", err);
|
|
1606
|
+
* const l = logger.for("my-ns"); l.warn("message", err);
|
|
1607
|
+
*/
|
|
1608
|
+
declare const logger: {
|
|
1609
|
+
debug: (ns: string, ...args: unknown[]) => void;
|
|
1610
|
+
info: (ns: string, ...args: unknown[]) => void;
|
|
1611
|
+
warn: (ns: string, ...args: unknown[]) => void;
|
|
1612
|
+
error: (ns: string, ...args: unknown[]) => void;
|
|
1613
|
+
for: typeof createNamespace;
|
|
1614
|
+
setLogLevel: typeof setLogLevel;
|
|
1615
|
+
setLogSink: typeof setLogSink;
|
|
1616
|
+
/** Current effective level (for tests / introspection). */
|
|
1617
|
+
getLogLevel: () => LogLevel;
|
|
1618
|
+
};
|
|
1619
|
+
|
|
1620
|
+
/**
|
|
1621
|
+
* Notification type definitions for Push Notification system.
|
|
1622
|
+
*
|
|
1623
|
+
* @see docs/features/push-notification.md
|
|
1624
|
+
*/
|
|
1625
|
+
/**
|
|
1626
|
+
* Transaction lifecycle status.
|
|
1627
|
+
* Mirrors TxMonitor (SRS-008) status values.
|
|
1628
|
+
*/
|
|
1629
|
+
type TxStatus = "pending" | "confirmed" | "failed" | "reorg" | "speedup" | "cancel";
|
|
1630
|
+
/**
|
|
1631
|
+
* How often to fire notifications for a transaction.
|
|
1632
|
+
*
|
|
1633
|
+
* - `per-tx`: every status change is notified
|
|
1634
|
+
* - `per-confirm`: every N confirmations
|
|
1635
|
+
* - `final-only`: only confirmed or failed (default)
|
|
1636
|
+
* - `muted`: never notify for this tx
|
|
1637
|
+
*/
|
|
1638
|
+
type NotificationFrequency = "per-tx" | "per-confirm" | "final-only" | "muted";
|
|
1639
|
+
/**
|
|
1640
|
+
* The payload delivered to every channel when a notification fires.
|
|
1641
|
+
*/
|
|
1642
|
+
interface NotificationPayload {
|
|
1643
|
+
/** Unique notification id (uuid) */
|
|
1644
|
+
id: string;
|
|
1645
|
+
/** Target user identifier */
|
|
1646
|
+
userId: string;
|
|
1647
|
+
/** Related transaction hash */
|
|
1648
|
+
txHash: string;
|
|
1649
|
+
/** Chain ID (CAIP-2, e.g. "eip155:1") */
|
|
1650
|
+
chainId: string;
|
|
1651
|
+
/** Human-readable chain name (e.g. "Ethereum Mainnet") */
|
|
1652
|
+
chainName: string;
|
|
1653
|
+
/** Current transaction status */
|
|
1654
|
+
status: TxStatus;
|
|
1655
|
+
/** Short notification title */
|
|
1656
|
+
title: string;
|
|
1657
|
+
/** Notification body text */
|
|
1658
|
+
body: string;
|
|
1659
|
+
/** Transaction value as raw bigint */
|
|
1660
|
+
value?: bigint;
|
|
1661
|
+
/** Formatted value string (e.g. "100 USDC") */
|
|
1662
|
+
valueFormatted?: string;
|
|
1663
|
+
/** USD-equivalent value */
|
|
1664
|
+
valueUsd?: number;
|
|
1665
|
+
/** Actual gas used */
|
|
1666
|
+
gasUsed?: bigint;
|
|
1667
|
+
/** Gas cost in USD */
|
|
1668
|
+
gasCostUsd?: number;
|
|
1669
|
+
/** Block explorer link */
|
|
1670
|
+
explorerUrl?: string;
|
|
1671
|
+
/** Final confirmation count */
|
|
1672
|
+
confirmations?: number;
|
|
1673
|
+
/** Notification creation timestamp (unix ms) */
|
|
1674
|
+
timestamp: number;
|
|
1675
|
+
/** Recipient type (for SenderPay) */
|
|
1676
|
+
recipientType?: "sender" | "merchant";
|
|
1677
|
+
}
|
|
1678
|
+
/**
|
|
1679
|
+
* Registration for a single transaction's notification lifecycle.
|
|
1680
|
+
* Remains active until the tx reaches a terminal state (confirmed/failed).
|
|
1681
|
+
*/
|
|
1682
|
+
interface NotificationWatch {
|
|
1683
|
+
/** Transaction hash being watched */
|
|
1684
|
+
txHash: string;
|
|
1685
|
+
/** Target user */
|
|
1686
|
+
userId: string;
|
|
1687
|
+
/** Channel ids that should receive this notification */
|
|
1688
|
+
channels: string[];
|
|
1689
|
+
/** Notification frequency for this watch */
|
|
1690
|
+
frequency: NotificationFrequency;
|
|
1691
|
+
/** Per-confirm interval (only meaningful when frequency is "per-confirm") */
|
|
1692
|
+
confirmInterval?: number;
|
|
1693
|
+
/** Transaction metadata for filtering / mute evaluation */
|
|
1694
|
+
txMetadata: TxMetadata;
|
|
1695
|
+
/** When this watch was created (unix ms) */
|
|
1696
|
+
createdAt: number;
|
|
1697
|
+
/** When the transaction resolved (unix ms, set when terminal status reached) */
|
|
1698
|
+
resolvedAt?: number;
|
|
1699
|
+
}
|
|
1700
|
+
interface TxMetadata {
|
|
1701
|
+
chainId: string;
|
|
1702
|
+
value?: bigint;
|
|
1703
|
+
to?: string;
|
|
1704
|
+
/** Detected tx type (transfer, swap, approve, custom) */
|
|
1705
|
+
txType: "transfer" | "swap" | "approve" | "custom";
|
|
1706
|
+
}
|
|
1707
|
+
interface ChannelCapability {
|
|
1708
|
+
supportsRichText: boolean;
|
|
1709
|
+
supportsActionButtons: boolean;
|
|
1710
|
+
supportsMedia: boolean;
|
|
1711
|
+
maxLength: number;
|
|
1712
|
+
isBackground: boolean;
|
|
1713
|
+
}
|
|
1714
|
+
interface NotificationChannel {
|
|
1715
|
+
readonly id: string;
|
|
1716
|
+
readonly name: string;
|
|
1717
|
+
send(payload: NotificationPayload): Promise<void>;
|
|
1718
|
+
isAvailable(): boolean;
|
|
1719
|
+
getCapabilities(): ChannelCapability;
|
|
1720
|
+
healthCheck(): Promise<boolean>;
|
|
1721
|
+
}
|
|
1722
|
+
interface UserNotificationPreferences {
|
|
1723
|
+
/** Active channel ids */
|
|
1724
|
+
channels: string[];
|
|
1725
|
+
/** Default notification frequency */
|
|
1726
|
+
frequency: NotificationFrequency;
|
|
1727
|
+
/** Per-confirm interval (default 6) */
|
|
1728
|
+
confirmInterval?: number;
|
|
1729
|
+
/** Pending alert timeout in seconds (default 300 = 5 min) */
|
|
1730
|
+
pendingTimeout?: number;
|
|
1731
|
+
/** Quiet hours configuration */
|
|
1732
|
+
quietHours?: {
|
|
1733
|
+
start: string;
|
|
1734
|
+
end: string;
|
|
1735
|
+
timezone: string;
|
|
1736
|
+
};
|
|
1737
|
+
}
|
|
1738
|
+
interface MuteRule {
|
|
1739
|
+
id: string;
|
|
1740
|
+
/** Mute all transactions on this chain */
|
|
1741
|
+
chainId?: string;
|
|
1742
|
+
/** Mute specific tx type */
|
|
1743
|
+
txType?: "transfer" | "swap" | "approve" | "custom";
|
|
1744
|
+
/** Suppress notifications below this USD value */
|
|
1745
|
+
minValueUsd?: number;
|
|
1746
|
+
/** Mute a specific contract address */
|
|
1747
|
+
contractAddress?: string;
|
|
1748
|
+
/** Optional expiry timestamp (unix ms). Omit = permanent */
|
|
1749
|
+
until?: number;
|
|
1750
|
+
/** When this rule was created (unix ms) */
|
|
1751
|
+
createdAt: number;
|
|
1752
|
+
}
|
|
1753
|
+
/**
|
|
1754
|
+
* A notification item displayed in the in-app notification center (React).
|
|
1755
|
+
*/
|
|
1756
|
+
interface NotificationItem {
|
|
1757
|
+
id: string;
|
|
1758
|
+
title: string;
|
|
1759
|
+
body: string;
|
|
1760
|
+
status: TxStatus;
|
|
1761
|
+
txHash: string;
|
|
1762
|
+
chainName: string;
|
|
1763
|
+
valueFormatted?: string;
|
|
1764
|
+
explorerUrl?: string;
|
|
1765
|
+
timestamp: number;
|
|
1766
|
+
read: boolean;
|
|
1767
|
+
}
|
|
1768
|
+
interface NotificationSettings {
|
|
1769
|
+
telegram: boolean;
|
|
1770
|
+
webpush: boolean;
|
|
1771
|
+
inapp: boolean;
|
|
1772
|
+
frequency: NotificationFrequency;
|
|
1773
|
+
mutedChains: string[];
|
|
1774
|
+
mutedTypes: string[];
|
|
1775
|
+
}
|
|
1776
|
+
interface NotifierOptions {
|
|
1777
|
+
/** Default user notification preferences (applied when a userId has no explicit prefs) */
|
|
1778
|
+
defaultPreferences?: Partial<UserNotificationPreferences>;
|
|
1779
|
+
/** Storage adapter for persisting notification history and prefs */
|
|
1780
|
+
storage?: {
|
|
1781
|
+
getItem: <T>(key: string) => Promise<T | null>;
|
|
1782
|
+
setItem: <T>(key: string, value: T) => Promise<void>;
|
|
1783
|
+
removeItem: (key: string) => Promise<void>;
|
|
1784
|
+
};
|
|
1785
|
+
/** Maximum number of in-app history entries to retain (default 200) */
|
|
1786
|
+
maxHistory?: number;
|
|
1787
|
+
}
|
|
1788
|
+
type TxStatusCallback = (status: TxStatus, payload?: Partial<NotificationPayload>) => void;
|
|
1789
|
+
|
|
1790
|
+
/**
|
|
1791
|
+
* Notification Channel Adapters.
|
|
1792
|
+
*
|
|
1793
|
+
* Provides the `NotificationChannel` interface plus built-in adapters:
|
|
1794
|
+
* - `InAppChannel` — in-memory / localStorage-backed notification list
|
|
1795
|
+
* - `TelegramChannel` — adapter stub (actual bot token provided externally)
|
|
1796
|
+
*
|
|
1797
|
+
* @see docs/features/push-notification.md §4.4
|
|
1798
|
+
*/
|
|
1799
|
+
|
|
1800
|
+
interface InAppChannelOptions {
|
|
1801
|
+
/** Maximum number of history entries kept in storage (default 200) */
|
|
1802
|
+
maxHistory?: number;
|
|
1803
|
+
/** Optional storage for persisting notification history */
|
|
1804
|
+
storage?: {
|
|
1805
|
+
getItem: <T>(key: string) => Promise<T | null>;
|
|
1806
|
+
setItem: <T>(key: string, value: T) => Promise<void>;
|
|
1807
|
+
removeItem: (key: string) => Promise<void>;
|
|
1808
|
+
};
|
|
1809
|
+
/** Callback fired when a new notification arrives (used by React hook) */
|
|
1810
|
+
onNotification?: (item: NotificationItem) => void;
|
|
1811
|
+
}
|
|
1812
|
+
/**
|
|
1813
|
+
* In-app notification channel.
|
|
1814
|
+
*
|
|
1815
|
+
* Stores notifications in a history buffer and fires a callback for each
|
|
1816
|
+
* new notification so React hooks can stay in sync.
|
|
1817
|
+
*/
|
|
1818
|
+
declare class InAppChannel implements NotificationChannel {
|
|
1819
|
+
readonly id = "inapp";
|
|
1820
|
+
readonly name = "In-App Toast";
|
|
1821
|
+
private history;
|
|
1822
|
+
private maxHistory;
|
|
1823
|
+
private storage?;
|
|
1824
|
+
onNotification?: (item: NotificationItem) => void;
|
|
1825
|
+
constructor(options?: InAppChannelOptions);
|
|
1826
|
+
getCapabilities(): ChannelCapability;
|
|
1827
|
+
isAvailable(): boolean;
|
|
1828
|
+
healthCheck(): Promise<boolean>;
|
|
1829
|
+
send(payload: NotificationPayload): Promise<void>;
|
|
1830
|
+
/** Returns all in-app notifications (newest last). */
|
|
1831
|
+
getHistory(): NotificationItem[];
|
|
1832
|
+
/** Mark a single notification as read. */
|
|
1833
|
+
markAsRead(id: string): void;
|
|
1834
|
+
/** Mark all notifications as read. */
|
|
1835
|
+
markAllAsRead(): void;
|
|
1836
|
+
/** Clear all in-app notifications. */
|
|
1837
|
+
clear(): void;
|
|
1838
|
+
/** Number of unread notifications. */
|
|
1839
|
+
get unreadCount(): number;
|
|
1840
|
+
private persist;
|
|
1841
|
+
/** Restore persisted history (call on initialization). */
|
|
1842
|
+
restore(): Promise<void>;
|
|
1843
|
+
}
|
|
1844
|
+
/**
|
|
1845
|
+
* Telegram notification channel.
|
|
1846
|
+
*
|
|
1847
|
+
* This is an adapter stub. The actual bot token is provided at runtime via
|
|
1848
|
+
* the constructor. The `send` method formats the payload into a Telegram
|
|
1849
|
+
* message and sends it through the Telegram Bot API.
|
|
1850
|
+
*
|
|
1851
|
+
* @remarks
|
|
1852
|
+
* Token is accepted but the HTTP call to Telegram's API is left to the
|
|
1853
|
+
* integrator's Telegram infrastructure (e.g., OpenClaw delivery channel).
|
|
1854
|
+
* The `send` implementation here is a placeholder that logs the formatted
|
|
1855
|
+
* message — the real transport should be injected or overridden.
|
|
1856
|
+
*/
|
|
1857
|
+
declare class TelegramChannel implements NotificationChannel {
|
|
1858
|
+
readonly id = "telegram";
|
|
1859
|
+
readonly name = "Telegram";
|
|
1860
|
+
private botToken;
|
|
1861
|
+
private chatId;
|
|
1862
|
+
private transport?;
|
|
1863
|
+
constructor(config: {
|
|
1864
|
+
botToken: string;
|
|
1865
|
+
chatId: string;
|
|
1866
|
+
/** Optional transport override. Defaults to console.log. */
|
|
1867
|
+
transport?: (payload: NotificationPayload, formatted: string) => Promise<void>;
|
|
1868
|
+
});
|
|
1869
|
+
getCapabilities(): ChannelCapability;
|
|
1870
|
+
isAvailable(): boolean;
|
|
1871
|
+
healthCheck(): Promise<boolean>;
|
|
1872
|
+
send(payload: NotificationPayload): Promise<void>;
|
|
1873
|
+
private formatMessage;
|
|
1874
|
+
private shortenHash;
|
|
1875
|
+
private statusEmoji;
|
|
1876
|
+
}
|
|
1877
|
+
/**
|
|
1878
|
+
* No-op channel for testing or disabling notifications entirely.
|
|
1879
|
+
*/
|
|
1880
|
+
declare class NoopChannel implements NotificationChannel {
|
|
1881
|
+
readonly id = "noop";
|
|
1882
|
+
readonly name = "No-op";
|
|
1883
|
+
getCapabilities(): ChannelCapability;
|
|
1884
|
+
isAvailable(): boolean;
|
|
1885
|
+
healthCheck(): Promise<boolean>;
|
|
1886
|
+
send(_payload: NotificationPayload): Promise<void>;
|
|
1887
|
+
}
|
|
1888
|
+
|
|
1889
|
+
/**
|
|
1890
|
+
* Notifier — Push Notification Core.
|
|
1891
|
+
*
|
|
1892
|
+
* Central orchestrator for transaction lifecycle push notifications.
|
|
1893
|
+
* Manages watch registrations, channel adapters, user preferences,
|
|
1894
|
+
* mute rules, and event-driven status dispatch.
|
|
1895
|
+
*
|
|
1896
|
+
* @see docs/features/push-notification.md
|
|
1897
|
+
*/
|
|
1898
|
+
|
|
1899
|
+
declare class Notifier {
|
|
1900
|
+
private channels;
|
|
1901
|
+
private watches;
|
|
1902
|
+
private preferences;
|
|
1903
|
+
private muteRules;
|
|
1904
|
+
private statusCallbacks;
|
|
1905
|
+
private defaultPreferences;
|
|
1906
|
+
private storage?;
|
|
1907
|
+
constructor(options?: NotifierOptions);
|
|
1908
|
+
registerChannel(channel: NotificationChannel): void;
|
|
1909
|
+
unregisterChannel(channelId: string): void;
|
|
1910
|
+
getChannel(channelId: string): NotificationChannel | undefined;
|
|
1911
|
+
getActiveChannels(): string[];
|
|
1912
|
+
/**
|
|
1913
|
+
* Start watching a transaction for notifications.
|
|
1914
|
+
*
|
|
1915
|
+
* When the tx status changes, notifications will be dispatched
|
|
1916
|
+
* to all registered channels based on the watch configuration
|
|
1917
|
+
* and the user's preferences + mute rules.
|
|
1918
|
+
*/
|
|
1919
|
+
watchTx(hash: string, chainId: string, options?: {
|
|
1920
|
+
userId?: string;
|
|
1921
|
+
channels?: string[];
|
|
1922
|
+
frequency?: NotificationFrequency;
|
|
1923
|
+
txMetadata?: Partial<TxMetadata>;
|
|
1924
|
+
}): void;
|
|
1925
|
+
/**
|
|
1926
|
+
* Stop watching a transaction.
|
|
1927
|
+
*/
|
|
1928
|
+
unregisterTxWatch(hash: string): void;
|
|
1929
|
+
getWatch(hash: string): NotificationWatch | undefined;
|
|
1930
|
+
getAllWatches(): NotificationWatch[];
|
|
1931
|
+
/**
|
|
1932
|
+
* Subscribe to status changes for a specific transaction.
|
|
1933
|
+
*
|
|
1934
|
+
* Returns an unsubscribe function.
|
|
1935
|
+
*/
|
|
1936
|
+
onTxStatus(hash: string, callback: TxStatusCallback): () => void;
|
|
1937
|
+
/**
|
|
1938
|
+
* Called when a transaction's status changes.
|
|
1939
|
+
*
|
|
1940
|
+
* This is the main entry point from TxMonitor integration.
|
|
1941
|
+
* It evaluates mute rules, determines whether to fire based on
|
|
1942
|
+
* the frequency preference, and dispatches to all channels.
|
|
1943
|
+
*/
|
|
1944
|
+
handleTxStatus(hash: string, status: TxStatus, receipt?: {
|
|
1945
|
+
confirmations?: number;
|
|
1946
|
+
value?: bigint;
|
|
1947
|
+
gasUsed?: bigint;
|
|
1948
|
+
gasCostUsd?: number;
|
|
1949
|
+
}): Promise<void>;
|
|
1950
|
+
/**
|
|
1951
|
+
* Send a notification directly (bypasses watch and frequency checks).
|
|
1952
|
+
*/
|
|
1953
|
+
notify(payload: Omit<NotificationPayload, "id" | "timestamp">, channels?: string[]): Promise<void>;
|
|
1954
|
+
setPreferences(userId: string, prefs: Partial<UserNotificationPreferences>): void;
|
|
1955
|
+
getPreferences(userId: string): UserNotificationPreferences;
|
|
1956
|
+
getDefaultPreferences(): UserNotificationPreferences;
|
|
1957
|
+
addMuteRule(userId: string, rule: MuteRule): void;
|
|
1958
|
+
removeMuteRule(userId: string, ruleId: string): void;
|
|
1959
|
+
getMuteRules(userId: string): MuteRule[];
|
|
1960
|
+
/**
|
|
1961
|
+
* Evaluate whether a transaction should be muted based on active rules.
|
|
1962
|
+
*/
|
|
1963
|
+
isMuted(metadata: TxMetadata, rules: MuteRule[]): boolean;
|
|
1964
|
+
/** Restore persisted state (call on initialization). */
|
|
1965
|
+
restore(): Promise<void>;
|
|
1966
|
+
private persistPreferences;
|
|
1967
|
+
private persistWatches;
|
|
1968
|
+
private persistMuteRules;
|
|
1969
|
+
private shouldNotify;
|
|
1970
|
+
private buildPayload;
|
|
1971
|
+
private dispatchToChannels;
|
|
1972
|
+
}
|
|
1973
|
+
|
|
1974
|
+
interface WalletPermission {
|
|
1975
|
+
parentCapability: string;
|
|
1976
|
+
invoker: string;
|
|
1977
|
+
date?: number;
|
|
1978
|
+
caveats?: {
|
|
1979
|
+
type: string;
|
|
1980
|
+
value: unknown;
|
|
1981
|
+
}[];
|
|
1982
|
+
}
|
|
1983
|
+
interface PermissionsRequest {
|
|
1984
|
+
eth_accounts: Record<string, never>;
|
|
1985
|
+
}
|
|
1986
|
+
declare function getPermissions(provider: {
|
|
1987
|
+
request: (args: {
|
|
1988
|
+
method: string;
|
|
1989
|
+
params?: unknown[];
|
|
1990
|
+
}) => Promise<unknown>;
|
|
1991
|
+
}): Promise<WalletPermission[] | null>;
|
|
1992
|
+
declare function requestPermissions(provider: {
|
|
1993
|
+
request: (args: {
|
|
1994
|
+
method: string;
|
|
1995
|
+
params?: unknown[];
|
|
1996
|
+
}) => Promise<unknown>;
|
|
1997
|
+
}): Promise<WalletPermission[]>;
|
|
1998
|
+
declare function extractAccountsFromPermissions(permissions: WalletPermission[]): string[];
|
|
1999
|
+
declare function hasPermission(permissions: WalletPermission[] | null, capability: string): boolean;
|
|
2000
|
+
|
|
2001
|
+
type Platform = "desktop-web" | "mobile-web" | "in-app-browser";
|
|
2002
|
+
declare function detectPlatform(): Platform;
|
|
2003
|
+
declare function isMobileBrowser(): boolean;
|
|
2004
|
+
|
|
2005
|
+
/**
|
|
2006
|
+
* Result of a forward name resolution (name → address).
|
|
2007
|
+
*/
|
|
2008
|
+
interface AddressResult {
|
|
2009
|
+
/** Resolved address (without CAIP-10 prefix). */
|
|
2010
|
+
address: string;
|
|
2011
|
+
/** Chain type that this address belongs to. */
|
|
2012
|
+
chainType: "eip155" | "solana" | "xrpl";
|
|
2013
|
+
/** The original name that was resolved. */
|
|
2014
|
+
name: string;
|
|
2015
|
+
/** Optional chain ID (CAIP-2 format) that the name was resolved on. */
|
|
2016
|
+
chainId?: string;
|
|
2017
|
+
}
|
|
2018
|
+
/**
|
|
2019
|
+
* Result of a reverse lookup (address → name).
|
|
2020
|
+
*/
|
|
2021
|
+
interface NameResult {
|
|
2022
|
+
/** Resolved name (e.g. "vitalik.eth", "vitalik.sol"). */
|
|
2023
|
+
name: string;
|
|
2024
|
+
/** Chain type that this name belongs to. */
|
|
2025
|
+
chainType: "eip155" | "solana" | "xrpl";
|
|
2026
|
+
/** Whether the result is a primary / canonical name. */
|
|
2027
|
+
isPrimary: boolean;
|
|
2028
|
+
}
|
|
2029
|
+
/**
|
|
2030
|
+
* Provider interface for a specific name service (ENS, SNS, etc.).
|
|
2031
|
+
*/
|
|
2032
|
+
interface ResolverProvider {
|
|
2033
|
+
/** The chain type this provider handles. */
|
|
2034
|
+
chainType: "eip155" | "solana" | "xrpl";
|
|
2035
|
+
/** Resolve a name to an address. Returns null if name is not found. */
|
|
2036
|
+
resolveName(name: string): Promise<AddressResult | null>;
|
|
2037
|
+
/** Reverse-lookup an address to a name. Returns null if no name is found. */
|
|
2038
|
+
lookupAddress(address: string): Promise<NameResult | null>;
|
|
2039
|
+
/** Check if this provider can handle a given name (by suffix or format). */
|
|
2040
|
+
supportsName(name: string): boolean;
|
|
2041
|
+
}
|
|
2042
|
+
/**
|
|
2043
|
+
* Error codes for name resolution failures.
|
|
2044
|
+
*/
|
|
2045
|
+
type ResolutionErrorCode = "NAME_NOT_FOUND" | "PROVIDER_UNAVAILABLE" | "UNSUPPORTED_NAME_SERVICE" | "RESOLUTION_TIMEOUT" | "INVALID_NAME" | "INVALID_ADDRESS";
|
|
2046
|
+
/**
|
|
2047
|
+
* Error class for name resolution failures.
|
|
2048
|
+
*/
|
|
2049
|
+
declare class ResolutionError extends Error {
|
|
2050
|
+
readonly code: ResolutionErrorCode;
|
|
2051
|
+
constructor(code: ResolutionErrorCode, message: string, cause?: unknown);
|
|
2052
|
+
}
|
|
2053
|
+
/**
|
|
2054
|
+
* Configuration for the name resolver.
|
|
2055
|
+
*/
|
|
2056
|
+
interface NameResolverConfig {
|
|
2057
|
+
providers?: {
|
|
2058
|
+
ens?: {
|
|
2059
|
+
rpcUrl: string;
|
|
2060
|
+
};
|
|
2061
|
+
sns?: {
|
|
2062
|
+
rpcUrl: string;
|
|
2063
|
+
};
|
|
2064
|
+
};
|
|
2065
|
+
cache?: {
|
|
2066
|
+
/** TTL in milliseconds (default: 5 minutes). */
|
|
2067
|
+
ttlMs: number;
|
|
2068
|
+
};
|
|
2069
|
+
/** Default timeout for resolution requests in ms. */
|
|
2070
|
+
timeoutMs?: number;
|
|
2071
|
+
}
|
|
2072
|
+
/**
|
|
2073
|
+
* Simple in-memory cache with TTL.
|
|
2074
|
+
*/
|
|
2075
|
+
declare class ResolverCache {
|
|
2076
|
+
private cache;
|
|
2077
|
+
private readonly ttlMs;
|
|
2078
|
+
constructor(ttlMs?: number);
|
|
2079
|
+
get<T>(key: string): T | null;
|
|
2080
|
+
set<T>(key: string, value: T): void;
|
|
2081
|
+
clear(): void;
|
|
2082
|
+
/** Remove stale entries. */
|
|
2083
|
+
prune(): void;
|
|
2084
|
+
}
|
|
2085
|
+
|
|
2086
|
+
/**
|
|
2087
|
+
* Unified name resolution service for ENS / SNS / future name systems.
|
|
2088
|
+
*
|
|
2089
|
+
* Features:
|
|
2090
|
+
* - Auto-detection of name service by suffix (.eth → ENS, .sol → SNS)
|
|
2091
|
+
* - Forward resolution: name → address
|
|
2092
|
+
* - Reverse lookup: address → name
|
|
2093
|
+
* - In-memory caching with configurable TTL
|
|
2094
|
+
* - Timeout support
|
|
2095
|
+
* - Minimal dependencies (plain fetch, no ethers/web3)
|
|
2096
|
+
*/
|
|
2097
|
+
declare class NameResolver {
|
|
2098
|
+
private readonly providers;
|
|
2099
|
+
private readonly cache;
|
|
2100
|
+
private readonly timeoutMs;
|
|
2101
|
+
constructor(config?: NameResolverConfig);
|
|
2102
|
+
/**
|
|
2103
|
+
* Register a custom name resolution provider.
|
|
2104
|
+
*/
|
|
2105
|
+
registerProvider(provider: ResolverProvider): void;
|
|
2106
|
+
/**
|
|
2107
|
+
* Resolve a human-readable name to a blockchain address.
|
|
2108
|
+
*
|
|
2109
|
+
* @param name - The name to resolve (e.g. "vitalik.eth", "jupiter.sol").
|
|
2110
|
+
* @returns AddressResult with the resolved address, or null if not found.
|
|
2111
|
+
* @throws ResolutionError on provider errors, timeout, or unsupported names.
|
|
2112
|
+
*/
|
|
2113
|
+
resolveName(name: string): Promise<AddressResult | null>;
|
|
2114
|
+
/**
|
|
2115
|
+
* Reverse-lookup a blockchain address to find its human-readable name.
|
|
2116
|
+
*
|
|
2117
|
+
* @param address - The blockchain address to look up.
|
|
2118
|
+
* @param chainId - Optional CAIP-2 chain ID to hint which provider to use.
|
|
2119
|
+
* @returns NameResult with the resolved name, or null if not found.
|
|
2120
|
+
*/
|
|
2121
|
+
lookupAddress(address: string, chainId?: string): Promise<NameResult | null>;
|
|
2122
|
+
/**
|
|
2123
|
+
* Resolve multiple names in a single batch call.
|
|
2124
|
+
* Merges requests by provider to minimize RPC calls.
|
|
2125
|
+
*
|
|
2126
|
+
* @param names - Array of names to resolve.
|
|
2127
|
+
* @returns Map of name to AddressResult (or null if not found).
|
|
2128
|
+
*/
|
|
2129
|
+
resolveNames(names: string[]): Promise<Map<string, AddressResult | null>>;
|
|
2130
|
+
/**
|
|
2131
|
+
* Clear the resolution cache.
|
|
2132
|
+
*/
|
|
2133
|
+
clearCache(): void;
|
|
2134
|
+
private findProviderForName;
|
|
2135
|
+
private detectChainType;
|
|
2136
|
+
private withTimeout;
|
|
2137
|
+
}
|
|
2138
|
+
|
|
2139
|
+
/**
|
|
2140
|
+
* ENS name resolution provider.
|
|
2141
|
+
*
|
|
2142
|
+
* Resolves `.eth` names via direct eth_call to ENS contracts.
|
|
2143
|
+
* Does NOT depend on ethers.js or web3.js — uses plain fetch + minimal
|
|
2144
|
+
* ABI encoding.
|
|
2145
|
+
*/
|
|
2146
|
+
declare class ENSProvider implements ResolverProvider {
|
|
2147
|
+
readonly chainType: "eip155";
|
|
2148
|
+
private readonly rpcUrl;
|
|
2149
|
+
constructor(rpcUrl: string);
|
|
2150
|
+
supportsName(name: string): boolean;
|
|
2151
|
+
resolveName(name: string): Promise<AddressResult | null>;
|
|
2152
|
+
lookupAddress(address: string): Promise<NameResult | null>;
|
|
2153
|
+
private getResolver;
|
|
2154
|
+
}
|
|
2155
|
+
|
|
2156
|
+
/**
|
|
2157
|
+
* SNS (Solana Name Service) provider.
|
|
2158
|
+
*
|
|
2159
|
+
* Resolves `.sol` names via Solana RPC, querying the Bonfida SNS program.
|
|
2160
|
+
* Uses plain fetch + @noble/hashes — no @solana/web3.js dependency.
|
|
2161
|
+
*/
|
|
2162
|
+
declare class SNSProvider implements ResolverProvider {
|
|
2163
|
+
readonly chainType: "solana";
|
|
2164
|
+
private readonly rpcUrl;
|
|
2165
|
+
constructor(rpcUrl: string);
|
|
2166
|
+
supportsName(name: string): boolean;
|
|
2167
|
+
resolveName(name: string): Promise<AddressResult | null>;
|
|
2168
|
+
lookupAddress(address: string): Promise<NameResult | null>;
|
|
2169
|
+
/**
|
|
2170
|
+
* Convert a hex string to a Base58 Solana address.
|
|
2171
|
+
*/
|
|
2172
|
+
private hexToBase58;
|
|
2173
|
+
}
|
|
2174
|
+
|
|
2175
|
+
/**
|
|
2176
|
+
* RouteEngine Types
|
|
2177
|
+
*
|
|
2178
|
+
* Core type definitions for the cross-chain routing engine with
|
|
2179
|
+
* provider-agnostic swap and bridge providers.
|
|
2180
|
+
*
|
|
2181
|
+
* @see docs/features/routes.md
|
|
2182
|
+
*/
|
|
2183
|
+
interface Token {
|
|
2184
|
+
chainId: number;
|
|
2185
|
+
address: string;
|
|
2186
|
+
decimals: number;
|
|
2187
|
+
symbol: string;
|
|
2188
|
+
}
|
|
2189
|
+
interface ChainInfo {
|
|
2190
|
+
chainId: number;
|
|
2191
|
+
name: string;
|
|
2192
|
+
}
|
|
2193
|
+
|
|
2194
|
+
declare const DEFAULT_RPC_URLS: Record<string, string>;
|
|
2195
|
+
/**
|
|
2196
|
+
* Get the default RPC URL for a given CAIP-2 chainId.
|
|
2197
|
+
* Returns undefined if no default is configured.
|
|
2198
|
+
*/
|
|
2199
|
+
declare function getRpcUrl(chainId: string, fallback?: string): string | undefined;
|
|
2200
|
+
|
|
2201
|
+
/**
|
|
2202
|
+
* Session Key Error Codes
|
|
2203
|
+
*/
|
|
2204
|
+
|
|
2205
|
+
type SessionKeyErrorCode = "session_key_not_found" | "session_key_expired" | "session_key_revoked" | "session_key_scope_exceeded" | "session_key_method_forbidden" | "session_key_contract_not_allowed" | "session_key_chain_not_allowed" | "session_key_storage_unavailable" | "session_key_encryption_failed" | "session_key_required_fields_missing" | "session_key_max_tx_count_exceeded" | "session_key_value_limit_exceeded" | "session_key_gas_limit_exceeded";
|
|
2206
|
+
declare const SESSION_KEY_ERROR_MESSAGES: Record<SessionKeyErrorCode, string>;
|
|
2207
|
+
/**
|
|
2208
|
+
* Create a WalletError with a session-key-specific error code.
|
|
2209
|
+
*/
|
|
2210
|
+
declare function createSessionKeyError(code: SessionKeyErrorCode, details?: unknown): WalletError;
|
|
2211
|
+
|
|
2212
|
+
/**
|
|
2213
|
+
* Storage Adapter Interface
|
|
2214
|
+
*
|
|
2215
|
+
* Defines the contract for session storage implementations.
|
|
2216
|
+
* Allows custom storage backends (localStorage, sessionStorage, IndexedDB, etc.)
|
|
2217
|
+
*/
|
|
2218
|
+
declare class StorageError extends Error {
|
|
2219
|
+
code: "quota_exceeded" | "not_available" | "parse_error" | "unknown";
|
|
2220
|
+
constructor(message: string, code?: "quota_exceeded" | "not_available" | "parse_error" | "unknown", cause?: unknown);
|
|
2221
|
+
}
|
|
2222
|
+
interface StorageAdapter {
|
|
2223
|
+
get<T>(key: string): Promise<T | null>;
|
|
2224
|
+
set<T>(key: string, value: T): Promise<void>;
|
|
2225
|
+
remove(key: string): Promise<void>;
|
|
2226
|
+
clear(): Promise<void>;
|
|
2227
|
+
has(key: string): Promise<boolean>;
|
|
2228
|
+
isAvailable(): boolean;
|
|
2229
|
+
}
|
|
2230
|
+
declare class LocalStorageAdapter implements StorageAdapter {
|
|
2231
|
+
private prefix;
|
|
2232
|
+
private _available;
|
|
2233
|
+
constructor(prefix?: string);
|
|
2234
|
+
private getKey;
|
|
2235
|
+
private getStorage;
|
|
2236
|
+
isAvailable(): boolean;
|
|
2237
|
+
get<T>(key: string): Promise<T | null>;
|
|
2238
|
+
set<T>(key: string, value: T): Promise<void>;
|
|
2239
|
+
remove(key: string): Promise<void>;
|
|
2240
|
+
clear(): Promise<void>;
|
|
2241
|
+
has(key: string): Promise<boolean>;
|
|
2242
|
+
}
|
|
2243
|
+
declare class SessionStorageAdapter implements StorageAdapter {
|
|
2244
|
+
private prefix;
|
|
2245
|
+
private _available;
|
|
2246
|
+
constructor(prefix?: string);
|
|
2247
|
+
private getKey;
|
|
2248
|
+
isAvailable(): boolean;
|
|
2249
|
+
get<T>(key: string): Promise<T | null>;
|
|
2250
|
+
set<T>(key: string, value: T): Promise<void>;
|
|
2251
|
+
remove(key: string): Promise<void>;
|
|
2252
|
+
clear(): Promise<void>;
|
|
2253
|
+
has(key: string): Promise<boolean>;
|
|
2254
|
+
}
|
|
2255
|
+
declare class MemoryStorageAdapter implements StorageAdapter {
|
|
2256
|
+
private store;
|
|
2257
|
+
isAvailable(): boolean;
|
|
2258
|
+
get<T>(key: string): Promise<T | null>;
|
|
2259
|
+
set<T>(key: string, value: T): Promise<void>;
|
|
2260
|
+
remove(key: string): Promise<void>;
|
|
2261
|
+
clear(): Promise<void>;
|
|
2262
|
+
has(key: string): Promise<boolean>;
|
|
2263
|
+
}
|
|
2264
|
+
declare class NoopStorageAdapter implements StorageAdapter {
|
|
2265
|
+
isAvailable(): boolean;
|
|
2266
|
+
get<T>(_key: string): Promise<T | null>;
|
|
2267
|
+
set<T>(_key: string, _value: T): Promise<void>;
|
|
2268
|
+
remove(_key: string): Promise<void>;
|
|
2269
|
+
clear(): Promise<void>;
|
|
2270
|
+
has(_key: string): Promise<boolean>;
|
|
2271
|
+
}
|
|
2272
|
+
declare function createStorageAdapter(type: "local" | "session" | "memory" | "none", prefix?: string): StorageAdapter;
|
|
2273
|
+
|
|
2274
|
+
/**
|
|
2275
|
+
* Session Keys / Ephemeral Keys — Type Definitions
|
|
2276
|
+
*
|
|
2277
|
+
* Defines the core types for session key creation, storage,
|
|
2278
|
+
* authorization, and scope-based transaction control.
|
|
2279
|
+
*
|
|
2280
|
+
* @see docs/features/session-keys.md
|
|
2281
|
+
*/
|
|
2282
|
+
/**
|
|
2283
|
+
* Defines the permitted scope for a session key.
|
|
2284
|
+
*
|
|
2285
|
+
* All numeric limits are best-effort enforced client-side.
|
|
2286
|
+
* For on-chain enforcement, use EIP-7702 or AA module delegation.
|
|
2287
|
+
*/
|
|
2288
|
+
interface SessionKeyScope {
|
|
2289
|
+
/** Unix timestamp (seconds) after which the key expires */
|
|
2290
|
+
expiry: number;
|
|
2291
|
+
/** Maximum total gas across all transactions (wei) */
|
|
2292
|
+
maxTotalGas?: bigint;
|
|
2293
|
+
/** Maximum gas per single transaction (wei) */
|
|
2294
|
+
maxGasPerTx?: bigint;
|
|
2295
|
+
/** Maximum total value of assets transferred (wei / token base units) */
|
|
2296
|
+
maxTotalValue?: bigint;
|
|
2297
|
+
/** Maximum value per single transaction */
|
|
2298
|
+
maxValuePerTx?: bigint;
|
|
2299
|
+
/** Maximum number of transactions this key can sign */
|
|
2300
|
+
maxTxCount?: number;
|
|
2301
|
+
/** Allowed target contract addresses (empty = any contract) */
|
|
2302
|
+
allowedContracts?: `0x${string}`[];
|
|
2303
|
+
/** Allowed method selectors (4-byte hex, empty = any method) */
|
|
2304
|
+
allowedMethods?: string[];
|
|
2305
|
+
/** Per-token allowances: token address → max amount in token base units */
|
|
2306
|
+
tokenAllowances?: Record<`0x${string}`, bigint>;
|
|
2307
|
+
/** Chain IDs this key is valid for (empty = any chain) */
|
|
2308
|
+
allowedChainIds?: number[];
|
|
2309
|
+
/** Session type: off-chain agreement, EIP-7702 delegation, or AA module */
|
|
2310
|
+
mode: "offchain" | "eip7702" | "aa_module";
|
|
2311
|
+
}
|
|
2312
|
+
/** A secp256k1 key pair (private key NEVER persisted unencrypted) */
|
|
2313
|
+
interface SessionKeyPair {
|
|
2314
|
+
publicKey: `0x${string}`;
|
|
2315
|
+
privateKey: `0x${string}`;
|
|
2316
|
+
}
|
|
2317
|
+
/** Encrypted session key data for local storage */
|
|
2318
|
+
interface EncryptedKeyPair {
|
|
2319
|
+
publicKey: `0x${string}`;
|
|
2320
|
+
encryptedPrivateKey: string;
|
|
2321
|
+
iv: string;
|
|
2322
|
+
salt: string;
|
|
2323
|
+
}
|
|
2324
|
+
/** Authorization signature from the main wallet */
|
|
2325
|
+
interface SignedAuthorization {
|
|
2326
|
+
/** EIP-7702 authorization bytes (if mode === "eip7702") */
|
|
2327
|
+
authorization?: `0x${string}`;
|
|
2328
|
+
/** Off-chain signature of scope hash (if mode === "offchain") */
|
|
2329
|
+
rawSignature?: `0x${string}`;
|
|
2330
|
+
/** Main wallet address that signed this authorization */
|
|
2331
|
+
signerAddress: `0x${string}`;
|
|
2332
|
+
/** Authorization type */
|
|
2333
|
+
type: "eip7702" | "offchain" | "aa_module";
|
|
2334
|
+
}
|
|
2335
|
+
/** Full session key record stored locally (private key encrypted) */
|
|
2336
|
+
interface StoredSessionKey {
|
|
2337
|
+
/** Unique session key ID (UUID v4) */
|
|
2338
|
+
id: string;
|
|
2339
|
+
/** Encrypted key pair for secure persistence */
|
|
2340
|
+
keyPair: EncryptedKeyPair;
|
|
2341
|
+
/** Authorized scope */
|
|
2342
|
+
scope: SessionKeyScope;
|
|
2343
|
+
/** Main wallet's authorization signature */
|
|
2344
|
+
authorization: SignedAuthorization;
|
|
2345
|
+
/** Current status */
|
|
2346
|
+
status: SessionKeyStatus;
|
|
2347
|
+
/** Creation timestamp (Unix ms) */
|
|
2348
|
+
createdAt: number;
|
|
2349
|
+
/** Last usage timestamp (Unix ms) */
|
|
2350
|
+
lastUsedAt: number;
|
|
2351
|
+
/** Number of transactions signed with this key */
|
|
2352
|
+
useCount: number;
|
|
2353
|
+
}
|
|
2354
|
+
/** Session key public info — safe to expose to UI */
|
|
2355
|
+
interface SessionKeyInfo {
|
|
2356
|
+
id: string;
|
|
2357
|
+
publicKey: `0x${string}`;
|
|
2358
|
+
scope: SessionKeyScope;
|
|
2359
|
+
status: SessionKeyStatus;
|
|
2360
|
+
createdAt: number;
|
|
2361
|
+
expiresAt: number;
|
|
2362
|
+
useCount: number;
|
|
2363
|
+
signerAddress: `0x${string}`;
|
|
2364
|
+
}
|
|
2365
|
+
type SessionKeyStatus = "active" | "revoked" | "expired";
|
|
2366
|
+
/** Decrypted session key ready for signing (memory only) */
|
|
2367
|
+
interface SessionKeyBundle {
|
|
2368
|
+
id: string;
|
|
2369
|
+
privateKey: `0x${string}`;
|
|
2370
|
+
scope: SessionKeyScope;
|
|
2371
|
+
authorization: SignedAuthorization;
|
|
2372
|
+
/** The main wallet address that authorized this session */
|
|
2373
|
+
signerAddress: `0x${string}`;
|
|
2374
|
+
}
|
|
2375
|
+
interface ScopeCheckResult {
|
|
2376
|
+
valid: boolean;
|
|
2377
|
+
reason?: string;
|
|
2378
|
+
remainingGas?: bigint;
|
|
2379
|
+
remainingValue?: bigint;
|
|
2380
|
+
remainingTxCount?: number;
|
|
2381
|
+
}
|
|
2382
|
+
interface SessionKeyManagerConfig {
|
|
2383
|
+
/** Storage key prefix (default: "naculus_session_keys") */
|
|
2384
|
+
storagePrefix?: string;
|
|
2385
|
+
/** Default max total value for new session keys (wei, default: 0.1 ETH) */
|
|
2386
|
+
defaultMaxTotalValue?: bigint;
|
|
2387
|
+
/** Default max transactions per key (default: 50) */
|
|
2388
|
+
defaultMaxTxCount?: number;
|
|
2389
|
+
/** Default max session duration in ms (default: 24h) */
|
|
2390
|
+
defaultExpiryMs?: number;
|
|
2391
|
+
/** Whether to require allowedContracts (default: true) */
|
|
2392
|
+
requireAllowedContracts?: boolean;
|
|
2393
|
+
/** Forbidden method selectors (default: approve, permit) */
|
|
2394
|
+
forbiddenMethods?: string[];
|
|
2395
|
+
/** Key derivation salt for encryption (auto-generated if not provided) */
|
|
2396
|
+
encryptionSalt?: string;
|
|
2397
|
+
/** Password-derived encryption key (hex string). If not provided, a random one is generated on first use. */
|
|
2398
|
+
encryptionKey?: string;
|
|
2399
|
+
/**
|
|
2400
|
+
* PBKDF2 iteration count for key derivation.
|
|
2401
|
+
* Default: 600_000 (OWASP recommended for AES-256 in 2025).
|
|
2402
|
+
* Set lower (e.g. 1000) for testing to avoid timeout.
|
|
2403
|
+
*/
|
|
2404
|
+
pbkdf2Iterations?: number;
|
|
2405
|
+
}
|
|
2406
|
+
declare const DEFAULT_SESSION_KEY_CONFIG: Required<SessionKeyManagerConfig>;
|
|
2407
|
+
|
|
2408
|
+
/**
|
|
2409
|
+
* SessionKeyManager
|
|
2410
|
+
*
|
|
2411
|
+
* Manages ephemeral session keys for automated transaction signing
|
|
2412
|
+
* without wallet popups. Session keys are:
|
|
2413
|
+
*
|
|
2414
|
+
* - Short-lived (configurable expiry, default 24h)
|
|
2415
|
+
* - Scoped (limits on value, gas, contracts, methods, chain)
|
|
2416
|
+
* - Revocable (local revoke instantly invalidates)
|
|
2417
|
+
* - Encrypted at rest (AES-256-CTR-HMAC via @noble/hashes)
|
|
2418
|
+
*
|
|
2419
|
+
* Uses standard secp256k1 key pairs generated client-side.
|
|
2420
|
+
* Private keys are encrypted before storage and decrypted only in memory.
|
|
2421
|
+
*
|
|
2422
|
+
* @see docs/features/session-keys.md
|
|
2423
|
+
*/
|
|
2424
|
+
|
|
2425
|
+
declare class SessionKeyManager {
|
|
2426
|
+
private config;
|
|
2427
|
+
private storage;
|
|
2428
|
+
private encryptionPassword;
|
|
2429
|
+
private activeBundle;
|
|
2430
|
+
private cache;
|
|
2431
|
+
constructor(config?: SessionKeyManagerConfig, storageAdapter?: StorageAdapter);
|
|
2432
|
+
/**
|
|
2433
|
+
* Check whether the storage backend is available.
|
|
2434
|
+
*/
|
|
2435
|
+
isStorageAvailable(): boolean;
|
|
2436
|
+
/**
|
|
2437
|
+
* Create a new session key (secp256k1 keypair).
|
|
2438
|
+
*
|
|
2439
|
+
* Generates a fresh key pair, encrypts the private key,
|
|
2440
|
+
* persists to storage, and returns public session info.
|
|
2441
|
+
*
|
|
2442
|
+
* @param scope - Optional scope overrides. Missing fields use defaults.
|
|
2443
|
+
* @param signerAddress - The main wallet address that authorizes this session
|
|
2444
|
+
* @returns Public session key info (no private key exposed)
|
|
2445
|
+
*/
|
|
2446
|
+
createSessionKey(scope?: Partial<SessionKeyScope>, signerAddress?: `0x${string}`): Promise<SessionKeyInfo>;
|
|
2447
|
+
/**
|
|
2448
|
+
* List all session keys (active, revoked, or expired).
|
|
2449
|
+
* Automatically marks expired keys.
|
|
2450
|
+
*/
|
|
2451
|
+
listSessions(): Promise<SessionKeyInfo[]>;
|
|
2452
|
+
/**
|
|
2453
|
+
* List only active session keys.
|
|
2454
|
+
*/
|
|
2455
|
+
listActiveSessions(): Promise<SessionKeyInfo[]>;
|
|
2456
|
+
/**
|
|
2457
|
+
* Revoke a session key by ID.
|
|
2458
|
+
* Sets status to "revoked" and invalidates the cached bundle.
|
|
2459
|
+
*/
|
|
2460
|
+
revokeSession(sessionId: string): Promise<void>;
|
|
2461
|
+
/**
|
|
2462
|
+
* Get a decrypted session key bundle for transaction signing.
|
|
2463
|
+
* Validates expiry and status before returning.
|
|
2464
|
+
*
|
|
2465
|
+
* @param sessionId - The session key ID
|
|
2466
|
+
* @returns Decrypted SessionKeyBundle or throws
|
|
2467
|
+
*/
|
|
2468
|
+
getSessionBundle(sessionId: string): Promise<SessionKeyBundle>;
|
|
2469
|
+
/**
|
|
2470
|
+
* Sign a raw message hash using a session key.
|
|
2471
|
+
* Validates scope, increments usage counter, and returns the signature.
|
|
2472
|
+
*
|
|
2473
|
+
* @param sessionId - The session key ID
|
|
2474
|
+
* @param messageHash - The 32-byte message hash to sign (0x-prefixed hex)
|
|
2475
|
+
* @returns secp256k1 signature as hex
|
|
2476
|
+
*/
|
|
2477
|
+
signWithSessionKey(sessionId: string, messageHash: `0x${string}`): Promise<`0x${string}`>;
|
|
2478
|
+
/**
|
|
2479
|
+
* Check whether a session key's scope allows a given transaction.
|
|
2480
|
+
* Updates usage tracking before returning.
|
|
2481
|
+
*/
|
|
2482
|
+
checkSessionScope(sessionId: string, tx: {
|
|
2483
|
+
to?: string;
|
|
2484
|
+
value?: string;
|
|
2485
|
+
data?: string;
|
|
2486
|
+
chainId?: number;
|
|
2487
|
+
gas?: string;
|
|
2488
|
+
}): Promise<ScopeCheckResult>;
|
|
2489
|
+
/**
|
|
2490
|
+
* Attach a signed authorization (e.g., EIP-7702 or off-chain signature)
|
|
2491
|
+
* to an existing session key.
|
|
2492
|
+
*/
|
|
2493
|
+
setAuthorization(sessionId: string, authorization: SignedAuthorization): Promise<void>;
|
|
2494
|
+
/**
|
|
2495
|
+
* Remove all session keys from storage.
|
|
2496
|
+
*/
|
|
2497
|
+
clearAll(): Promise<void>;
|
|
2498
|
+
/**
|
|
2499
|
+
* Resolve the final scope by merging user-provided overrides with defaults.
|
|
2500
|
+
*/
|
|
2501
|
+
private resolveScope;
|
|
2502
|
+
/**
|
|
2503
|
+
* Validate that a session key is active and not expired.
|
|
2504
|
+
*/
|
|
2505
|
+
private validateSessionStatus;
|
|
2506
|
+
/**
|
|
2507
|
+
* Check whether a transaction falls within the session key's scope.
|
|
2508
|
+
*/
|
|
2509
|
+
private checkScopeAgainstTx;
|
|
2510
|
+
/**
|
|
2511
|
+
* Reload the cache from storage, auto-marking expired keys.
|
|
2512
|
+
*/
|
|
2513
|
+
private refreshCache;
|
|
2514
|
+
/**
|
|
2515
|
+
* Convert a StoredSessionKey to a public SessionKeyInfo.
|
|
2516
|
+
*/
|
|
2517
|
+
private toSessionKeyInfo;
|
|
2518
|
+
}
|
|
2519
|
+
|
|
2520
|
+
/**
|
|
2521
|
+
* Session Key Secure Storage
|
|
2522
|
+
*
|
|
2523
|
+
* Provides AES-256-GCM encryption for session key private keys
|
|
2524
|
+
* using a password-derived key (PBKDF2) for storage.
|
|
2525
|
+
*
|
|
2526
|
+
* Supports:
|
|
2527
|
+
* - LocalStorageAdapter (from core/storage.ts)
|
|
2528
|
+
* - MemoryStorageAdapter (for testing / SSR)
|
|
2529
|
+
* - IndexedDB-backed storage (browser-native, non-blocking)
|
|
2530
|
+
*
|
|
2531
|
+
* Private keys are NEVER stored in plaintext — always encrypted
|
|
2532
|
+
* before persisting, and decrypted only in memory during signing.
|
|
2533
|
+
*
|
|
2534
|
+
* @see docs/features/session-keys.md §6
|
|
2535
|
+
*/
|
|
2536
|
+
|
|
2537
|
+
/**
|
|
2538
|
+
* Encrypt a private key hex string for secure storage.
|
|
2539
|
+
*
|
|
2540
|
+
* @param privateKeyHex - The raw private key as a 0x-prefixed hex string
|
|
2541
|
+
* @param password - Derivation password (e.g. wallet seed hash or user-provided)
|
|
2542
|
+
* @param salt - Optional salt override (provided for decryption consistency)
|
|
2543
|
+
* @returns EncryptedKeyPair with ciphertext, IV, and salt
|
|
2544
|
+
*/
|
|
2545
|
+
declare function encryptPrivateKey(privateKeyHex: `0x${string}`, password: string, salt?: Uint8Array, iterations?: number, publicKeyHex?: `0x${string}`): EncryptedKeyPair;
|
|
2546
|
+
/**
|
|
2547
|
+
* Decrypt an encrypted private key for in-memory signing.
|
|
2548
|
+
*
|
|
2549
|
+
* @param encrypted - EncryptedKeyPair from storage
|
|
2550
|
+
* @param password - The same password used during encryption
|
|
2551
|
+
* @param iterations - Must match the value used during encryption
|
|
2552
|
+
* @returns The raw private key as a 0x-prefixed hex string
|
|
2553
|
+
*/
|
|
2554
|
+
declare function decryptPrivateKey(encrypted: EncryptedKeyPair, password: string, iterations?: number): `0x${string}`;
|
|
2555
|
+
/**
|
|
2556
|
+
* Manages persistence of StoredSessionKey records to a StorageAdapter.
|
|
2557
|
+
* All private keys are already encrypted before reaching this layer.
|
|
2558
|
+
*/
|
|
2559
|
+
declare class SessionKeyStorage {
|
|
2560
|
+
private adapter;
|
|
2561
|
+
constructor(adapter?: StorageAdapter);
|
|
2562
|
+
/**
|
|
2563
|
+
* Check if the storage backend is available.
|
|
2564
|
+
*/
|
|
2565
|
+
isAvailable(): boolean;
|
|
2566
|
+
/**
|
|
2567
|
+
* Load all stored session keys with BigInt revival.
|
|
2568
|
+
*/
|
|
2569
|
+
loadAll(): Promise<StoredSessionKey[]>;
|
|
2570
|
+
/**
|
|
2571
|
+
* Persist an array of session keys with BigInt serialization.
|
|
2572
|
+
*/
|
|
2573
|
+
private persistAll;
|
|
2574
|
+
/**
|
|
2575
|
+
* Save a single session key (adds or updates).
|
|
2576
|
+
*/
|
|
2577
|
+
save(key: StoredSessionKey): Promise<void>;
|
|
2578
|
+
/**
|
|
2579
|
+
* Retrieve a single session key by ID.
|
|
2580
|
+
*/
|
|
2581
|
+
get(id: string): Promise<StoredSessionKey | null>;
|
|
2582
|
+
/**
|
|
2583
|
+
* Remove a single session key by ID.
|
|
2584
|
+
*/
|
|
2585
|
+
remove(id: string): Promise<void>;
|
|
2586
|
+
/**
|
|
2587
|
+
* Update the status of a session key (active → revoked / expired).
|
|
2588
|
+
*/
|
|
2589
|
+
updateStatus(id: string, status: StoredSessionKey["status"]): Promise<void>;
|
|
2590
|
+
/**
|
|
2591
|
+
* Increment the usage counter for a session key.
|
|
2592
|
+
*/
|
|
2593
|
+
incrementUsage(id: string): Promise<void>;
|
|
2594
|
+
/**
|
|
2595
|
+
* Remove all session keys.
|
|
2596
|
+
*/
|
|
2597
|
+
clear(): Promise<void>;
|
|
2598
|
+
}
|
|
2599
|
+
|
|
2600
|
+
/**
|
|
2601
|
+
* Session-Manager-Specific Error Codes
|
|
2602
|
+
*
|
|
2603
|
+
* Extends WalletError with session-specific error codes.
|
|
2604
|
+
*
|
|
2605
|
+
* @see SRS-009 §8
|
|
2606
|
+
*/
|
|
2607
|
+
|
|
2608
|
+
type SessionErrorCode = "no_active_session" | "chain_switch_rejected" | "chain_unsupported" | "fee_rpc_error" | "method_unsupported" | "invalid_chain";
|
|
2609
|
+
declare const SESSION_ERROR_MESSAGES: Record<SessionErrorCode, string>;
|
|
2610
|
+
/**
|
|
2611
|
+
* Create a WalletError with session-manager-specific error code.
|
|
2612
|
+
*/
|
|
2613
|
+
declare function createSessionError(code: SessionErrorCode, details?: unknown): WalletError;
|
|
2614
|
+
|
|
2615
|
+
/**
|
|
2616
|
+
* Chain Session Model for Multi-Chain Session Management
|
|
2617
|
+
*
|
|
2618
|
+
* @see SRS-009 §3
|
|
2619
|
+
*/
|
|
2620
|
+
|
|
2621
|
+
/**
|
|
2622
|
+
* Chain-specific session data.
|
|
2623
|
+
*
|
|
2624
|
+
* Defines the state of a session on one specific chain.
|
|
2625
|
+
* A single UniversalWalletSession can contain multiple ChainSessions
|
|
2626
|
+
* across different namespaces (e.g., EVM + Solana).
|
|
2627
|
+
*/
|
|
2628
|
+
interface ChainSession {
|
|
2629
|
+
/** Chain ID in CAIP-2 format (e.g., "eip155:1", "solana:0") */
|
|
2630
|
+
chainId: string;
|
|
2631
|
+
/** The connector instance ID that manages this chain */
|
|
2632
|
+
connectorId: string;
|
|
2633
|
+
/** RPC endpoint for this chain */
|
|
2634
|
+
rpcUrl: string;
|
|
2635
|
+
/** Native currency metadata */
|
|
2636
|
+
nativeCurrency: {
|
|
2637
|
+
name: string;
|
|
2638
|
+
symbol: string;
|
|
2639
|
+
decimals: number;
|
|
2640
|
+
};
|
|
2641
|
+
/** Block explorer URL (optional) */
|
|
2642
|
+
blockExplorer?: string;
|
|
2643
|
+
/** Last known fee values (cached) */
|
|
2644
|
+
lastKnownFees?: FeeValues;
|
|
2645
|
+
/** Timestamp of last successful fee estimation */
|
|
2646
|
+
lastFeeUpdatedAt?: string;
|
|
2647
|
+
}
|
|
2648
|
+
/**
|
|
2649
|
+
* Active session bundle: wraps a UniversalWalletSession with
|
|
2650
|
+
* its constituent ChainSessions for multi-chain visibility.
|
|
2651
|
+
*/
|
|
2652
|
+
interface ActiveSessionBundle {
|
|
2653
|
+
/** The persistent UniversalWalletSession */
|
|
2654
|
+
walletSession: UniversalWalletSession;
|
|
2655
|
+
/** Chain-specific sessions derived from namespaces */
|
|
2656
|
+
chainSessions: Map<string, ChainSession>;
|
|
2657
|
+
/** The currently "active" chain ID (the chain being transacted on) */
|
|
2658
|
+
activeChainId: string;
|
|
2659
|
+
/** When this session was last used */
|
|
2660
|
+
lastActiveAt: string;
|
|
2661
|
+
}
|
|
2662
|
+
/**
|
|
2663
|
+
* Serialized format for session persistence.
|
|
2664
|
+
* Map is serialized as Record for JSON compatibility.
|
|
2665
|
+
*/
|
|
2666
|
+
interface PersistedSessionData {
|
|
2667
|
+
walletSession: UniversalWalletSession;
|
|
2668
|
+
lastActiveChainId: string;
|
|
2669
|
+
chainSessions: Record<string, ChainSession>;
|
|
2670
|
+
lastConnectedAt: string;
|
|
2671
|
+
}
|
|
2672
|
+
/**
|
|
2673
|
+
* User-configured fee overrides, preserved across chain switches.
|
|
2674
|
+
* Keyed by CAIP-2 chainId.
|
|
2675
|
+
*/
|
|
2676
|
+
interface UserFeeOverrides {
|
|
2677
|
+
[chainId: string]: {
|
|
2678
|
+
type?: "eip1559" | "legacy";
|
|
2679
|
+
maxPriorityFeePerGas?: bigint;
|
|
2680
|
+
baseFeeMultiplier?: bigint;
|
|
2681
|
+
};
|
|
2682
|
+
}
|
|
2683
|
+
interface SessionManagerConfig {
|
|
2684
|
+
/** Default RPC URLs keyed by chainId */
|
|
2685
|
+
defaultRpcUrls?: Record<string, string>;
|
|
2686
|
+
/** Default native currency metadata keyed by chainId */
|
|
2687
|
+
defaultCurrencies?: Record<string, {
|
|
2688
|
+
name: string;
|
|
2689
|
+
symbol: string;
|
|
2690
|
+
decimals: number;
|
|
2691
|
+
}>;
|
|
2692
|
+
/** Default block explorers keyed by chainId */
|
|
2693
|
+
defaultExplorers?: Record<string, string>;
|
|
2694
|
+
/** Whether to auto-refresh fee estimation on chain switch (default: true) */
|
|
2695
|
+
autoRefreshFeeOnSwitch?: boolean;
|
|
2696
|
+
/** Maximum active session bundles (default: 10) */
|
|
2697
|
+
maxActiveSessions?: number;
|
|
2698
|
+
/** Optional AES-GCM encryption key for session persistence */
|
|
2699
|
+
encryptionKey?: string;
|
|
2700
|
+
}
|
|
2701
|
+
interface RefreshFeesOptions {
|
|
2702
|
+
force?: boolean;
|
|
2703
|
+
userOverrides?: Partial<FeeEstimationConfig>;
|
|
2704
|
+
}
|
|
2705
|
+
/**
|
|
2706
|
+
* Parse a CAIP-2 chain ID into namespace and reference parts.
|
|
2707
|
+
* e.g., "eip155:1" → { namespace: "eip155", reference: "1" }
|
|
2708
|
+
* e.g., "solana:0" → { namespace: "solana", reference: "0" }
|
|
2709
|
+
*/
|
|
2710
|
+
declare function parseChainId(chainId: string): {
|
|
2711
|
+
namespace: string;
|
|
2712
|
+
reference: string;
|
|
2713
|
+
};
|
|
2714
|
+
/**
|
|
2715
|
+
* Validate a CAIP-2 chain ID format.
|
|
2716
|
+
* Supported namespaces: eip155, solana, xrpl
|
|
2717
|
+
*/
|
|
2718
|
+
declare function validateChainId(chainId: string): void;
|
|
2719
|
+
|
|
2720
|
+
/**
|
|
2721
|
+
* Event system for SessionManager
|
|
2722
|
+
*
|
|
2723
|
+
* Provides a typed event emitter that dispatches session lifecycle events
|
|
2724
|
+
* for consumption by React hooks and UI layers.
|
|
2725
|
+
*
|
|
2726
|
+
* @see SRS-009 §7
|
|
2727
|
+
*/
|
|
2728
|
+
|
|
2729
|
+
type SessionEvent = "sessionConnected" | "sessionDisconnected" | "chainChanged" | "chainSessionAdded" | "chainSessionRemoved" | "feesUpdated" | "accountsChanged";
|
|
2730
|
+
interface SessionEventPayloads {
|
|
2731
|
+
sessionConnected: {
|
|
2732
|
+
bundle: ActiveSessionBundle;
|
|
2733
|
+
};
|
|
2734
|
+
sessionDisconnected: {
|
|
2735
|
+
connectorId: string;
|
|
2736
|
+
topic?: string;
|
|
2737
|
+
};
|
|
2738
|
+
chainChanged: {
|
|
2739
|
+
bundle: ActiveSessionBundle;
|
|
2740
|
+
previousChainId: string;
|
|
2741
|
+
newChainId: string;
|
|
2742
|
+
};
|
|
2743
|
+
chainSessionAdded: {
|
|
2744
|
+
bundle: ActiveSessionBundle;
|
|
2745
|
+
chainSession: ChainSession;
|
|
2746
|
+
};
|
|
2747
|
+
chainSessionRemoved: {
|
|
2748
|
+
bundle: ActiveSessionBundle;
|
|
2749
|
+
chainId: string;
|
|
2750
|
+
};
|
|
2751
|
+
feesUpdated: {
|
|
2752
|
+
chainId: string;
|
|
2753
|
+
fees: FeeValues;
|
|
2754
|
+
};
|
|
2755
|
+
accountsChanged: {
|
|
2756
|
+
bundle: ActiveSessionBundle;
|
|
2757
|
+
accounts: string[];
|
|
2758
|
+
};
|
|
2759
|
+
}
|
|
2760
|
+
type SessionEventHandler<E extends SessionEvent = SessionEvent> = (payload: SessionEventPayloads[E]) => void;
|
|
2761
|
+
declare class SessionEventEmitter {
|
|
2762
|
+
private listeners;
|
|
2763
|
+
/**
|
|
2764
|
+
* Register an event handler.
|
|
2765
|
+
*/
|
|
2766
|
+
on<E extends SessionEvent>(event: E, handler: SessionEventHandler<E>): void;
|
|
2767
|
+
/**
|
|
2768
|
+
* Remove a previously registered event handler.
|
|
2769
|
+
*/
|
|
2770
|
+
off<E extends SessionEvent>(event: E, handler: SessionEventHandler<E>): void;
|
|
2771
|
+
/**
|
|
2772
|
+
* Remove all handlers for a specific event.
|
|
2773
|
+
*/
|
|
2774
|
+
removeAllListeners(event?: SessionEvent): void;
|
|
2775
|
+
/**
|
|
2776
|
+
* Emit an event to all registered handlers.
|
|
2777
|
+
* Errors in handlers are caught and logged to prevent cascading failures.
|
|
2778
|
+
*/
|
|
2779
|
+
protected emit<E extends SessionEvent>(event: E, payload: SessionEventPayloads[E]): void;
|
|
2780
|
+
}
|
|
2781
|
+
|
|
2782
|
+
/**
|
|
2783
|
+
* Session Persistence
|
|
2784
|
+
*
|
|
2785
|
+
* Extends LocalStorageSessionStorage to persist ChainSession data
|
|
2786
|
+
* alongside the wallet session, enabling multi-chain state recovery
|
|
2787
|
+
* across page reloads.
|
|
2788
|
+
*
|
|
2789
|
+
* @see SRS-009 §9
|
|
2790
|
+
*/
|
|
2791
|
+
|
|
2792
|
+
declare class SessionPersistence {
|
|
2793
|
+
private adapter;
|
|
2794
|
+
private key;
|
|
2795
|
+
/**
|
|
2796
|
+
* @param key - Storage key for the persisted data.
|
|
2797
|
+
* @param adapter - Optional custom storage adapter. Defaults to LocalStorageAdapter.
|
|
2798
|
+
*/
|
|
2799
|
+
constructor(key?: string, adapter?: StorageAdapter);
|
|
2800
|
+
/**
|
|
2801
|
+
* Return whether the backing storage is available.
|
|
2802
|
+
*/
|
|
2803
|
+
isAvailable(): boolean;
|
|
2804
|
+
/**
|
|
2805
|
+
* Load the persisted session data.
|
|
2806
|
+
* Returns null if no data is found or parsing fails.
|
|
2807
|
+
*/
|
|
2808
|
+
load(): Promise<PersistedSessionData | null>;
|
|
2809
|
+
/**
|
|
2810
|
+
* Save session data to persistent storage.
|
|
2811
|
+
*/
|
|
2812
|
+
save(data: PersistedSessionData): Promise<void>;
|
|
2813
|
+
/**
|
|
2814
|
+
* Clear persisted session data.
|
|
2815
|
+
*/
|
|
2816
|
+
clear(): Promise<void>;
|
|
2817
|
+
/**
|
|
2818
|
+
* Serialize an ActiveSessionBundle to PersistedSessionData.
|
|
2819
|
+
* Converts the Map to a Record for JSON compatibility.
|
|
2820
|
+
*/
|
|
2821
|
+
serializeBundle(bundle: ActiveSessionBundle): PersistedSessionData;
|
|
2822
|
+
/**
|
|
2823
|
+
* Deserialize PersistedSessionData back to a bundle structure.
|
|
2824
|
+
* Returns null if the wallet session has expired.
|
|
2825
|
+
*/
|
|
2826
|
+
deserializeToBundle(data: PersistedSessionData): ActiveSessionBundle | null;
|
|
2827
|
+
}
|
|
2828
|
+
/**
|
|
2829
|
+
* Create a SessionPersistence instance.
|
|
2830
|
+
*/
|
|
2831
|
+
declare function createSessionPersistence(key?: string, adapter?: StorageAdapter): SessionPersistence;
|
|
2832
|
+
|
|
2833
|
+
/**
|
|
2834
|
+
* SessionManager
|
|
2835
|
+
*
|
|
2836
|
+
* Unified multi-chain session management system.
|
|
2837
|
+
* Wraps ConnectorManager to add chain-aware session lifecycle,
|
|
2838
|
+
* fee estimation sync, event emission, and persistence.
|
|
2839
|
+
*
|
|
2840
|
+
* @see SRS-009 §3-6
|
|
2841
|
+
*/
|
|
2842
|
+
|
|
2843
|
+
declare class SessionManager extends SessionEventEmitter {
|
|
2844
|
+
private connectorManager;
|
|
2845
|
+
private bundles;
|
|
2846
|
+
private activeBundleId;
|
|
2847
|
+
private userFeeOverrides;
|
|
2848
|
+
private config;
|
|
2849
|
+
private persistence;
|
|
2850
|
+
constructor(connectorManager: ConnectorManager, config?: SessionManagerConfig);
|
|
2851
|
+
/**
|
|
2852
|
+
* Connect to a wallet on a specific chain.
|
|
2853
|
+
* Delegates to the connector's connect method and wraps the result
|
|
2854
|
+
* in an ActiveSessionBundle.
|
|
2855
|
+
*/
|
|
2856
|
+
connect(walletType: string, chainId: string, input?: unknown): Promise<ActiveSessionBundle>;
|
|
2857
|
+
/**
|
|
2858
|
+
* Switch the active chain for the current session.
|
|
2859
|
+
* Delegates to the appropriate connector's switchChain method.
|
|
2860
|
+
* After successful switch, auto-refreshes fee estimation.
|
|
2861
|
+
*/
|
|
2862
|
+
switchChain(chainId: string): Promise<void>;
|
|
2863
|
+
/**
|
|
2864
|
+
* Disconnect the active session.
|
|
2865
|
+
* Cleans up all chain sessions and clears storage.
|
|
2866
|
+
*/
|
|
2867
|
+
disconnect(): Promise<void>;
|
|
2868
|
+
/**
|
|
2869
|
+
* Disconnect a specific chain session within the active bundle.
|
|
2870
|
+
* Does not disconnect the entire wallet.
|
|
2871
|
+
*/
|
|
2872
|
+
disconnectChain(chainId: string): Promise<void>;
|
|
2873
|
+
/**
|
|
2874
|
+
* Get the active chain session.
|
|
2875
|
+
*/
|
|
2876
|
+
getActiveChainSession(): ChainSession | undefined;
|
|
2877
|
+
/**
|
|
2878
|
+
* Get all active chain sessions across all connected bundles.
|
|
2879
|
+
*/
|
|
2880
|
+
getAllChainSessions(): ChainSession[];
|
|
2881
|
+
/**
|
|
2882
|
+
* Get all active session bundles.
|
|
2883
|
+
*/
|
|
2884
|
+
getAllActiveSessions(): ActiveSessionBundle[];
|
|
2885
|
+
/**
|
|
2886
|
+
* Get the currently active session bundle.
|
|
2887
|
+
*/
|
|
2888
|
+
getActiveBundle(): ActiveSessionBundle | null;
|
|
2889
|
+
/**
|
|
2890
|
+
* Refresh fee estimation for a specific chain.
|
|
2891
|
+
* Called automatically on switchChain if autoRefreshFeeOnSwitch is enabled.
|
|
2892
|
+
*/
|
|
2893
|
+
refreshFees(chainId?: string, options?: RefreshFeesOptions): Promise<FeeValues | null>;
|
|
2894
|
+
/**
|
|
2895
|
+
* Set user fee overrides for a specific chain.
|
|
2896
|
+
* Overrides are preserved across chain switches.
|
|
2897
|
+
*/
|
|
2898
|
+
setUserFeeOverrides(chainId: string, overrides: Partial<UserFeeOverrides[string]>): void;
|
|
2899
|
+
/**
|
|
2900
|
+
* Get the current user fee overrides for a specific chain.
|
|
2901
|
+
*/
|
|
2902
|
+
getUserFeeOverrides(chainId: string): UserFeeOverrides[string] | undefined;
|
|
2903
|
+
/**
|
|
2904
|
+
* Clear user fee overrides for a specific chain.
|
|
2905
|
+
*/
|
|
2906
|
+
clearUserFeeOverrides(chainId?: string): void;
|
|
2907
|
+
/**
|
|
2908
|
+
* Attempt to restore a session from persistence.
|
|
2909
|
+
* Returns true if a session was restored, false otherwise.
|
|
2910
|
+
*/
|
|
2911
|
+
restoreFromPersistence(): Promise<boolean>;
|
|
2912
|
+
on<E extends SessionEvent>(event: E, handler: SessionEventHandler<E>): void;
|
|
2913
|
+
off<E extends SessionEvent>(event: E, handler: SessionEventHandler<E>): void;
|
|
2914
|
+
/**
|
|
2915
|
+
* Build a bundle from a wallet session, marking the given chain as active.
|
|
2916
|
+
*/
|
|
2917
|
+
private buildBundle;
|
|
2918
|
+
/**
|
|
2919
|
+
* Create a ChainSession for the given chain ID.
|
|
2920
|
+
* Resolves RPC URL, native currency, and block explorer from config
|
|
2921
|
+
* or defaults.
|
|
2922
|
+
*/
|
|
2923
|
+
private createChainSession;
|
|
2924
|
+
/**
|
|
2925
|
+
* Update the UniversalWalletSession namespaces to reflect
|
|
2926
|
+
* the current active chain.
|
|
2927
|
+
*/
|
|
2928
|
+
private updateSessionNamespace;
|
|
2929
|
+
/**
|
|
2930
|
+
* Resolve the appropriate connector for a given wallet session.
|
|
2931
|
+
*/
|
|
2932
|
+
private resolveConnector;
|
|
2933
|
+
/**
|
|
2934
|
+
* Get a unique bundle ID from a wallet session.
|
|
2935
|
+
*/
|
|
2936
|
+
private getBundleId;
|
|
2937
|
+
/**
|
|
2938
|
+
* Persist the active bundle to storage.
|
|
2939
|
+
*/
|
|
2940
|
+
private persistBundle;
|
|
2941
|
+
}
|
|
2942
|
+
/**
|
|
2943
|
+
* Create a SessionManager instance.
|
|
2944
|
+
*/
|
|
2945
|
+
declare function createSessionManager(connectorManager: ConnectorManager, config?: SessionManagerConfig): SessionManager;
|
|
2946
|
+
|
|
2947
|
+
/**
|
|
2948
|
+
* Transaction Simulation — Core Type Definitions
|
|
2949
|
+
*
|
|
2950
|
+
* Defines the shapes for:
|
|
2951
|
+
* - SimulationResult: what a simulation yields
|
|
2952
|
+
* - BalanceChange / ApprovalChange: predicted state changes
|
|
2953
|
+
* - RiskAssessment / RiskWarning: security scoring
|
|
2954
|
+
* - GasInfo: fee estimation from simulation
|
|
2955
|
+
* - TransactionRequest: minimal tx descriptor for simulation
|
|
2956
|
+
*
|
|
2957
|
+
* @see /docs/features/transaction-simulation.md
|
|
2958
|
+
*/
|
|
2959
|
+
type SimulationProviderName = "eth_call" | "blowfish" | "tenderly" | "auto";
|
|
2960
|
+
type SimulationStatus = "success" | "reverted" | "unavailable";
|
|
2961
|
+
interface SimulationResult {
|
|
2962
|
+
/** Whether the simulation completed, reverted, or was unavailable */
|
|
2963
|
+
status: SimulationStatus;
|
|
2964
|
+
/** Revert reason (when status === "reverted") */
|
|
2965
|
+
revertReason?: string;
|
|
2966
|
+
/** Predicted balance changes from the simulation */
|
|
2967
|
+
balanceChanges: BalanceChange[];
|
|
2968
|
+
/** Predicted approval changes from the simulation */
|
|
2969
|
+
approvalChanges: ApprovalChange[];
|
|
2970
|
+
/** Risk assessment of the simulated transaction */
|
|
2971
|
+
riskAssessment: RiskAssessment;
|
|
2972
|
+
/** Gas estimation details */
|
|
2973
|
+
gasInfo?: GasInfo;
|
|
2974
|
+
/** Which provider produced this result */
|
|
2975
|
+
provider: SimulationProviderName;
|
|
2976
|
+
/** Human-readable summary of the simulation */
|
|
2977
|
+
summary?: string;
|
|
2978
|
+
/** Whether the simulation detected any state changes */
|
|
2979
|
+
changesDetected: boolean;
|
|
2980
|
+
/** Raw provider response (for debugging / transparency) */
|
|
2981
|
+
raw?: unknown;
|
|
2982
|
+
}
|
|
2983
|
+
interface BalanceChange {
|
|
2984
|
+
/** Token contract address (zero address for native gas token) */
|
|
2985
|
+
tokenAddress: `0x${string}`;
|
|
2986
|
+
/** Token symbol (e.g. "USDC", "ETH") */
|
|
2987
|
+
tokenSymbol: string;
|
|
2988
|
+
/** Number of decimals for display */
|
|
2989
|
+
tokenDecimals: number;
|
|
2990
|
+
/** Raw change amount in smallest unit (stringified bigint) */
|
|
2991
|
+
amount: string;
|
|
2992
|
+
/** Direction of the balance change */
|
|
2993
|
+
direction: "in" | "out";
|
|
2994
|
+
/** Source address */
|
|
2995
|
+
from: `0x${string}`;
|
|
2996
|
+
/** Destination address */
|
|
2997
|
+
to: `0x${string}`;
|
|
2998
|
+
/** Human-readable representation (e.g. "-1.5 USDC") */
|
|
2999
|
+
humanReadable: string;
|
|
3000
|
+
}
|
|
3001
|
+
interface ApprovalChange {
|
|
3002
|
+
/** Token contract address */
|
|
3003
|
+
tokenAddress: `0x${string}`;
|
|
3004
|
+
/** Token symbol */
|
|
3005
|
+
tokenSymbol: string;
|
|
3006
|
+
/** Owner (usually the user address) */
|
|
3007
|
+
owner: `0x${string}`;
|
|
3008
|
+
/** Spender (contract being approved) */
|
|
3009
|
+
spender: `0x${string}`;
|
|
3010
|
+
/** Approval amount in smallest unit (stringified bigint) */
|
|
3011
|
+
amount: string;
|
|
3012
|
+
/** Whether this is an unlimited approval (type(uint256).max) */
|
|
3013
|
+
isUnlimited: boolean;
|
|
3014
|
+
/** Human-readable description */
|
|
3015
|
+
humanReadable: string;
|
|
3016
|
+
}
|
|
3017
|
+
type RiskLevel = "safe" | "warning" | "malicious" | "unknown";
|
|
3018
|
+
type RiskWarningCategory = "phishing" | "unlimited_approval" | "high_value" | "unknown_contract" | "malicious_domain" | "simulation_failed" | "other";
|
|
3019
|
+
type RiskWarningSeverity = "low" | "medium" | "high" | "critical";
|
|
3020
|
+
interface RiskAssessment {
|
|
3021
|
+
/** Aggregated risk level */
|
|
3022
|
+
level: RiskLevel;
|
|
3023
|
+
/** Numeric score 0–100 (higher = more dangerous) */
|
|
3024
|
+
score: number;
|
|
3025
|
+
/** Individual warnings that contributed to the score */
|
|
3026
|
+
warnings: RiskWarning[];
|
|
3027
|
+
}
|
|
3028
|
+
interface RiskWarning {
|
|
3029
|
+
/** Classification category */
|
|
3030
|
+
category: RiskWarningCategory;
|
|
3031
|
+
/** Severity level */
|
|
3032
|
+
severity: RiskWarningSeverity;
|
|
3033
|
+
/** Human-readable warning message */
|
|
3034
|
+
message: string;
|
|
3035
|
+
}
|
|
3036
|
+
interface GasInfo {
|
|
3037
|
+
/** Estimated gas limit */
|
|
3038
|
+
gasLimit: bigint;
|
|
3039
|
+
/** Estimated gas price in wei */
|
|
3040
|
+
gasPrice?: bigint;
|
|
3041
|
+
/** Predicted total gas fee in ETH (stringified) */
|
|
3042
|
+
estimatedFeeEth?: string;
|
|
3043
|
+
/** Predicted total gas fee in USD */
|
|
3044
|
+
estimatedFeeUsd?: string;
|
|
3045
|
+
}
|
|
3046
|
+
interface TransactionDescriptor {
|
|
3047
|
+
/** Target contract / recipient address */
|
|
3048
|
+
to: `0x${string}`;
|
|
3049
|
+
/** Call data (ABI-encoded function call) */
|
|
3050
|
+
data: `0x${string}`;
|
|
3051
|
+
/** Value in wei (stringified hex with 0x prefix) */
|
|
3052
|
+
value: string;
|
|
3053
|
+
/** Sender address */
|
|
3054
|
+
from?: `0x${string}`;
|
|
3055
|
+
/** Gas limit override (optional) */
|
|
3056
|
+
gas?: string;
|
|
3057
|
+
}
|
|
3058
|
+
interface SimulationConfig {
|
|
3059
|
+
/** Blowfish API key (optional; enables Blowfish provider) */
|
|
3060
|
+
blowfishApiKey?: string;
|
|
3061
|
+
/** Default provider to use (default: "auto") */
|
|
3062
|
+
defaultProvider?: SimulationProviderName;
|
|
3063
|
+
/** Whether simulation is enabled globally (default: true) */
|
|
3064
|
+
enabled?: boolean;
|
|
3065
|
+
/** Custom RPC URL for eth_call provider */
|
|
3066
|
+
rpcUrl?: string;
|
|
3067
|
+
}
|
|
3068
|
+
|
|
3069
|
+
/**
|
|
3070
|
+
* SimulationProvider — Abstract interface for simulation backends.
|
|
3071
|
+
*
|
|
3072
|
+
* All simulation providers (eth_call, Blowfish, Tenderly) implement
|
|
3073
|
+
* this interface so they can be swapped transparently by SimulationManager.
|
|
3074
|
+
*
|
|
3075
|
+
* @see /docs/features/transaction-simulation.md §6.4
|
|
3076
|
+
*/
|
|
3077
|
+
|
|
3078
|
+
interface SimulationProvider {
|
|
3079
|
+
/** Human-readable provider name */
|
|
3080
|
+
readonly name: SimulationProviderName;
|
|
3081
|
+
/** Chain IDs this provider supports (empty = all EVM) */
|
|
3082
|
+
readonly supportedChains: number[];
|
|
3083
|
+
/**
|
|
3084
|
+
* Simulate a transaction and return the result.
|
|
3085
|
+
*
|
|
3086
|
+
* @param tx - The transaction to simulate
|
|
3087
|
+
* @param from - The sender address
|
|
3088
|
+
* @param options - Optional.origin (dApp URL for phishing detection)
|
|
3089
|
+
* and optional.rpcUrl (override for eth_call provider)
|
|
3090
|
+
*/
|
|
3091
|
+
simulate(tx: TransactionDescriptor, from: `0x${string}`, options?: {
|
|
3092
|
+
origin?: string;
|
|
3093
|
+
rpcUrl?: string;
|
|
3094
|
+
}): Promise<SimulationResult>;
|
|
3095
|
+
/**
|
|
3096
|
+
* Check whether this provider is available for the given chain.
|
|
3097
|
+
*/
|
|
3098
|
+
isAvailable(chainId: number): boolean;
|
|
3099
|
+
}
|
|
3100
|
+
|
|
3101
|
+
/**
|
|
3102
|
+
* BlowfishProvider — Blowfish API integration for transaction simulation
|
|
3103
|
+
* and security scanning.
|
|
3104
|
+
*
|
|
3105
|
+
* This is an **adapter stub** (Layer 2 / P1). When configured with an
|
|
3106
|
+
* API key, it provides:
|
|
3107
|
+
* - Full balance change detection
|
|
3108
|
+
* - Human-readable simulation summaries
|
|
3109
|
+
* - Risk scoring (suggestedAction: NONE / WARN / BLOCK)
|
|
3110
|
+
* - Phishing detection
|
|
3111
|
+
*
|
|
3112
|
+
* Implementation notes:
|
|
3113
|
+
* - API key is provided by the wallet host (not end-user)
|
|
3114
|
+
* - Falls back to basic simulation on rate-limit / 500
|
|
3115
|
+
* - Sensitive transaction data is sent to Blowfish servers
|
|
3116
|
+
*
|
|
3117
|
+
* @see https://docs.blowfish.xyz
|
|
3118
|
+
* @see /docs/features/transaction-simulation.md §5.2
|
|
3119
|
+
*/
|
|
3120
|
+
|
|
3121
|
+
declare class BlowfishProvider implements SimulationProvider {
|
|
3122
|
+
readonly name: SimulationProviderName;
|
|
3123
|
+
readonly supportedChains: number[];
|
|
3124
|
+
private apiKey;
|
|
3125
|
+
constructor(apiKey: string);
|
|
3126
|
+
simulate(tx: TransactionDescriptor, from: `0x${string}`, options?: {
|
|
3127
|
+
origin?: string;
|
|
3128
|
+
rpcUrl?: string;
|
|
3129
|
+
}): Promise<SimulationResult>;
|
|
3130
|
+
isAvailable(chainId: number): boolean;
|
|
3131
|
+
/**
|
|
3132
|
+
* Best-effort infer chain ID from origin or other context.
|
|
3133
|
+
* Defaults to 1 (Ethereum mainnet).
|
|
3134
|
+
*/
|
|
3135
|
+
private _inferChainId;
|
|
3136
|
+
}
|
|
3137
|
+
|
|
3138
|
+
/**
|
|
3139
|
+
* EthCallProvider — Basic simulation using the eth_call RPC method.
|
|
3140
|
+
*
|
|
3141
|
+
* Provides Layer 1 (P0) simulation: checks for revert, returns revert
|
|
3142
|
+
* reason if the transaction would fail. Cannot resolve balance changes,
|
|
3143
|
+
* approval changes, or risk scores since eth_call only returns the
|
|
3144
|
+
* function output, not state diffs.
|
|
3145
|
+
*
|
|
3146
|
+
* Uses raw fetch to call JSON-RPC (no ethers/viem dependency).
|
|
3147
|
+
*
|
|
3148
|
+
* @see /docs/features/transaction-simulation.md §5.1
|
|
3149
|
+
*/
|
|
3150
|
+
|
|
3151
|
+
declare class EthCallProvider implements SimulationProvider {
|
|
3152
|
+
readonly name: SimulationProviderName;
|
|
3153
|
+
readonly supportedChains: number[];
|
|
3154
|
+
private defaultRpcUrl?;
|
|
3155
|
+
constructor(defaultRpcUrl?: string);
|
|
3156
|
+
/**
|
|
3157
|
+
* Simulate a transaction via eth_call.
|
|
3158
|
+
*
|
|
3159
|
+
* eth_call returns only the function return data — it does not expose
|
|
3160
|
+
* state diffs. Therefore this provider can only determine:
|
|
3161
|
+
* - Is the transaction going to revert?
|
|
3162
|
+
* - What is the revert reason?
|
|
3163
|
+
*
|
|
3164
|
+
* It CANNOT resolve balance changes or approval changes.
|
|
3165
|
+
*/
|
|
3166
|
+
simulate(tx: TransactionDescriptor, from: `0x${string}`, options?: {
|
|
3167
|
+
origin?: string;
|
|
3168
|
+
rpcUrl?: string;
|
|
3169
|
+
}): Promise<SimulationResult>;
|
|
3170
|
+
isAvailable(_chainId: number): boolean;
|
|
3171
|
+
/**
|
|
3172
|
+
* Attempt to infer chain ID from the RPC URL (best-effort).
|
|
3173
|
+
* Returns 0 if unknown.
|
|
3174
|
+
*/
|
|
3175
|
+
private _extractChainId;
|
|
3176
|
+
}
|
|
3177
|
+
|
|
3178
|
+
/**
|
|
3179
|
+
* Token Configuration — uniquely identifies an ERC-20 token on a specific chain.
|
|
3180
|
+
*/
|
|
3181
|
+
interface TokenConfig {
|
|
3182
|
+
/** ERC-20 token contract address */
|
|
3183
|
+
address: `0x${string}`;
|
|
3184
|
+
/** Chain ID (decimal, e.g. 1 for Ethereum) */
|
|
3185
|
+
chainId: number;
|
|
3186
|
+
/** Optional cached decimals (skip RPC call when provided) */
|
|
3187
|
+
decimals?: number;
|
|
3188
|
+
}
|
|
3189
|
+
/**
|
|
3190
|
+
* Token Metadata — fetched on-chain via name(), symbol(), decimals(), totalSupply().
|
|
3191
|
+
*/
|
|
3192
|
+
interface TokenInfo {
|
|
3193
|
+
name: string;
|
|
3194
|
+
symbol: string;
|
|
3195
|
+
decimals: number;
|
|
3196
|
+
totalSupply: bigint;
|
|
3197
|
+
}
|
|
3198
|
+
/**
|
|
3199
|
+
* Parameters for building an ERC-20 transfer transaction.
|
|
3200
|
+
*/
|
|
3201
|
+
interface ERC20TransferTxParams {
|
|
3202
|
+
token: TokenConfig;
|
|
3203
|
+
from: `0x${string}`;
|
|
3204
|
+
to: `0x${string}`;
|
|
3205
|
+
/** Amount in human-readable units (e.g. "1.50" for 1.5 USDC) */
|
|
3206
|
+
amount: string | bigint;
|
|
3207
|
+
}
|
|
3208
|
+
/**
|
|
3209
|
+
* Parameters for building an ERC-20 approve transaction.
|
|
3210
|
+
*/
|
|
3211
|
+
interface ERC20ApproveTxParams {
|
|
3212
|
+
token: TokenConfig;
|
|
3213
|
+
owner: `0x${string}`;
|
|
3214
|
+
spender: `0x${string}`;
|
|
3215
|
+
amount: string | bigint;
|
|
3216
|
+
}
|
|
3217
|
+
/**
|
|
3218
|
+
* Parameters for building an ERC-20 transferFrom transaction.
|
|
3219
|
+
*/
|
|
3220
|
+
interface ERC20TransferFromTxParams {
|
|
3221
|
+
token: TokenConfig;
|
|
3222
|
+
from: `0x${string}`;
|
|
3223
|
+
to: `0x${string}`;
|
|
3224
|
+
amount: string | bigint;
|
|
3225
|
+
}
|
|
3226
|
+
/**
|
|
3227
|
+
* RPC call options — useful for overriding the default RPC URL.
|
|
3228
|
+
*/
|
|
3229
|
+
interface ERC20CallOptions {
|
|
3230
|
+
/** Override RPC URL (default: derived from chainId via config) */
|
|
3231
|
+
rpcUrl?: string;
|
|
3232
|
+
}
|
|
3233
|
+
|
|
3234
|
+
/**
|
|
3235
|
+
* SimulationManager — Central orchestrator for transaction simulation.
|
|
3236
|
+
*
|
|
3237
|
+
* Dispatches simulation requests to the appropriate provider based on
|
|
3238
|
+
* configuration and chain support. Handles:
|
|
3239
|
+
* - Provider selection (auto / eth_call / blowfish)
|
|
3240
|
+
* - Graceful fallback when a provider is unavailable
|
|
3241
|
+
* - Convenience methods like simulateERC20Transfer
|
|
3242
|
+
*
|
|
3243
|
+
* Integration points:
|
|
3244
|
+
* - wallet-engine: PocketWallet.simulateTransaction()
|
|
3245
|
+
* - Token helper (SRS-007): Builds calldata for ERC-20 transfers
|
|
3246
|
+
* - TxMonitor (SRS-008): Compares simulation vs actual results
|
|
3247
|
+
*
|
|
3248
|
+
* @see /docs/features/transaction-simulation.md §6.3
|
|
3249
|
+
*/
|
|
3250
|
+
|
|
3251
|
+
declare class SimulationManager {
|
|
3252
|
+
private providers;
|
|
3253
|
+
private _defaultProvider;
|
|
3254
|
+
private _enabled;
|
|
3255
|
+
private blowfishApiKey?;
|
|
3256
|
+
constructor(config?: SimulationConfig);
|
|
3257
|
+
/**
|
|
3258
|
+
* Main simulation entry point.
|
|
3259
|
+
*
|
|
3260
|
+
* Routes to the best available provider based on config and chain support.
|
|
3261
|
+
* Falls back to eth_call if Blowfish is unavailable for the chain.
|
|
3262
|
+
*
|
|
3263
|
+
* @param tx - Transaction to simulate
|
|
3264
|
+
* @param from - Sender address
|
|
3265
|
+
* @param options - Optional chainId, rpcUrl, origin
|
|
3266
|
+
*/
|
|
3267
|
+
simulate(tx: TransactionDescriptor, from: `0x${string}`, options?: {
|
|
3268
|
+
chainId?: number;
|
|
3269
|
+
origin?: string;
|
|
3270
|
+
rpcUrl?: string;
|
|
3271
|
+
}): Promise<SimulationResult>;
|
|
3272
|
+
/**
|
|
3273
|
+
* Convenience: simulate an ERC-20 token transfer.
|
|
3274
|
+
*
|
|
3275
|
+
* Builds the transfer calldata using ERC20TokenHelper (SRS-007),
|
|
3276
|
+
* then runs the simulation.
|
|
3277
|
+
*
|
|
3278
|
+
* @param token - Token to transfer
|
|
3279
|
+
* @param from - Sender address
|
|
3280
|
+
* @param to - Recipient address
|
|
3281
|
+
* @param amount - Amount in human-readable units (e.g. "1.50")
|
|
3282
|
+
* @param chainId - Chain ID
|
|
3283
|
+
*/
|
|
3284
|
+
simulateERC20Transfer(token: TokenConfig, from: `0x${string}`, to: `0x${string}`, amount: string, chainId: number): Promise<SimulationResult>;
|
|
3285
|
+
/**
|
|
3286
|
+
* Check whether simulation is available for a given chain.
|
|
3287
|
+
*/
|
|
3288
|
+
isAvailable(chainId: number): boolean;
|
|
3289
|
+
/**
|
|
3290
|
+
* Enable or disable simulation globally.
|
|
3291
|
+
*/
|
|
3292
|
+
setEnabled(enabled: boolean): void;
|
|
3293
|
+
/**
|
|
3294
|
+
* Get whether simulation is currently enabled.
|
|
3295
|
+
*/
|
|
3296
|
+
get enabled(): boolean;
|
|
3297
|
+
/**
|
|
3298
|
+
* Register a custom provider.
|
|
3299
|
+
* Useful for testing or third-party providers.
|
|
3300
|
+
*/
|
|
3301
|
+
registerProvider(name: SimulationProviderName, provider: SimulationProvider): void;
|
|
3302
|
+
/**
|
|
3303
|
+
* Add or update a Blowfish API key at runtime.
|
|
3304
|
+
*/
|
|
3305
|
+
setBlowfishApiKey(apiKey: string): void;
|
|
3306
|
+
/**
|
|
3307
|
+
* Remove a registered provider.
|
|
3308
|
+
*/
|
|
3309
|
+
unregisterProvider(name: SimulationProviderName): void;
|
|
3310
|
+
/**
|
|
3311
|
+
* Select the best provider for the given chain.
|
|
3312
|
+
*
|
|
3313
|
+
* Selection rules:
|
|
3314
|
+
* - "auto": Try blowfish first (if registered + chain supported),
|
|
3315
|
+
* fall back to eth_call
|
|
3316
|
+
* - "blowfish": Use blowfish if available
|
|
3317
|
+
* - "eth_call": Always available on EVM
|
|
3318
|
+
*/
|
|
3319
|
+
private _selectProvider;
|
|
3320
|
+
/**
|
|
3321
|
+
* Estimate chain ID from the from address or config.
|
|
3322
|
+
* Best-effort; returns 0 if unknown.
|
|
3323
|
+
*/
|
|
3324
|
+
private _estimateChainId;
|
|
3325
|
+
/**
|
|
3326
|
+
* Resolve an RPC URL for the eth_call fallback provider.
|
|
3327
|
+
*/
|
|
3328
|
+
private _resolveRpcUrl;
|
|
3329
|
+
}
|
|
3330
|
+
/**
|
|
3331
|
+
* Compare simulation results with actual transaction receipt.
|
|
3332
|
+
*
|
|
3333
|
+
* Used by TxMonitor to detect discrepancies between simulated and
|
|
3334
|
+
* actual transaction outcomes.
|
|
3335
|
+
*
|
|
3336
|
+
* @param simulation - The simulation result
|
|
3337
|
+
* @param actualStatus - Actual tx receipt status ("success" | "reverted")
|
|
3338
|
+
* @returns Match result
|
|
3339
|
+
*/
|
|
3340
|
+
declare function compareSimulationVsActual(simulation: SimulationResult, actualStatus: "success" | "reverted"): {
|
|
3341
|
+
match: boolean;
|
|
3342
|
+
discrepancies?: string[];
|
|
3343
|
+
};
|
|
3344
|
+
|
|
3345
|
+
/** Full minimal ABI as const for viem compatibility */
|
|
3346
|
+
declare const ERC20_MIN_ABI: readonly [{
|
|
3347
|
+
readonly name: "transfer";
|
|
3348
|
+
readonly type: "function";
|
|
3349
|
+
readonly stateMutability: "nonpayable";
|
|
3350
|
+
readonly inputs: readonly [{
|
|
3351
|
+
readonly name: "to";
|
|
3352
|
+
readonly type: "address";
|
|
3353
|
+
}, {
|
|
3354
|
+
readonly name: "amount";
|
|
3355
|
+
readonly type: "uint256";
|
|
3356
|
+
}];
|
|
3357
|
+
readonly outputs: readonly [{
|
|
3358
|
+
readonly name: "success";
|
|
3359
|
+
readonly type: "bool";
|
|
3360
|
+
}];
|
|
3361
|
+
}, {
|
|
3362
|
+
readonly name: "approve";
|
|
3363
|
+
readonly type: "function";
|
|
3364
|
+
readonly stateMutability: "nonpayable";
|
|
3365
|
+
readonly inputs: readonly [{
|
|
3366
|
+
readonly name: "spender";
|
|
3367
|
+
readonly type: "address";
|
|
3368
|
+
}, {
|
|
3369
|
+
readonly name: "amount";
|
|
3370
|
+
readonly type: "uint256";
|
|
3371
|
+
}];
|
|
3372
|
+
readonly outputs: readonly [{
|
|
3373
|
+
readonly name: "success";
|
|
3374
|
+
readonly type: "bool";
|
|
3375
|
+
}];
|
|
3376
|
+
}, {
|
|
3377
|
+
readonly name: "transferFrom";
|
|
3378
|
+
readonly type: "function";
|
|
3379
|
+
readonly stateMutability: "nonpayable";
|
|
3380
|
+
readonly inputs: readonly [{
|
|
3381
|
+
readonly name: "from";
|
|
3382
|
+
readonly type: "address";
|
|
3383
|
+
}, {
|
|
3384
|
+
readonly name: "to";
|
|
3385
|
+
readonly type: "address";
|
|
3386
|
+
}, {
|
|
3387
|
+
readonly name: "amount";
|
|
3388
|
+
readonly type: "uint256";
|
|
3389
|
+
}];
|
|
3390
|
+
readonly outputs: readonly [{
|
|
3391
|
+
readonly name: "success";
|
|
3392
|
+
readonly type: "bool";
|
|
3393
|
+
}];
|
|
3394
|
+
}, {
|
|
3395
|
+
readonly name: "allowance";
|
|
3396
|
+
readonly type: "function";
|
|
3397
|
+
readonly stateMutability: "view";
|
|
3398
|
+
readonly inputs: readonly [{
|
|
3399
|
+
readonly name: "owner";
|
|
3400
|
+
readonly type: "address";
|
|
3401
|
+
}, {
|
|
3402
|
+
readonly name: "spender";
|
|
3403
|
+
readonly type: "address";
|
|
3404
|
+
}];
|
|
3405
|
+
readonly outputs: readonly [{
|
|
3406
|
+
readonly name: "remaining";
|
|
3407
|
+
readonly type: "uint256";
|
|
3408
|
+
}];
|
|
3409
|
+
}, {
|
|
3410
|
+
readonly name: "balanceOf";
|
|
3411
|
+
readonly type: "function";
|
|
3412
|
+
readonly stateMutability: "view";
|
|
3413
|
+
readonly inputs: readonly [{
|
|
3414
|
+
readonly name: "owner";
|
|
3415
|
+
readonly type: "address";
|
|
3416
|
+
}];
|
|
3417
|
+
readonly outputs: readonly [{
|
|
3418
|
+
readonly name: "balance";
|
|
3419
|
+
readonly type: "uint256";
|
|
3420
|
+
}];
|
|
3421
|
+
}, {
|
|
3422
|
+
readonly name: "decimals";
|
|
3423
|
+
readonly type: "function";
|
|
3424
|
+
readonly stateMutability: "view";
|
|
3425
|
+
readonly inputs: readonly [];
|
|
3426
|
+
readonly outputs: readonly [{
|
|
3427
|
+
readonly name: "decimals";
|
|
3428
|
+
readonly type: "uint8";
|
|
3429
|
+
}];
|
|
3430
|
+
}, {
|
|
3431
|
+
readonly name: "symbol";
|
|
3432
|
+
readonly type: "function";
|
|
3433
|
+
readonly stateMutability: "view";
|
|
3434
|
+
readonly inputs: readonly [];
|
|
3435
|
+
readonly outputs: readonly [{
|
|
3436
|
+
readonly name: "symbol";
|
|
3437
|
+
readonly type: "string";
|
|
3438
|
+
}];
|
|
3439
|
+
}, {
|
|
3440
|
+
readonly name: "name";
|
|
3441
|
+
readonly type: "function";
|
|
3442
|
+
readonly stateMutability: "view";
|
|
3443
|
+
readonly inputs: readonly [];
|
|
3444
|
+
readonly outputs: readonly [{
|
|
3445
|
+
readonly name: "name";
|
|
3446
|
+
readonly type: "string";
|
|
3447
|
+
}];
|
|
3448
|
+
}, {
|
|
3449
|
+
readonly name: "totalSupply";
|
|
3450
|
+
readonly type: "function";
|
|
3451
|
+
readonly stateMutability: "view";
|
|
3452
|
+
readonly inputs: readonly [];
|
|
3453
|
+
readonly outputs: readonly [{
|
|
3454
|
+
readonly name: "totalSupply";
|
|
3455
|
+
readonly type: "uint256";
|
|
3456
|
+
}];
|
|
3457
|
+
}];
|
|
3458
|
+
/**
|
|
3459
|
+
* Canonical function signatures (for manual keccak256-based encoding).
|
|
3460
|
+
*/
|
|
3461
|
+
declare const ERC20_FUNCTION_SIGNATURES: {
|
|
3462
|
+
readonly transfer: "transfer(address,uint256)";
|
|
3463
|
+
readonly approve: "approve(address,uint256)";
|
|
3464
|
+
readonly transferFrom: "transferFrom(address,address,uint256)";
|
|
3465
|
+
readonly allowance: "allowance(address,address)";
|
|
3466
|
+
readonly balanceOf: "balanceOf(address)";
|
|
3467
|
+
readonly decimals: "decimals()";
|
|
3468
|
+
readonly symbol: "symbol()";
|
|
3469
|
+
readonly name: "name()";
|
|
3470
|
+
readonly totalSupply: "totalSupply()";
|
|
3471
|
+
};
|
|
3472
|
+
/**
|
|
3473
|
+
* Type helper — extract the ABI items for a given function name.
|
|
3474
|
+
*/
|
|
3475
|
+
type AbiItem<TName extends (typeof ERC20_MIN_ABI)[number]["name"]> = (typeof ERC20_MIN_ABI)[number] & {
|
|
3476
|
+
name: TName;
|
|
3477
|
+
};
|
|
3478
|
+
|
|
3479
|
+
/**
|
|
3480
|
+
* ERC20TokenHelper — ABI encoding, RPC queries, and transaction building
|
|
3481
|
+
* for ERC-20 tokens.
|
|
3482
|
+
*
|
|
3483
|
+
* Design:
|
|
3484
|
+
* - Zero dependency on viem/ethers for ABI encoding
|
|
3485
|
+
* - Uses @noble/hashes/keccak_256 (already in monorepo) for selector computation
|
|
3486
|
+
* - All methods are static (composition over inheritance)
|
|
3487
|
+
* - Transaction builder methods return raw TransactionRequest objects
|
|
3488
|
+
*
|
|
3489
|
+
* @see SRS-007
|
|
3490
|
+
*/
|
|
3491
|
+
|
|
3492
|
+
/**
|
|
3493
|
+
* ABI-encode an address: left-pad to 32 bytes.
|
|
3494
|
+
* "0xabc" → "0x0000...000abc"
|
|
3495
|
+
*/
|
|
3496
|
+
declare function abiEncodeAddress(addr: `0x${string}`): `0x${string}`;
|
|
3497
|
+
/**
|
|
3498
|
+
* ABI-encode a uint256: left-pad to 32 bytes.
|
|
3499
|
+
*/
|
|
3500
|
+
declare function abiEncodeUint256(value: bigint): `0x${string}`;
|
|
3501
|
+
/**
|
|
3502
|
+
* Compute a 4-byte function selector from a canonical function signature.
|
|
3503
|
+
*
|
|
3504
|
+
* @example
|
|
3505
|
+
* abiFunctionSelector("transfer(address,uint256)")
|
|
3506
|
+
* // → "0xa9059cbb"
|
|
3507
|
+
*/
|
|
3508
|
+
declare function abiFunctionSelector(signature: string): Promise<`0x${string}`>;
|
|
3509
|
+
/**
|
|
3510
|
+
* Full ABI function call encoding: 4-byte selector + packed args.
|
|
3511
|
+
*
|
|
3512
|
+
* @example
|
|
3513
|
+
* const data = await abiEncodeFunctionCall(
|
|
3514
|
+
* "transfer(address,uint256)",
|
|
3515
|
+
* "0xRecipientAddress...",
|
|
3516
|
+
* "0x0000...0001e240" // already-encoded uint256
|
|
3517
|
+
* );
|
|
3518
|
+
*/
|
|
3519
|
+
declare function abiEncodeFunctionCall(signature: string, ...encodedArgs: string[]): Promise<`0x${string}`>;
|
|
3520
|
+
declare class ERC20TokenHelper {
|
|
3521
|
+
/**
|
|
3522
|
+
* Build a raw ERC-20 transfer TransactionRequest.
|
|
3523
|
+
*
|
|
3524
|
+
* The returned object can be fed into PocketWallet.sendTransaction()
|
|
3525
|
+
* or signed offline.
|
|
3526
|
+
*/
|
|
3527
|
+
static buildTransferTx(params: ERC20TransferTxParams, decimals: number): Promise<{
|
|
3528
|
+
to: `0x${string}`;
|
|
3529
|
+
from: `0x${string}`;
|
|
3530
|
+
data: `0x${string}`;
|
|
3531
|
+
value: "0x0";
|
|
3532
|
+
}>;
|
|
3533
|
+
/**
|
|
3534
|
+
* Build a raw ERC-20 approve TransactionRequest.
|
|
3535
|
+
*/
|
|
3536
|
+
static buildApproveTx(params: ERC20ApproveTxParams, decimals: number): Promise<{
|
|
3537
|
+
to: `0x${string}`;
|
|
3538
|
+
from: `0x${string}`;
|
|
3539
|
+
data: `0x${string}`;
|
|
3540
|
+
value: "0x0";
|
|
3541
|
+
}>;
|
|
3542
|
+
/**
|
|
3543
|
+
* Build a raw ERC-20 transferFrom TransactionRequest.
|
|
3544
|
+
* Requires the caller to have been approved first.
|
|
3545
|
+
*/
|
|
3546
|
+
static buildTransferFromTx(params: ERC20TransferFromTxParams, decimals: number): Promise<{
|
|
3547
|
+
to: `0x${string}`;
|
|
3548
|
+
from: `0x${string}`;
|
|
3549
|
+
data: `0x${string}`;
|
|
3550
|
+
value: "0x0";
|
|
3551
|
+
}>;
|
|
3552
|
+
/**
|
|
3553
|
+
* Call allowance(address,address) on-chain.
|
|
3554
|
+
* Returns remaining allowance in smallest unit (bigint).
|
|
3555
|
+
*/
|
|
3556
|
+
static getAllowance(token: TokenConfig, owner: `0x${string}`, spender: `0x${string}`, options?: ERC20CallOptions): Promise<bigint>;
|
|
3557
|
+
/**
|
|
3558
|
+
* Fetch token metadata (name, symbol, decimals, totalSupply) from chain.
|
|
3559
|
+
* Makes 4 parallel RPC calls.
|
|
3560
|
+
*/
|
|
3561
|
+
static getTokenInfo(token: TokenConfig, options?: ERC20CallOptions): Promise<TokenInfo>;
|
|
3562
|
+
/**
|
|
3563
|
+
* Check if a token is deployed on the target chain.
|
|
3564
|
+
* Returns true if the contract has code (extcodesize > 0).
|
|
3565
|
+
*/
|
|
3566
|
+
static isTokenDeployed(token: TokenConfig, options?: ERC20CallOptions): Promise<boolean>;
|
|
3567
|
+
/**
|
|
3568
|
+
* Fetch token decimals from chain (or return cached value).
|
|
3569
|
+
*/
|
|
3570
|
+
static getDecimals(token: TokenConfig, options?: ERC20CallOptions): Promise<number>;
|
|
3571
|
+
/**
|
|
3572
|
+
* Convenience: parse a human-readable amount to raw units using the token's decimals.
|
|
3573
|
+
*/
|
|
3574
|
+
static parseToRawAmount(token: TokenConfig, amount: string | number, options?: ERC20CallOptions): Promise<bigint>;
|
|
3575
|
+
/**
|
|
3576
|
+
* Convenience: format a raw bigint amount to a human-readable string using the token's decimals.
|
|
3577
|
+
*/
|
|
3578
|
+
static formatRawAmount(token: TokenConfig, rawAmount: bigint, options?: ERC20CallOptions): Promise<string>;
|
|
3579
|
+
}
|
|
3580
|
+
|
|
3581
|
+
/**
|
|
3582
|
+
* Unified error handling for ERC-20 token operations.
|
|
3583
|
+
*
|
|
3584
|
+
* ERC20TokenError is independent of WalletError — the core package
|
|
3585
|
+
* shouldn't depend on wallet-engine. Wallet-engine integration wraps
|
|
3586
|
+
* these into WalletError when needed.
|
|
3587
|
+
*/
|
|
3588
|
+
type ERC20TokenErrorCode = "token_not_deployed" | "invalid_address" | "invalid_amount" | "insufficient_allowance" | "insufficient_balance" | "decimals_fetch_failed" | "token_info_fetch_failed" | "rpc_error" | "encoding_error" | "unknown_error";
|
|
3589
|
+
declare class ERC20TokenError extends Error {
|
|
3590
|
+
readonly code: ERC20TokenErrorCode;
|
|
3591
|
+
readonly cause?: unknown | undefined;
|
|
3592
|
+
constructor(code: ERC20TokenErrorCode, message?: string, cause?: unknown | undefined);
|
|
3593
|
+
/** Check if this error has a specific code */
|
|
3594
|
+
hasCode(code: ERC20TokenErrorCode): boolean;
|
|
3595
|
+
}
|
|
3596
|
+
/** Type guard */
|
|
3597
|
+
declare function isERC20TokenError(e: unknown): e is ERC20TokenError;
|
|
3598
|
+
|
|
3599
|
+
/**
|
|
3600
|
+
* Amount formatting utilities for ERC-20 tokens.
|
|
3601
|
+
*
|
|
3602
|
+
* Provides parseUnits (human-readable → raw bigint) and
|
|
3603
|
+
* formatUnits (raw bigint → human-readable string).
|
|
3604
|
+
*
|
|
3605
|
+
* Handles any decimal count (0–255 as per ERC-20 spec).
|
|
3606
|
+
*/
|
|
3607
|
+
/**
|
|
3608
|
+
* Convert a human-readable amount (string, number, or bigint) to the smallest unit.
|
|
3609
|
+
*
|
|
3610
|
+
* @example
|
|
3611
|
+
* parseUnits("1.5", 6) → 1500000n (USDC: 1.5 → 1,500,000)
|
|
3612
|
+
* parseUnits("0.01", 18) → 10000000000000000n
|
|
3613
|
+
* parseUnits("100", 0) → 100n
|
|
3614
|
+
*
|
|
3615
|
+
* @throws {ERC20TokenError} on invalid input
|
|
3616
|
+
*/
|
|
3617
|
+
declare function parseUnits(amount: string | number | bigint, decimals: number): bigint;
|
|
3618
|
+
/**
|
|
3619
|
+
* Convert a raw bigint amount to a human-readable decimal string.
|
|
3620
|
+
*
|
|
3621
|
+
* @example
|
|
3622
|
+
* formatUnits(1500000n, 6) → "1.5"
|
|
3623
|
+
* formatUnits(10000000000000000n, 18) → "0.01"
|
|
3624
|
+
* formatUnits(0n, 18) → "0"
|
|
3625
|
+
*/
|
|
3626
|
+
declare function formatUnits(amount: bigint, decimals: number): string;
|
|
3627
|
+
|
|
3628
|
+
/**
|
|
3629
|
+
* Token List Types — compliant with Uniswap Token List spec
|
|
3630
|
+
*
|
|
3631
|
+
* @see https://github.com/Uniswap/token-lists
|
|
3632
|
+
*/
|
|
3633
|
+
/**
|
|
3634
|
+
* Metadata for a single token.
|
|
3635
|
+
*/
|
|
3636
|
+
interface TokenListEntry {
|
|
3637
|
+
/** EVM contract address or token identifier */
|
|
3638
|
+
readonly address: string;
|
|
3639
|
+
/** Numeric chain ID (e.g. 1 for Ethereum) */
|
|
3640
|
+
readonly chainId: number;
|
|
3641
|
+
/** Human-readable name (e.g. "USD Coin") */
|
|
3642
|
+
readonly name: string;
|
|
3643
|
+
/** Ticker symbol (e.g. "USDC") */
|
|
3644
|
+
readonly symbol: string;
|
|
3645
|
+
/** Token decimals (e.g. 6 for USDC, 18 for ETH) */
|
|
3646
|
+
readonly decimals: number;
|
|
3647
|
+
/** Optional logo URL */
|
|
3648
|
+
readonly logoURI?: string;
|
|
3649
|
+
/** Optional semantic tags (e.g. ["stablecoin"]) */
|
|
3650
|
+
readonly tags?: string[];
|
|
3651
|
+
/** Optional extensions for custom metadata */
|
|
3652
|
+
readonly extensions?: Record<string, unknown>;
|
|
3653
|
+
/** Source identifier (set internally by the manager) */
|
|
3654
|
+
readonly source?: string;
|
|
3655
|
+
}
|
|
3656
|
+
/**
|
|
3657
|
+
* A token list conforming to the Uniswap Token List JSON schema.
|
|
3658
|
+
*/
|
|
3659
|
+
interface TokenList {
|
|
3660
|
+
readonly name: string;
|
|
3661
|
+
readonly timestamp: string;
|
|
3662
|
+
readonly version: {
|
|
3663
|
+
major: number;
|
|
3664
|
+
minor: number;
|
|
3665
|
+
patch: number;
|
|
3666
|
+
};
|
|
3667
|
+
readonly tokens: TokenListEntry[];
|
|
3668
|
+
readonly logoURI?: string;
|
|
3669
|
+
readonly keywords?: string[];
|
|
3670
|
+
readonly tags?: Record<string, TokenListTag>;
|
|
3671
|
+
}
|
|
3672
|
+
interface TokenListTag {
|
|
3673
|
+
readonly name: string;
|
|
3674
|
+
readonly description: string;
|
|
3675
|
+
}
|
|
3676
|
+
/**
|
|
3677
|
+
* Configuration for a single token list source.
|
|
3678
|
+
*/
|
|
3679
|
+
interface TokenListSource {
|
|
3680
|
+
/** Unique source identifier */
|
|
3681
|
+
name: string;
|
|
3682
|
+
/** Remote URL to fetch the list from */
|
|
3683
|
+
url?: string;
|
|
3684
|
+
/** Inline token array (used for built-in lists or custom tokens) */
|
|
3685
|
+
tokens?: TokenListEntry[];
|
|
3686
|
+
/** Refresh interval in ms (default 24h) */
|
|
3687
|
+
refreshInterval?: number;
|
|
3688
|
+
/** Whether this source is enabled by default */
|
|
3689
|
+
enabled: boolean;
|
|
3690
|
+
/** Optional chain filter – only tokens matching these chain IDs are kept */
|
|
3691
|
+
chainFilter?: number[];
|
|
3692
|
+
}
|
|
3693
|
+
/**
|
|
3694
|
+
* Configuration for TokenListManager.
|
|
3695
|
+
*/
|
|
3696
|
+
interface TokenListManagerConfig {
|
|
3697
|
+
/** Ordered list of token list sources */
|
|
3698
|
+
sources: TokenListSource[];
|
|
3699
|
+
/** localStorage key for caching merged results */
|
|
3700
|
+
cacheKey?: string;
|
|
3701
|
+
/** Cache TTL in ms (default 24h) */
|
|
3702
|
+
cacheTtl?: number;
|
|
3703
|
+
/** Source priority for deduplication – earlier = higher priority */
|
|
3704
|
+
sourcePriority?: string[];
|
|
3705
|
+
/** Fetch timeout per source (ms, default 10000) */
|
|
3706
|
+
fetchTimeout?: number;
|
|
3707
|
+
}
|
|
3708
|
+
/**
|
|
3709
|
+
* Status snapshot of a single source.
|
|
3710
|
+
*/
|
|
3711
|
+
interface TokenListSourceStatus {
|
|
3712
|
+
name: string;
|
|
3713
|
+
enabled: boolean;
|
|
3714
|
+
state: "loading" | "loaded" | "error";
|
|
3715
|
+
tokenCount: number;
|
|
3716
|
+
lastUpdated: number | null;
|
|
3717
|
+
error?: string;
|
|
3718
|
+
}
|
|
3719
|
+
/**
|
|
3720
|
+
* Search query parameters.
|
|
3721
|
+
*/
|
|
3722
|
+
interface TokenSearchQuery {
|
|
3723
|
+
query: string;
|
|
3724
|
+
chainId?: number;
|
|
3725
|
+
limit?: number;
|
|
3726
|
+
}
|
|
3727
|
+
/**
|
|
3728
|
+
* Result of a token search.
|
|
3729
|
+
*/
|
|
3730
|
+
interface TokenSearchResult {
|
|
3731
|
+
exact: TokenMatch[];
|
|
3732
|
+
fuzzy: TokenMatch[];
|
|
3733
|
+
hasMore: boolean;
|
|
3734
|
+
}
|
|
3735
|
+
/**
|
|
3736
|
+
* A single search match with relevance score.
|
|
3737
|
+
*/
|
|
3738
|
+
interface TokenMatch {
|
|
3739
|
+
token: TokenListEntry;
|
|
3740
|
+
score: number;
|
|
3741
|
+
matchField: "symbol" | "name" | "address";
|
|
3742
|
+
hasBalance?: boolean;
|
|
3743
|
+
balance?: string;
|
|
3744
|
+
}
|
|
3745
|
+
|
|
3746
|
+
/**
|
|
3747
|
+
* Auto-detect — fetch token metadata from chain and cache to localStorage.
|
|
3748
|
+
*
|
|
3749
|
+
* Uses ERC20TokenHelper.getTokenInfo() to retrieve name, symbol, decimals.
|
|
3750
|
+
* Results are cached in localStorage to avoid repeated RPC calls.
|
|
3751
|
+
*/
|
|
3752
|
+
|
|
3753
|
+
/**
|
|
3754
|
+
* A minimal on-chain token fetcher compatible with Node and browser.
|
|
3755
|
+
*
|
|
3756
|
+
* Makes eth_call RPC requests to invoke standard ERC-20 functions:
|
|
3757
|
+
* name(), symbol(), decimals()
|
|
3758
|
+
*/
|
|
3759
|
+
declare function detectTokenInfo(address: string, chainId: number, rpcUrl: string, options?: {
|
|
3760
|
+
skipCache?: boolean;
|
|
3761
|
+
}): Promise<TokenListEntry>;
|
|
3762
|
+
/**
|
|
3763
|
+
* Clear the auto-detect cache.
|
|
3764
|
+
*/
|
|
3765
|
+
declare function clearAutoDetectCache(): Promise<void>;
|
|
3766
|
+
|
|
3767
|
+
/**
|
|
3768
|
+
* Built-in default token lists.
|
|
3769
|
+
*
|
|
3770
|
+
* Only includes the most common tokens to keep the bundle small.
|
|
3771
|
+
* Full lists (Uniswap, Coinbase, Jupiter) are loaded from remote sources.
|
|
3772
|
+
*/
|
|
3773
|
+
|
|
3774
|
+
/**
|
|
3775
|
+
* Popular Ethereum mainnet tokens (chainId = 1).
|
|
3776
|
+
*/
|
|
3777
|
+
declare const ETHEREUM_MAINNET_TOKENS: TokenListEntry[];
|
|
3778
|
+
/**
|
|
3779
|
+
* Popular Polygon (chainId 137) tokens.
|
|
3780
|
+
*/
|
|
3781
|
+
declare const POLYGON_TOKENS: TokenListEntry[];
|
|
3782
|
+
/**
|
|
3783
|
+
* Optimism (chainId 10) tokens.
|
|
3784
|
+
*/
|
|
3785
|
+
declare const OPTIMISM_TOKENS: TokenListEntry[];
|
|
3786
|
+
/**
|
|
3787
|
+
* Arbitrum (chainId 42161) tokens.
|
|
3788
|
+
*/
|
|
3789
|
+
declare const ARBITRUM_TOKENS: TokenListEntry[];
|
|
3790
|
+
/**
|
|
3791
|
+
* Base (chainId 8453) tokens.
|
|
3792
|
+
*/
|
|
3793
|
+
declare const BASE_TOKENS: TokenListEntry[];
|
|
3794
|
+
/**
|
|
3795
|
+
* All built-in tokens aggregated by chain ID.
|
|
3796
|
+
*/
|
|
3797
|
+
declare const DEFAULT_BUILTIN_TOKENS: Record<number, TokenListEntry[]>;
|
|
3798
|
+
/**
|
|
3799
|
+
* All built-in tokens as a flat array.
|
|
3800
|
+
*/
|
|
3801
|
+
declare function getAllBuiltinTokens(): TokenListEntry[];
|
|
3802
|
+
/**
|
|
3803
|
+
* Default sources for TokenListManager.
|
|
3804
|
+
*
|
|
3805
|
+
* - Built-in (inline): always available, no network fetch needed
|
|
3806
|
+
* - Uniswap Default: loaded from remote URL on first use
|
|
3807
|
+
* - Coinbase: loaded from remote URL on first use
|
|
3808
|
+
*/
|
|
3809
|
+
declare const DEFAULT_SOURCES: TokenListSource[];
|
|
3810
|
+
|
|
3811
|
+
/**
|
|
3812
|
+
* TokenListManager — load, merge, cache, and search token lists.
|
|
3813
|
+
*
|
|
3814
|
+
* Supports multiple sources (built-in, Uniswap, Coinbase, custom).
|
|
3815
|
+
* Deduplicates by (chainId, address) with configurable source priority.
|
|
3816
|
+
* Caches merged results to localStorage.
|
|
3817
|
+
*/
|
|
3818
|
+
|
|
3819
|
+
declare class TokenListManager {
|
|
3820
|
+
private config;
|
|
3821
|
+
private tokens;
|
|
3822
|
+
private sourceStatus;
|
|
3823
|
+
private storage;
|
|
3824
|
+
constructor(config?: Partial<TokenListManagerConfig>);
|
|
3825
|
+
/**
|
|
3826
|
+
* Load all enabled sources.
|
|
3827
|
+
* Checks cache first, falls back to in-memory or failed-source stale data.
|
|
3828
|
+
*/
|
|
3829
|
+
load(): Promise<TokenListEntry[]>;
|
|
3830
|
+
/**
|
|
3831
|
+
* Force-refresh all sources, bypassing cache.
|
|
3832
|
+
*/
|
|
3833
|
+
refresh(): Promise<TokenListEntry[]>;
|
|
3834
|
+
/**
|
|
3835
|
+
* Get all loaded tokens, optionally filtered.
|
|
3836
|
+
*/
|
|
3837
|
+
getTokens(options?: {
|
|
3838
|
+
chainId?: number;
|
|
3839
|
+
source?: string;
|
|
3840
|
+
}): TokenListEntry[];
|
|
3841
|
+
/**
|
|
3842
|
+
* Search tokens by symbol, name, or address.
|
|
3843
|
+
*/
|
|
3844
|
+
search(query: string, options?: {
|
|
3845
|
+
chainId?: number;
|
|
3846
|
+
limit?: number;
|
|
3847
|
+
}): TokenSearchResult;
|
|
3848
|
+
/**
|
|
3849
|
+
* Get a single token by address and chain ID.
|
|
3850
|
+
*/
|
|
3851
|
+
getToken(address: string, chainId: number): TokenListEntry | undefined;
|
|
3852
|
+
/**
|
|
3853
|
+
* Clear all caches.
|
|
3854
|
+
*/
|
|
3855
|
+
clearCache(): void;
|
|
3856
|
+
/**
|
|
3857
|
+
* Get status of all registered sources.
|
|
3858
|
+
*/
|
|
3859
|
+
getSourcesStatus(): TokenListSourceStatus[];
|
|
3860
|
+
private fetchSource;
|
|
3861
|
+
/**
|
|
3862
|
+
* Deduplicate tokens by (chainId, address).
|
|
3863
|
+
* Source priority controls which record wins for colliding tokens.
|
|
3864
|
+
*/
|
|
3865
|
+
private deduplicate;
|
|
3866
|
+
private loadFromCache;
|
|
3867
|
+
private saveToCache;
|
|
3868
|
+
private isCacheExpired;
|
|
3869
|
+
private updateSourceStatuses;
|
|
3870
|
+
}
|
|
3871
|
+
|
|
3872
|
+
/**
|
|
3873
|
+
* Get the USD price of a native token (e.g. ETH, MATIC) by chain ID.
|
|
3874
|
+
*
|
|
3875
|
+
* This function was missing from the source but exists in the dist build.
|
|
3876
|
+
* It was added to the Ladle Vite bridge to unblock storybook-based testing.
|
|
3877
|
+
*
|
|
3878
|
+
* @param chain - EIP-155 chain ID (e.g. "eip155:1")
|
|
3879
|
+
* @param rpcUrl - Optional RPC URL for on-chain price lookup
|
|
3880
|
+
* @returns USD price as a number, or null if unavailable
|
|
3881
|
+
*/
|
|
3882
|
+
declare function getNativeTokenPriceUsd(chain: string, _rpcUrl?: string): Promise<number | null>;
|
|
3883
|
+
|
|
3884
|
+
export { type AAErrorCode, AA_ERROR_MESSAGES, AA_SUPPORTED_CHAINS, ARBITRUM_TOKENS, AUTO_RECONNECT_TIMEOUT_MS, type AbiItem, AccountAbstractionError, type AccountType, type ActiveSessionBundle, type Address, type AddressResult, type ApprovalChange, type AutoReconnectConfig, AutoReconnectManager, AxelarProvider, type AxelarProviderConfig, BASE_TOKENS, type BalanceChange, type BatchCall, BlowfishProvider, type BridgeProvider, type BridgeProviderId, type BundlerClient, CHAINS, CONNECTOR_ERROR_MESSAGES, type Call, type CallsStatus, type ChainAbstractionConfig, ChainAbstractionError, type ChainAbstractionErrorCode, type ChainFeeEstimator, type ChainFeeSupport, type ChainInfo, type ChainSession, type ChannelCapability, type ConnectorEntry, type ConnectorId, ConnectorManager, type ConnectorManagerConfig, type ConnectorSupport, type CostComparison, type CostComparisonOperation, type CostComparisonOptions, type CreateEmptySessionInput, DEFAULT_BUILTIN_TOKENS, DEFAULT_CALL_GAS_LIMIT, DEFAULT_ENTRY_POINT, DEFAULT_EVM_CHAIN, DEFAULT_NONCE_LENGTH, DEFAULT_PRE_VERIFICATION_GAS, DEFAULT_RPC_URLS, DEFAULT_SESSION_KEY_CONFIG, DEFAULT_SOLANA_CLUSTER, DEFAULT_SOURCES, DEFAULT_VERIFICATION_GAS_LIMIT, DEFAULT_XRPL_NETWORK, EIP155_ARBITRUM, EIP155_ARBITRUM_GOERLI, EIP155_BASE, EIP155_GOERLI, EIP155_MAINNET, EIP155_MUMBAI, EIP155_OPTIMISM, EIP155_OPTIMISM_GOERLI, EIP155_POLYGON, EIP155_SEPOLIA, ENSProvider, ENTRY_POINT_V0_6, ENTRY_POINT_V0_7, type ERC20ApproveTxParams, type ERC20CallOptions, ERC20TokenError, type ERC20TokenErrorCode, ERC20TokenHelper, type ERC20TransferFromTxParams, type ERC20TransferTxParams, ERC20_FUNCTION_SIGNATURES, ERC20_MIN_ABI, ETHEREUM_MAINNET_TOKENS, type EncryptedKeyPair, EthCallProvider, type ExecuteOptions, type ExecuteRouteResult, FEE_ERROR_MESSAGES, type FeeEstimationConfig, FeeEstimationError, type FeeEstimationErrorCode, type FeeTypeStrategy, type FeeValues, type FeeValuesEIP1559, type FeeValuesLegacy, type GasEstimate, type GasInfo, type Hex, InAppChannel, type InAppChannelOptions, LiFiProvider, type LiFiProviderConfig, LocalStorageAdapter, LocalStorageSessionStorage, type LogLevel, type LoggerNamespace, MemoryStorageAdapter, type MuteRule, NAMESPACE_EIP155, NAMESPACE_SOLANA, NAMESPACE_XRPL, NameResolver, type NameResolverConfig, type NameResult, type Namespace, type NamespaceCapabilities, NoopChannel, NoopStorageAdapter, type NotificationChannel, type NotificationFrequency, type NotificationItem, type NotificationPayload, type NotificationSettings, type NotificationWatch, Notifier, type NotifierOptions, OPTIMISM_TOKENS, POLYGON_TOKENS, type Paymaster, type PaymasterConfig, type PaymasterData, PaymasterService, type PaymasterServiceConfig, type PaymasterType, type PermissionsRequest, type PersistedSessionData, type Platform, type ProviderTransaction, type Quote, type QuoteOptions, type QuoteSortBy, type RefreshFeesOptions, ResolutionError, type ResolutionErrorCode, ResolverCache, type ResolverProvider, type RiskAssessment, type RiskLevel, type RiskWarning, type RiskWarningCategory, type RiskWarningSeverity, type Route, RouteEngine, type RouteStatus, type RouteStatusValue, type RouteStep, SESSION_ERROR_MESSAGES, SESSION_KEY_ERROR_MESSAGES, SESSION_TIMEOUT_MS, SIMPLE_ACCOUNT_FACTORY, SNSProvider, SOLANA_DEVNET, SOLANA_MAINNET, SOLANA_TESTNET, STORAGE_KEYS, SUPPORTED_NAMESPACES, type ScopeCheckResult, type SendUserOpOptions, type SessionErrorCode, type SessionEvent, SessionEventEmitter, type SessionEventHandler, type SessionEventPayloads, type SessionKeyBundle, type SessionKeyErrorCode, type SessionKeyInfo, SessionKeyManager, type SessionKeyManagerConfig, type SessionKeyPair, type SessionKeyScope, type SessionKeyStatus, SessionKeyStorage, SessionManager, type SessionManagerConfig, type SessionNamespace, SessionPersistence, type SessionStorage, SessionStorageAdapter, type SignedAuthorization, type SimulationConfig, SimulationManager, type SimulationProvider, type SimulationProviderName, type SimulationResult, type SimulationStatus, type SmartAccountConfig, type SmartAccountInfo, SmartAccountManager, type SmartAccountManagerConfig, type StorageAdapter, StorageError, type StoredSessionKey, TelegramChannel, type Token, type TokenConfig, type TokenInfo, type TokenList, type TokenListEntry, TokenListManager, type TokenListManagerConfig, type TokenListSource, type TokenListSourceStatus, type TokenMatch, type TokenSearchQuery, type TokenSearchResult, type TransactionDescriptor, type TxMetadata, type TxStatus, type TxStatusCallback, type UniversalConnector, type UniversalWalletSession, type UserFeeOverrides, type UserNotificationPreferences, type UserOperation, type UserOperationGasEstimate, type UserOperationReceipt, type UserOperationResponse, WC_DISCONNECT_SESSION_EXPIRED, WC_DISCONNECT_TIMEOUT, WC_DISCONNECT_USER, type WalletCapabilities, WalletError, type WalletErrorCode, type WalletPermission, XRPL_DEVNET, XRPL_MAINNET, XRPL_TESTNET, abiEncodeAddress, abiEncodeFunctionCall, abiEncodeUint256, abiFunctionSelector, buildCallData, buildUserOperation, clearAutoDetectCache, clearChainFeeEstimators, compareSimulationVsActual, createAutoReconnectManager, createConnectorManager, createEmptySession, createPaymasterService, createRouteEngine, createSessionError, createSessionKeyError, createSessionManager, createSessionPersistence, createStorageAdapter, decodeGasLimits, decryptPrivateKey, detectPlatform, detectTokenInfo, encodeGasLimits, encryptPrivateKey, estimateFees, estimateMaxPriorityFeePerGas, estimateUserOperationGas, extractAccounts, extractAccountsFromPermissions, formatUnits, getAllBuiltinTokens, getChainId, getChainsFromNamespaces, getEventsFromNamespaces, getFeeData, getGasPrice, getLatestBaseFee, getMethodsFromNamespaces, getNativeTokenPriceUsd, getPermissions, getRpcUrl, hasPermission, hashUserOperation, isAAError, isBurnAddress, isChainAbstractionError, isERC20TokenError, isFeeEstimationError, isMobileBrowser, isSessionExpired, isValidAddress, isWalletError, isZeroAddress, logger, parseBigInt, parseChainId, parseUnits, registerChainFeeEstimator, requestPermissions, sendUserOperation, setLogLevel, setLogSink, signUserOperation, toDecString, toHumanReadable, unregisterChainFeeEstimator, updateSession, validateChainId };
|