amped-defi 1.0.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/README.md +757 -0
- package/dist/__mocks__/@sodax/sdk.d.ts +24 -0
- package/dist/__mocks__/@sodax/sdk.d.ts.map +1 -0
- package/dist/__mocks__/@sodax/sdk.js +24 -0
- package/dist/__mocks__/@sodax/sdk.js.map +1 -0
- package/dist/__tests__/setup.d.ts +4 -0
- package/dist/__tests__/setup.d.ts.map +1 -0
- package/dist/__tests__/setup.js +32 -0
- package/dist/__tests__/setup.js.map +1 -0
- package/dist/index.d.ts +66 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +281 -0
- package/dist/index.js.map +1 -0
- package/dist/policy/policyEngine.d.ts +119 -0
- package/dist/policy/policyEngine.d.ts.map +1 -0
- package/dist/policy/policyEngine.js +322 -0
- package/dist/policy/policyEngine.js.map +1 -0
- package/dist/providers/spokeProviderFactory.d.ts +38 -0
- package/dist/providers/spokeProviderFactory.d.ts.map +1 -0
- package/dist/providers/spokeProviderFactory.js +212 -0
- package/dist/providers/spokeProviderFactory.js.map +1 -0
- package/dist/sodax/client.d.ts +34 -0
- package/dist/sodax/client.d.ts.map +1 -0
- package/dist/sodax/client.js +99 -0
- package/dist/sodax/client.js.map +1 -0
- package/dist/tools/bridge.d.ts +105 -0
- package/dist/tools/bridge.d.ts.map +1 -0
- package/dist/tools/bridge.js +334 -0
- package/dist/tools/bridge.js.map +1 -0
- package/dist/tools/discovery.d.ts +141 -0
- package/dist/tools/discovery.d.ts.map +1 -0
- package/dist/tools/discovery.js +777 -0
- package/dist/tools/discovery.js.map +1 -0
- package/dist/tools/moneyMarket.d.ts +227 -0
- package/dist/tools/moneyMarket.d.ts.map +1 -0
- package/dist/tools/moneyMarket.js +867 -0
- package/dist/tools/moneyMarket.js.map +1 -0
- package/dist/tools/portfolio.d.ts +43 -0
- package/dist/tools/portfolio.d.ts.map +1 -0
- package/dist/tools/portfolio.js +538 -0
- package/dist/tools/portfolio.js.map +1 -0
- package/dist/tools/swap.d.ts +71 -0
- package/dist/tools/swap.d.ts.map +1 -0
- package/dist/tools/swap.js +762 -0
- package/dist/tools/swap.js.map +1 -0
- package/dist/tools/walletManagement.d.ts +80 -0
- package/dist/tools/walletManagement.d.ts.map +1 -0
- package/dist/tools/walletManagement.js +289 -0
- package/dist/tools/walletManagement.js.map +1 -0
- package/dist/types.d.ts +205 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/errorUtils.d.ts +2 -0
- package/dist/utils/errorUtils.d.ts.map +1 -0
- package/dist/utils/errorUtils.js +19 -0
- package/dist/utils/errorUtils.js.map +1 -0
- package/dist/utils/errors.d.ts +144 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/dist/utils/errors.js +310 -0
- package/dist/utils/errors.js.map +1 -0
- package/dist/utils/positionAggregator.d.ts +122 -0
- package/dist/utils/positionAggregator.d.ts.map +1 -0
- package/dist/utils/positionAggregator.js +377 -0
- package/dist/utils/positionAggregator.js.map +1 -0
- package/dist/utils/priceService.d.ts +45 -0
- package/dist/utils/priceService.d.ts.map +1 -0
- package/dist/utils/priceService.js +108 -0
- package/dist/utils/priceService.js.map +1 -0
- package/dist/utils/sodaxApi.d.ts +92 -0
- package/dist/utils/sodaxApi.d.ts.map +1 -0
- package/dist/utils/sodaxApi.js +143 -0
- package/dist/utils/sodaxApi.js.map +1 -0
- package/dist/utils/tokenResolver.d.ts +54 -0
- package/dist/utils/tokenResolver.d.ts.map +1 -0
- package/dist/utils/tokenResolver.js +252 -0
- package/dist/utils/tokenResolver.js.map +1 -0
- package/dist/wallet/backendConfig.d.ts +37 -0
- package/dist/wallet/backendConfig.d.ts.map +1 -0
- package/dist/wallet/backendConfig.js +125 -0
- package/dist/wallet/backendConfig.js.map +1 -0
- package/dist/wallet/backends/BankrBackend.d.ts +73 -0
- package/dist/wallet/backends/BankrBackend.d.ts.map +1 -0
- package/dist/wallet/backends/BankrBackend.js +315 -0
- package/dist/wallet/backends/BankrBackend.js.map +1 -0
- package/dist/wallet/backends/BankrWalletProvider.d.ts +75 -0
- package/dist/wallet/backends/BankrWalletProvider.d.ts.map +1 -0
- package/dist/wallet/backends/BankrWalletProvider.js +243 -0
- package/dist/wallet/backends/BankrWalletProvider.js.map +1 -0
- package/dist/wallet/backends/EnvBackend.d.ts +50 -0
- package/dist/wallet/backends/EnvBackend.d.ts.map +1 -0
- package/dist/wallet/backends/EnvBackend.js +114 -0
- package/dist/wallet/backends/EnvBackend.js.map +1 -0
- package/dist/wallet/backends/EvmWalletSkillBackend.d.ts +40 -0
- package/dist/wallet/backends/EvmWalletSkillBackend.d.ts.map +1 -0
- package/dist/wallet/backends/EvmWalletSkillBackend.js +81 -0
- package/dist/wallet/backends/EvmWalletSkillBackend.js.map +1 -0
- package/dist/wallet/backends/index.d.ts +10 -0
- package/dist/wallet/backends/index.d.ts.map +1 -0
- package/dist/wallet/backends/index.js +10 -0
- package/dist/wallet/backends/index.js.map +1 -0
- package/dist/wallet/index.d.ts +9 -0
- package/dist/wallet/index.d.ts.map +1 -0
- package/dist/wallet/index.js +12 -0
- package/dist/wallet/index.js.map +1 -0
- package/dist/wallet/providers/AmpedWalletProvider.d.ts +107 -0
- package/dist/wallet/providers/AmpedWalletProvider.d.ts.map +1 -0
- package/dist/wallet/providers/AmpedWalletProvider.js +208 -0
- package/dist/wallet/providers/AmpedWalletProvider.js.map +1 -0
- package/dist/wallet/providers/BankrBackend.d.ts +105 -0
- package/dist/wallet/providers/BankrBackend.d.ts.map +1 -0
- package/dist/wallet/providers/BankrBackend.js +327 -0
- package/dist/wallet/providers/BankrBackend.js.map +1 -0
- package/dist/wallet/providers/LocalKeyBackend.d.ts +62 -0
- package/dist/wallet/providers/LocalKeyBackend.d.ts.map +1 -0
- package/dist/wallet/providers/LocalKeyBackend.js +152 -0
- package/dist/wallet/providers/LocalKeyBackend.js.map +1 -0
- package/dist/wallet/providers/chainConfig.d.ts +209 -0
- package/dist/wallet/providers/chainConfig.d.ts.map +1 -0
- package/dist/wallet/providers/chainConfig.js +175 -0
- package/dist/wallet/providers/chainConfig.js.map +1 -0
- package/dist/wallet/providers/index.d.ts +30 -0
- package/dist/wallet/providers/index.d.ts.map +1 -0
- package/dist/wallet/providers/index.js +32 -0
- package/dist/wallet/providers/index.js.map +1 -0
- package/dist/wallet/providers/types.d.ts +156 -0
- package/dist/wallet/providers/types.d.ts.map +1 -0
- package/dist/wallet/providers/types.js +11 -0
- package/dist/wallet/providers/types.js.map +1 -0
- package/dist/wallet/skillWalletAdapter.d.ts +96 -0
- package/dist/wallet/skillWalletAdapter.d.ts.map +1 -0
- package/dist/wallet/skillWalletAdapter.js +280 -0
- package/dist/wallet/skillWalletAdapter.js.map +1 -0
- package/dist/wallet/types.d.ts +134 -0
- package/dist/wallet/types.d.ts.map +1 -0
- package/dist/wallet/types.js +138 -0
- package/dist/wallet/types.js.map +1 -0
- package/dist/wallet/walletManager.d.ts +111 -0
- package/dist/wallet/walletManager.d.ts.map +1 -0
- package/dist/wallet/walletManager.js +476 -0
- package/dist/wallet/walletManager.js.map +1 -0
- package/dist/wallet/walletRegistry.d.ts +95 -0
- package/dist/wallet/walletRegistry.d.ts.map +1 -0
- package/dist/wallet/walletRegistry.js +184 -0
- package/dist/wallet/walletRegistry.js.map +1 -0
- package/index.js +2 -0
- package/openclaw.plugin.json +37 -0
- package/package.json +69 -0
- package/src/__mocks__/@sodax/sdk.ts +28 -0
- package/src/__tests__/errors.test.ts +238 -0
- package/src/__tests__/policyEngine.test.ts +354 -0
- package/src/__tests__/positionAggregator.test.ts +271 -0
- package/src/__tests__/setup.ts +35 -0
- package/src/__tests__/sodaxApi.test.ts +203 -0
- package/src/__tests__/walletRegistry.test.ts +155 -0
- package/src/index.ts +376 -0
- package/src/policy/policyEngine.ts +389 -0
- package/src/providers/spokeProviderFactory.ts +283 -0
- package/src/sodax/client.ts +113 -0
- package/src/tools/bridge.ts +425 -0
- package/src/tools/discovery.ts +989 -0
- package/src/tools/moneyMarket.ts +1265 -0
- package/src/tools/portfolio.ts +697 -0
- package/src/tools/swap.ts +926 -0
- package/src/tools/walletManagement.ts +359 -0
- package/src/types.ts +228 -0
- package/src/utils/errorUtils.ts +16 -0
- package/src/utils/errors.ts +396 -0
- package/src/utils/positionAggregator.ts +559 -0
- package/src/utils/priceService.ts +153 -0
- package/src/utils/sodaxApi.ts +261 -0
- package/src/utils/tokenResolver.ts +286 -0
- package/src/wallet/backendConfig.ts +151 -0
- package/src/wallet/backends/BankrBackend.ts +399 -0
- package/src/wallet/backends/BankrWalletProvider.ts +329 -0
- package/src/wallet/backends/EnvBackend.ts +149 -0
- package/src/wallet/backends/EvmWalletSkillBackend.ts +110 -0
- package/src/wallet/backends/index.ts +10 -0
- package/src/wallet/index.ts +14 -0
- package/src/wallet/providers/AmpedWalletProvider.ts +267 -0
- package/src/wallet/providers/BankrBackend.ts +407 -0
- package/src/wallet/providers/LocalKeyBackend.ts +184 -0
- package/src/wallet/providers/chainConfig.ts +194 -0
- package/src/wallet/providers/index.ts +62 -0
- package/src/wallet/providers/types.ts +186 -0
- package/src/wallet/skillWalletAdapter.ts +335 -0
- package/src/wallet/types.ts +248 -0
- package/src/wallet/walletManager.ts +561 -0
- package/src/wallet/walletRegistry.ts +216 -0
|
@@ -0,0 +1,396 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Error Handling Utilities
|
|
3
|
+
*
|
|
4
|
+
* Provides standardized error handling, error codes, and user-friendly error messages
|
|
5
|
+
* for all Amped DeFi operations.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Standard error codes for Amped DeFi operations
|
|
10
|
+
*/
|
|
11
|
+
export enum ErrorCode {
|
|
12
|
+
// Policy errors
|
|
13
|
+
POLICY_SLIPPAGE_EXCEEDED = 'POLICY_SLIPPAGE_EXCEEDED',
|
|
14
|
+
POLICY_SPEND_LIMIT_EXCEEDED = 'POLICY_SPEND_LIMIT_EXCEEDED',
|
|
15
|
+
POLICY_CHAIN_NOT_ALLOWED = 'POLICY_CHAIN_NOT_ALLOWED',
|
|
16
|
+
POLICY_TOKEN_NOT_ALLOWED = 'POLICY_TOKEN_NOT_ALLOWED',
|
|
17
|
+
POLICY_RECIPIENT_BLOCKED = 'POLICY_RECIPIENT_BLOCKED',
|
|
18
|
+
|
|
19
|
+
// Wallet errors
|
|
20
|
+
WALLET_NOT_FOUND = 'WALLET_NOT_FOUND',
|
|
21
|
+
WALLET_INVALID_ADDRESS = 'WALLET_INVALID_ADDRESS',
|
|
22
|
+
WALLET_MISSING_PRIVATE_KEY = 'WALLET_MISSING_PRIVATE_KEY',
|
|
23
|
+
WALLET_RESOLUTION_FAILED = 'WALLET_RESOLUTION_FAILED',
|
|
24
|
+
|
|
25
|
+
// Chain/Provider errors
|
|
26
|
+
CHAIN_NOT_SUPPORTED = 'CHAIN_NOT_SUPPORTED',
|
|
27
|
+
RPC_URL_NOT_CONFIGURED = 'RPC_URL_NOT_CONFIGURED',
|
|
28
|
+
PROVIDER_CREATION_FAILED = 'PROVIDER_CREATION_FAILED',
|
|
29
|
+
SONIC_PROVIDER_REQUIRED = 'SONIC_PROVIDER_REQUIRED',
|
|
30
|
+
|
|
31
|
+
// Token errors
|
|
32
|
+
INSUFFICIENT_BALANCE = 'INSUFFICIENT_BALANCE',
|
|
33
|
+
INSUFFICIENT_ALLOWANCE = 'INSUFFICIENT_ALLOWANCE',
|
|
34
|
+
TOKEN_NOT_SUPPORTED = 'TOKEN_NOT_SUPPORTED',
|
|
35
|
+
TOKEN_DECIMALS_NOT_FOUND = 'TOKEN_DECIMALS_NOT_FOUND',
|
|
36
|
+
|
|
37
|
+
// Operation errors
|
|
38
|
+
QUOTE_EXPIRED = 'QUOTE_EXPIRED',
|
|
39
|
+
QUOTE_NOT_FOUND = 'QUOTE_NOT_FOUND',
|
|
40
|
+
BRIDGE_NOT_AVAILABLE = 'BRIDGE_NOT_AVAILABLE',
|
|
41
|
+
SWAP_EXECUTION_FAILED = 'SWAP_EXECUTION_FAILED',
|
|
42
|
+
BRIDGE_EXECUTION_FAILED = 'BRIDGE_EXECUTION_FAILED',
|
|
43
|
+
MM_HEALTH_FACTOR_LOW = 'MM_HEALTH_FACTOR_LOW',
|
|
44
|
+
MM_CROSS_CHAIN_NOT_SUPPORTED = 'MM_CROSS_CHAIN_NOT_SUPPORTED',
|
|
45
|
+
MM_INSUFFICIENT_COLLATERAL = 'MM_INSUFFICIENT_COLLATERAL',
|
|
46
|
+
MM_POSITION_NOT_FOUND = 'MM_POSITION_NOT_FOUND',
|
|
47
|
+
|
|
48
|
+
// Transaction errors
|
|
49
|
+
TRANSACTION_FAILED = 'TRANSACTION_FAILED',
|
|
50
|
+
TRANSACTION_TIMEOUT = 'TRANSACTION_TIMEOUT',
|
|
51
|
+
TRANSACTION_REJECTED = 'TRANSACTION_REJECTED',
|
|
52
|
+
TRANSACTION_SIMULATION_FAILED = 'TRANSACTION_SIMULATION_FAILED',
|
|
53
|
+
|
|
54
|
+
// SDK/Configuration errors
|
|
55
|
+
SDK_NOT_INITIALIZED = 'SDK_NOT_INITIALIZED',
|
|
56
|
+
SDK_INITIALIZATION_FAILED = 'SDK_INITIALIZATION_FAILED',
|
|
57
|
+
INVALID_CONFIGURATION = 'INVALID_CONFIGURATION',
|
|
58
|
+
CONFIG_PARSE_ERROR = 'CONFIG_PARSE_ERROR',
|
|
59
|
+
|
|
60
|
+
// Unknown/Generic
|
|
61
|
+
UNKNOWN_ERROR = 'UNKNOWN_ERROR',
|
|
62
|
+
OPERATION_CANCELLED = 'OPERATION_CANCELLED',
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Error severity levels
|
|
67
|
+
*/
|
|
68
|
+
export enum ErrorSeverity {
|
|
69
|
+
INFO = 'info',
|
|
70
|
+
WARNING = 'warning',
|
|
71
|
+
ERROR = 'error',
|
|
72
|
+
CRITICAL = 'critical',
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Structured error information
|
|
77
|
+
*/
|
|
78
|
+
export interface AmpedError {
|
|
79
|
+
code: ErrorCode;
|
|
80
|
+
message: string;
|
|
81
|
+
severity: ErrorSeverity;
|
|
82
|
+
remediation?: string;
|
|
83
|
+
details?: Record<string, unknown>;
|
|
84
|
+
cause?: Error;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Error context for logging
|
|
89
|
+
*/
|
|
90
|
+
export interface ErrorContext {
|
|
91
|
+
operation?: string;
|
|
92
|
+
walletId?: string;
|
|
93
|
+
chainId?: string;
|
|
94
|
+
chainIds?: string[];
|
|
95
|
+
token?: string;
|
|
96
|
+
tokens?: string[];
|
|
97
|
+
amount?: string;
|
|
98
|
+
requestId?: string;
|
|
99
|
+
txHash?: string;
|
|
100
|
+
[key: string]: unknown;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Amped DeFi Error class
|
|
105
|
+
*/
|
|
106
|
+
export class AmpedDefiError extends Error {
|
|
107
|
+
public readonly code: ErrorCode;
|
|
108
|
+
public readonly severity: ErrorSeverity;
|
|
109
|
+
public readonly remediation?: string;
|
|
110
|
+
public readonly details?: Record<string, unknown>;
|
|
111
|
+
public readonly context?: ErrorContext;
|
|
112
|
+
|
|
113
|
+
constructor(
|
|
114
|
+
code: ErrorCode,
|
|
115
|
+
message: string,
|
|
116
|
+
options?: {
|
|
117
|
+
severity?: ErrorSeverity;
|
|
118
|
+
remediation?: string;
|
|
119
|
+
details?: Record<string, unknown>;
|
|
120
|
+
context?: ErrorContext;
|
|
121
|
+
cause?: Error;
|
|
122
|
+
}
|
|
123
|
+
) {
|
|
124
|
+
super(message, { cause: options?.cause });
|
|
125
|
+
this.name = 'AmpedDefiError';
|
|
126
|
+
this.code = code;
|
|
127
|
+
this.severity = options?.severity || ErrorSeverity.ERROR;
|
|
128
|
+
this.remediation = options?.remediation;
|
|
129
|
+
this.details = options?.details;
|
|
130
|
+
this.context = options?.context;
|
|
131
|
+
|
|
132
|
+
// Maintains proper stack trace for where our error was thrown (only available on V8)
|
|
133
|
+
if (Error.captureStackTrace) {
|
|
134
|
+
Error.captureStackTrace(this, AmpedDefiError);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Convert to JSON-serializable object
|
|
140
|
+
*/
|
|
141
|
+
toJSON(): AmpedError {
|
|
142
|
+
return {
|
|
143
|
+
code: this.code,
|
|
144
|
+
message: this.message,
|
|
145
|
+
severity: this.severity,
|
|
146
|
+
remediation: this.remediation,
|
|
147
|
+
details: this.details,
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Get user-friendly error message
|
|
153
|
+
*/
|
|
154
|
+
toUserMessage(): string {
|
|
155
|
+
let msg = `[${this.code}] ${this.message}`;
|
|
156
|
+
if (this.remediation) {
|
|
157
|
+
msg += `\n\nSuggestion: ${this.remediation}`;
|
|
158
|
+
}
|
|
159
|
+
return msg;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// ============================================================================
|
|
164
|
+
// Error Factory Functions
|
|
165
|
+
// ============================================================================
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Create a policy error
|
|
169
|
+
*/
|
|
170
|
+
export function createPolicyError(
|
|
171
|
+
code: ErrorCode,
|
|
172
|
+
message: string,
|
|
173
|
+
details?: { current?: unknown; limit?: unknown; [key: string]: unknown },
|
|
174
|
+
context?: ErrorContext
|
|
175
|
+
): AmpedDefiError {
|
|
176
|
+
const remediation = getPolicyRemediation(code, details);
|
|
177
|
+
return new AmpedDefiError(code, message, {
|
|
178
|
+
severity: ErrorSeverity.WARNING,
|
|
179
|
+
remediation,
|
|
180
|
+
details,
|
|
181
|
+
context,
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Create a wallet error
|
|
187
|
+
*/
|
|
188
|
+
export function createWalletError(
|
|
189
|
+
code: ErrorCode,
|
|
190
|
+
walletId: string,
|
|
191
|
+
cause?: Error,
|
|
192
|
+
context?: ErrorContext
|
|
193
|
+
): AmpedDefiError {
|
|
194
|
+
const message = getWalletErrorMessage(code, walletId);
|
|
195
|
+
return new AmpedDefiError(code, message, {
|
|
196
|
+
severity: ErrorSeverity.ERROR,
|
|
197
|
+
remediation: getWalletRemediation(code),
|
|
198
|
+
context: { ...context, walletId },
|
|
199
|
+
cause,
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Create a transaction error
|
|
205
|
+
*/
|
|
206
|
+
export function createTransactionError(
|
|
207
|
+
code: ErrorCode,
|
|
208
|
+
message: string,
|
|
209
|
+
txHash?: string,
|
|
210
|
+
cause?: Error,
|
|
211
|
+
context?: ErrorContext
|
|
212
|
+
): AmpedDefiError {
|
|
213
|
+
return new AmpedDefiError(code, message, {
|
|
214
|
+
severity: ErrorSeverity.ERROR,
|
|
215
|
+
remediation: getTransactionRemediation(code),
|
|
216
|
+
details: txHash ? { txHash } : undefined,
|
|
217
|
+
context: txHash ? { ...context, txHash } : context,
|
|
218
|
+
cause,
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Create an SDK error
|
|
224
|
+
*/
|
|
225
|
+
export function createSDKError(
|
|
226
|
+
code: ErrorCode,
|
|
227
|
+
message: string,
|
|
228
|
+
cause?: Error,
|
|
229
|
+
context?: ErrorContext
|
|
230
|
+
): AmpedDefiError {
|
|
231
|
+
return new AmpedDefiError(code, message, {
|
|
232
|
+
severity: ErrorSeverity.CRITICAL,
|
|
233
|
+
remediation: 'Please check your configuration and try again. If the issue persists, contact support.',
|
|
234
|
+
context,
|
|
235
|
+
cause,
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* Wrap an unknown error into an AmpedDefiError
|
|
241
|
+
*/
|
|
242
|
+
export function wrapError(
|
|
243
|
+
error: unknown,
|
|
244
|
+
fallbackCode: ErrorCode = ErrorCode.UNKNOWN_ERROR,
|
|
245
|
+
context?: ErrorContext
|
|
246
|
+
): AmpedDefiError {
|
|
247
|
+
if (error instanceof AmpedDefiError) {
|
|
248
|
+
return error;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
if (error instanceof Error) {
|
|
252
|
+
// Try to infer error code from message
|
|
253
|
+
const code = inferErrorCode(error.message) || fallbackCode;
|
|
254
|
+
return new AmpedDefiError(code, error.message, {
|
|
255
|
+
severity: ErrorSeverity.ERROR,
|
|
256
|
+
context,
|
|
257
|
+
cause: error,
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
return new AmpedDefiError(fallbackCode, String(error), {
|
|
262
|
+
severity: ErrorSeverity.ERROR,
|
|
263
|
+
context,
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
// ============================================================================
|
|
268
|
+
// Remediation Helpers
|
|
269
|
+
// ============================================================================
|
|
270
|
+
|
|
271
|
+
function getPolicyRemediation(code: ErrorCode, details?: Record<string, unknown>): string {
|
|
272
|
+
switch (code) {
|
|
273
|
+
case ErrorCode.POLICY_SLIPPAGE_EXCEEDED:
|
|
274
|
+
return `Slippage ${details?.current} bps exceeds limit of ${details?.limit} bps. Increase maxSlippageBps in your policy configuration or wait for better market conditions.`;
|
|
275
|
+
case ErrorCode.POLICY_SPEND_LIMIT_EXCEEDED:
|
|
276
|
+
return `Reduce the operation amount or request a policy limit increase. Current limit: ${details?.limit}`;
|
|
277
|
+
case ErrorCode.POLICY_CHAIN_NOT_ALLOWED:
|
|
278
|
+
return `Add the chain to your allowedChains policy configuration or use a different chain.`;
|
|
279
|
+
case ErrorCode.POLICY_TOKEN_NOT_ALLOWED:
|
|
280
|
+
return `Add the token to your allowedTokensByChain policy configuration or use a different token.`;
|
|
281
|
+
case ErrorCode.POLICY_RECIPIENT_BLOCKED:
|
|
282
|
+
return `Use a different recipient address. This address has been blocked by policy.`;
|
|
283
|
+
default:
|
|
284
|
+
return 'Review your policy configuration or contact your administrator.';
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
function getWalletRemediation(code: ErrorCode): string {
|
|
289
|
+
switch (code) {
|
|
290
|
+
case ErrorCode.WALLET_NOT_FOUND:
|
|
291
|
+
return 'Check your AMPED_OC_WALLETS_JSON configuration and ensure the walletId is correct.';
|
|
292
|
+
case ErrorCode.WALLET_INVALID_ADDRESS:
|
|
293
|
+
return 'Verify the wallet address format (should be 0x-prefixed Ethereum address).';
|
|
294
|
+
case ErrorCode.WALLET_MISSING_PRIVATE_KEY:
|
|
295
|
+
return 'Add the private key to your wallet configuration for execute mode, or switch to prepare mode.';
|
|
296
|
+
default:
|
|
297
|
+
return 'Check your wallet configuration and try again.';
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
function getTransactionRemediation(code: ErrorCode): string {
|
|
302
|
+
switch (code) {
|
|
303
|
+
case ErrorCode.TRANSACTION_FAILED:
|
|
304
|
+
return 'Check the transaction on a block explorer for revert reasons. You may need to adjust parameters or try again later.';
|
|
305
|
+
case ErrorCode.TRANSACTION_TIMEOUT:
|
|
306
|
+
return 'The operation timed out. You can check the status later using the transaction hash.';
|
|
307
|
+
case ErrorCode.TRANSACTION_REJECTED:
|
|
308
|
+
return 'The transaction was rejected. This may be due to network congestion or insufficient gas.';
|
|
309
|
+
case ErrorCode.TRANSACTION_SIMULATION_FAILED:
|
|
310
|
+
return 'The transaction would fail if executed. Check your balances, allowances, and parameters.';
|
|
311
|
+
default:
|
|
312
|
+
return 'Try again or contact support if the issue persists.';
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
function getWalletErrorMessage(code: ErrorCode, walletId: string): string {
|
|
317
|
+
switch (code) {
|
|
318
|
+
case ErrorCode.WALLET_NOT_FOUND:
|
|
319
|
+
return `Wallet not found: ${walletId}`;
|
|
320
|
+
case ErrorCode.WALLET_INVALID_ADDRESS:
|
|
321
|
+
return `Wallet ${walletId} has an invalid address`;
|
|
322
|
+
case ErrorCode.WALLET_MISSING_PRIVATE_KEY:
|
|
323
|
+
return `Wallet ${walletId} is missing private key (required in execute mode)`;
|
|
324
|
+
default:
|
|
325
|
+
return `Wallet error for ${walletId}`;
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
function inferErrorCode(message: string): ErrorCode | null {
|
|
330
|
+
const lowerMsg = message.toLowerCase();
|
|
331
|
+
|
|
332
|
+
if (lowerMsg.includes('insufficient balance')) return ErrorCode.INSUFFICIENT_BALANCE;
|
|
333
|
+
if (lowerMsg.includes('allowance')) return ErrorCode.INSUFFICIENT_ALLOWANCE;
|
|
334
|
+
if (lowerMsg.includes('slippage')) return ErrorCode.POLICY_SLIPPAGE_EXCEEDED;
|
|
335
|
+
if (lowerMsg.includes('health factor')) return ErrorCode.MM_HEALTH_FACTOR_LOW;
|
|
336
|
+
if (lowerMsg.includes('timeout')) return ErrorCode.TRANSACTION_TIMEOUT;
|
|
337
|
+
if (lowerMsg.includes('rejected')) return ErrorCode.TRANSACTION_REJECTED;
|
|
338
|
+
if (lowerMsg.includes('simulation')) return ErrorCode.TRANSACTION_SIMULATION_FAILED;
|
|
339
|
+
if (lowerMsg.includes('not initialized')) return ErrorCode.SDK_NOT_INITIALIZED;
|
|
340
|
+
if (lowerMsg.includes('bridge') && lowerMsg.includes('not')) return ErrorCode.BRIDGE_NOT_AVAILABLE;
|
|
341
|
+
if (lowerMsg.includes('quote') && lowerMsg.includes('expir')) return ErrorCode.QUOTE_EXPIRED;
|
|
342
|
+
|
|
343
|
+
return null;
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
// ============================================================================
|
|
347
|
+
// Logging and Observability
|
|
348
|
+
// ============================================================================
|
|
349
|
+
|
|
350
|
+
/**
|
|
351
|
+
* Log an error with structured context
|
|
352
|
+
*/
|
|
353
|
+
export function logError(error: AmpedDefiError | Error, context?: ErrorContext): void {
|
|
354
|
+
const structuredLog = {
|
|
355
|
+
timestamp: new Date().toISOString(),
|
|
356
|
+
component: 'amped-defi',
|
|
357
|
+
level: error instanceof AmpedDefiError ? error.severity : 'error',
|
|
358
|
+
code: error instanceof AmpedDefiError ? error.code : ErrorCode.UNKNOWN_ERROR,
|
|
359
|
+
message: error.message,
|
|
360
|
+
context,
|
|
361
|
+
stack: error.stack,
|
|
362
|
+
cause: error.cause,
|
|
363
|
+
};
|
|
364
|
+
|
|
365
|
+
// Log as JSON for structured logging systems
|
|
366
|
+
console.error(JSON.stringify(structuredLog, (k, v) => typeof v === 'bigint' ? v.toString() : v));
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
/**
|
|
370
|
+
* Check if an error is retryable
|
|
371
|
+
*/
|
|
372
|
+
export function isRetryableError(error: AmpedDefiError | Error): boolean {
|
|
373
|
+
if (error instanceof AmpedDefiError) {
|
|
374
|
+
const retryableCodes = [
|
|
375
|
+
ErrorCode.TRANSACTION_TIMEOUT,
|
|
376
|
+
ErrorCode.RPC_URL_NOT_CONFIGURED,
|
|
377
|
+
ErrorCode.SDK_NOT_INITIALIZED,
|
|
378
|
+
ErrorCode.UNKNOWN_ERROR,
|
|
379
|
+
];
|
|
380
|
+
return retryableCodes.includes(error.code);
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
// For generic errors, check message patterns
|
|
384
|
+
const lowerMsg = error.message.toLowerCase();
|
|
385
|
+
return lowerMsg.includes('timeout') ||
|
|
386
|
+
lowerMsg.includes('network') ||
|
|
387
|
+
lowerMsg.includes('connection') ||
|
|
388
|
+
lowerMsg.includes('rate limit');
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
/**
|
|
392
|
+
* Get retry delay in milliseconds with exponential backoff
|
|
393
|
+
*/
|
|
394
|
+
export function getRetryDelay(attempt: number, baseDelay = 1000): number {
|
|
395
|
+
return Math.min(baseDelay * Math.pow(2, attempt), 30000); // Cap at 30 seconds
|
|
396
|
+
}
|