sdk-triggerx 0.1.16 → 0.1.18

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.
@@ -0,0 +1,109 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SAFE_TX_TYPEHASH = exports.SAFE_ABI = void 0;
4
+ exports.isSafeModuleEnabled = isSafeModuleEnabled;
5
+ exports.ensureSingleOwnerAndMatchSigner = ensureSingleOwnerAndMatchSigner;
6
+ exports.enableSafeModule = enableSafeModule;
7
+ const ethers_1 = require("ethers");
8
+ // Minimal Safe ABI fragments used in this SDK
9
+ exports.SAFE_ABI = [
10
+ // module checks
11
+ "function isModuleEnabled(address module) view returns (bool)",
12
+ // module management
13
+ "function enableModule(address module)",
14
+ // EIP-712 domain separator for Safe
15
+ "function domainSeparator() view returns (bytes32)",
16
+ // Safe nonce
17
+ "function nonce() view returns (uint256)",
18
+ // Exec transaction (self-call to enable module)
19
+ "function execTransaction(address to,uint256 value,bytes data,uint8 operation,uint256 safeTxGas,uint256 baseGas,uint256 gasPrice,address gasToken,address refundReceiver,bytes signatures) returns (bool)",
20
+ // Owners and threshold, to validate single signer safes
21
+ "function getOwners() view returns (address[])",
22
+ "function getThreshold() view returns (uint256)",
23
+ // Add getTransactionHash for onchain hash calculation
24
+ "function getTransactionHash(address to,uint256 value,bytes data,uint8 operation,uint256 safeTxGas,uint256 baseGas,uint256 gasPrice,address gasToken,address refundReceiver,uint256 nonce) view returns (bytes32)"
25
+ ];
26
+ // Safe EIP-712 typehash for transactions
27
+ exports.SAFE_TX_TYPEHASH = ethers_1.ethers.id("SafeTx(address to,uint256 value,bytes data,uint8 operation,uint256 safeTxGas,uint256 baseGas,uint256 gasPrice,address gasToken,address refundReceiver,uint256 _nonce)");
28
+ async function isSafeModuleEnabled(safeAddress, provider, moduleAddress) {
29
+ const safe = new ethers_1.ethers.Contract(safeAddress, exports.SAFE_ABI, provider);
30
+ return await safe.isModuleEnabled(moduleAddress);
31
+ }
32
+ async function ensureSingleOwnerAndMatchSigner(safeAddress, provider, signerAddress) {
33
+ const safe = new ethers_1.ethers.Contract(safeAddress, exports.SAFE_ABI, provider);
34
+ const [owners, threshold] = await Promise.all([
35
+ safe.getOwners(),
36
+ safe.getThreshold(),
37
+ ]);
38
+ if (Number(threshold) !== 1) {
39
+ throw new Error('Safe wallet must have threshold 1');
40
+ }
41
+ // Check if signerAddress matches any of the Safe owners
42
+ const normalizedSigner = signerAddress.toLowerCase();
43
+ const normalizedOwners = owners.map((owner) => owner.toLowerCase());
44
+ if (!normalizedOwners.includes(normalizedSigner)) {
45
+ throw new Error('Signer is not an owner of the Safe wallet');
46
+ }
47
+ if (owners[0].toLowerCase() !== signerAddress.toLowerCase()) {
48
+ throw new Error('Signer must be the sole owner of the Safe wallet');
49
+ }
50
+ }
51
+ // Enable provided module on the Safe by crafting and signing a Safe execTransaction
52
+ async function enableSafeModule(safeAddress, signer, moduleAddress) {
53
+ const provider = signer.provider;
54
+ if (!provider)
55
+ throw new Error('Signer provider is required');
56
+ const safeProxy = new ethers_1.ethers.Contract(safeAddress, exports.SAFE_ABI, provider);
57
+ // If already enabled, exit early
58
+ const already = await safeProxy.isModuleEnabled(moduleAddress);
59
+ if (already) {
60
+ console.log('Module is already enabled');
61
+ return;
62
+ }
63
+ // First, let's try the direct approach for single-owner Safes
64
+ try {
65
+ console.log('Attempting direct enableModule call...');
66
+ const safeWithSigner = new ethers_1.ethers.Contract(safeAddress, exports.SAFE_ABI, signer);
67
+ const tx = await safeWithSigner.enableModule(moduleAddress);
68
+ await tx.wait();
69
+ console.log('Module enabled via direct call');
70
+ return;
71
+ }
72
+ catch (error) {
73
+ console.log('Direct call failed, trying execTransaction approach...');
74
+ }
75
+ // If direct call fails, use execTransaction with proper signature
76
+ const safeNonce = await safeProxy.nonce();
77
+ const iface = new ethers_1.ethers.Interface(exports.SAFE_ABI);
78
+ const data = iface.encodeFunctionData('enableModule', [moduleAddress]);
79
+ const to = safeAddress;
80
+ const value = 0;
81
+ const operation = 0; // CALL
82
+ const safeTxGas = 0;
83
+ const baseGas = 0;
84
+ const gasPrice = 0;
85
+ const gasToken = ethers_1.ethers.ZeroAddress;
86
+ const refundReceiver = ethers_1.ethers.ZeroAddress;
87
+ // Use contract to compute tx hash to avoid mismatch
88
+ const safeTxHash = await safeProxy.getTransactionHash(to, value, data, operation, safeTxGas, baseGas, gasPrice, gasToken, refundReceiver, safeNonce);
89
+ // Sign the transaction hash using the connected wallet (personal_sign)
90
+ // For Gnosis Safe, personal_sign signatures must have v adjusted by +4 to mark EthSign
91
+ const rawSignature = await signer.signMessage(ethers_1.ethers.getBytes(safeTxHash));
92
+ const sigObj = ethers_1.ethers.Signature.from(rawSignature);
93
+ const adjustedV = sigObj.v + 4;
94
+ const signature = ethers_1.ethers.concat([
95
+ sigObj.r,
96
+ sigObj.s,
97
+ ethers_1.ethers.toBeHex(adjustedV, 1),
98
+ ]);
99
+ // Execute the transaction through Safe's execTransaction
100
+ const safeProxyWithSigner = new ethers_1.ethers.Contract(safeAddress, exports.SAFE_ABI, signer);
101
+ const tx = await safeProxyWithSigner.execTransaction(to, value, data, operation, safeTxGas, baseGas, gasPrice, gasToken, refundReceiver, signature);
102
+ await tx.wait();
103
+ // Verify module is enabled
104
+ const isNowEnabled = await safeProxy.isModuleEnabled(moduleAddress);
105
+ if (!isNowEnabled) {
106
+ throw new Error("Module verification failed");
107
+ }
108
+ console.log('Module enabled successfully via execTransaction');
109
+ }
package/dist/types.d.ts CHANGED
@@ -8,6 +8,21 @@ export interface ApiResponse<T> {
8
8
  data: T;
9
9
  error?: string;
10
10
  }
11
+ export type HttpStatusCode = 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 421 | 422 | 423 | 424 | 425 | 426 | 428 | 429 | 431 | 451 | 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 510 | 511;
12
+ export type ApiErrorCode = 'BAD_REQUEST' | 'UNAUTHORIZED' | 'PAYMENT_REQUIRED' | 'FORBIDDEN' | 'NOT_FOUND' | 'METHOD_NOT_ALLOWED' | 'NOT_ACCEPTABLE' | 'PROXY_AUTHENTICATION_REQUIRED' | 'REQUEST_TIMEOUT' | 'CONFLICT' | 'GONE' | 'LENGTH_REQUIRED' | 'PRECONDITION_FAILED' | 'PAYLOAD_TOO_LARGE' | 'URI_TOO_LONG' | 'UNSUPPORTED_MEDIA_TYPE' | 'RANGE_NOT_SATISFIABLE' | 'EXPECTATION_FAILED' | 'IM_A_TEAPOT' | 'MISDIRECTED_REQUEST' | 'UNPROCESSABLE_ENTITY' | 'LOCKED' | 'FAILED_DEPENDENCY' | 'TOO_EARLY' | 'UPGRADE_REQUIRED' | 'PRECONDITION_REQUIRED' | 'TOO_MANY_REQUESTS' | 'REQUEST_HEADER_FIELDS_TOO_LARGE' | 'UNAVAILABLE_FOR_LEGAL_REASONS' | 'INTERNAL_SERVER_ERROR' | 'NOT_IMPLEMENTED' | 'BAD_GATEWAY' | 'SERVICE_UNAVAILABLE' | 'GATEWAY_TIMEOUT' | 'HTTP_VERSION_NOT_SUPPORTED' | 'VARIANT_ALSO_NEGOTIATES' | 'INSUFFICIENT_STORAGE' | 'LOOP_DETECTED' | 'NOT_EXTENDED' | 'NETWORK_AUTHENTICATION_REQUIRED' | 'VALIDATION_ERROR' | 'NETWORK_ERROR' | 'AUTHENTICATION_ERROR' | 'CONTRACT_ERROR' | 'BALANCE_ERROR' | 'CONFIGURATION_ERROR' | 'RATE_LIMIT_EXCEEDED' | 'INSUFFICIENT_FUNDS' | 'INVALID_SIGNATURE' | 'TRANSACTION_FAILED' | 'CONTRACT_REVERT' | 'GAS_ESTIMATION_FAILED' | 'NONCE_TOO_LOW' | 'NONCE_TOO_HIGH' | 'REPLACEMENT_UNDERPRICED' | 'UNKNOWN_ERROR';
13
+ export interface ErrorResponse {
14
+ success: false;
15
+ error: string;
16
+ errorCode: ApiErrorCode;
17
+ httpStatusCode?: HttpStatusCode;
18
+ errorType: 'VALIDATION_ERROR' | 'NETWORK_ERROR' | 'AUTHENTICATION_ERROR' | 'CONTRACT_ERROR' | 'API_ERROR' | 'BALANCE_ERROR' | 'CONFIGURATION_ERROR' | 'UNKNOWN_ERROR';
19
+ details?: any;
20
+ }
21
+ export interface SuccessResponse<T> {
22
+ success: true;
23
+ data: T;
24
+ }
25
+ export type ApiResult<T> = SuccessResponse<T> | ErrorResponse;
11
26
  export declare enum JobType {
12
27
  Time = "time",
13
28
  Event = "event",
@@ -17,6 +32,7 @@ export declare enum ArgType {
17
32
  Static = "static",
18
33
  Dynamic = "dynamic"
19
34
  }
35
+ export type WalletMode = 'regular' | 'safe';
20
36
  export type CreateJobInput = (TimeBasedJobInput & {
21
37
  jobType: JobType.Time;
22
38
  argType: ArgType.Static | ArgType.Dynamic;
@@ -36,13 +52,19 @@ export interface TimeBasedJobInput {
36
52
  specificSchedule?: string;
37
53
  timezone: string;
38
54
  chainId: string;
39
- targetContractAddress: string;
40
- targetFunction: string;
41
- abi: string;
55
+ targetContractAddress?: string;
56
+ targetFunction?: string;
57
+ abi?: string;
42
58
  isImua?: boolean;
43
59
  arguments?: string[];
44
60
  dynamicArgumentsScriptUrl?: string;
45
61
  autotopupTG?: boolean;
62
+ walletMode?: WalletMode;
63
+ /**
64
+ * The Safe address to use when walletMode is 'safe'.
65
+ * Required if walletMode is 'safe'.
66
+ */
67
+ safeAddress: string;
46
68
  }
47
69
  export interface EventBasedJobInput {
48
70
  jobTitle: string;
@@ -53,13 +75,19 @@ export interface EventBasedJobInput {
53
75
  timezone: string;
54
76
  recurring?: boolean;
55
77
  chainId: string;
56
- targetContractAddress: string;
57
- targetFunction: string;
58
- abi: string;
78
+ targetContractAddress?: string;
79
+ targetFunction?: string;
80
+ abi?: string;
59
81
  isImua?: boolean;
60
82
  arguments?: string[];
61
83
  dynamicArgumentsScriptUrl?: string;
62
84
  autotopupTG?: boolean;
85
+ walletMode?: WalletMode;
86
+ /**
87
+ * The Safe address to use when walletMode is 'safe'.
88
+ * Required if walletMode is 'safe'.
89
+ */
90
+ safeAddress: string;
63
91
  }
64
92
  export interface ConditionBasedJobInput {
65
93
  jobTitle: string;
@@ -72,13 +100,19 @@ export interface ConditionBasedJobInput {
72
100
  timezone: string;
73
101
  recurring?: boolean;
74
102
  chainId: string;
75
- targetContractAddress: string;
76
- targetFunction: string;
77
- abi: string;
103
+ targetContractAddress?: string;
104
+ targetFunction?: string;
105
+ abi?: string;
78
106
  isImua?: boolean;
79
107
  arguments?: string[];
80
108
  dynamicArgumentsScriptUrl?: string;
81
109
  autotopupTG?: boolean;
110
+ walletMode?: WalletMode;
111
+ /**
112
+ * The Safe address to use when walletMode is 'safe'.
113
+ * Required if walletMode is 'safe'.
114
+ */
115
+ safeAddress: string;
82
116
  }
83
117
  export interface CreateJobData {
84
118
  job_id: string;
@@ -118,6 +152,10 @@ export interface JobResponse {
118
152
  success: boolean;
119
153
  data?: any;
120
154
  error?: string;
155
+ errorCode?: ApiErrorCode;
156
+ httpStatusCode?: HttpStatusCode;
157
+ errorType?: 'VALIDATION_ERROR' | 'NETWORK_ERROR' | 'AUTHENTICATION_ERROR' | 'CONTRACT_ERROR' | 'API_ERROR' | 'BALANCE_ERROR' | 'CONFIGURATION_ERROR' | 'UNKNOWN_ERROR';
158
+ details?: any;
121
159
  }
122
160
  export interface JobDataAPI {
123
161
  job_id: string;
@@ -209,6 +247,10 @@ export interface ConditionJobData {
209
247
  export interface JobResponseUser {
210
248
  success: boolean;
211
249
  error?: string;
250
+ errorCode?: ApiErrorCode;
251
+ httpStatusCode?: HttpStatusCode;
252
+ errorType?: 'VALIDATION_ERROR' | 'NETWORK_ERROR' | 'AUTHENTICATION_ERROR' | 'CONTRACT_ERROR' | 'API_ERROR' | 'BALANCE_ERROR' | 'CONFIGURATION_ERROR' | 'UNKNOWN_ERROR';
253
+ details?: any;
212
254
  jobs?: JobResponseAPI;
213
255
  }
214
256
  export interface JobResponseAPI {
@@ -1,4 +1,43 @@
1
+ import { ApiErrorCode, HttpStatusCode } from '../types';
1
2
  export declare class TriggerXError extends Error {
2
- constructor(message: string);
3
+ readonly errorCode: ApiErrorCode;
4
+ readonly httpStatusCode?: HttpStatusCode;
5
+ readonly errorType: 'VALIDATION_ERROR' | 'NETWORK_ERROR' | 'AUTHENTICATION_ERROR' | 'CONTRACT_ERROR' | 'API_ERROR' | 'BALANCE_ERROR' | 'CONFIGURATION_ERROR' | 'UNKNOWN_ERROR';
6
+ readonly details?: any;
7
+ constructor(message: string, errorCode: ApiErrorCode, errorType: 'VALIDATION_ERROR' | 'NETWORK_ERROR' | 'AUTHENTICATION_ERROR' | 'CONTRACT_ERROR' | 'API_ERROR' | 'BALANCE_ERROR' | 'CONFIGURATION_ERROR' | 'UNKNOWN_ERROR', details?: any, httpStatusCode?: HttpStatusCode);
3
8
  }
9
+ export declare const HTTP_STATUS_TO_ERROR_CODE: Record<HttpStatusCode, ApiErrorCode>;
10
+ export declare const ERROR_PATTERN_TO_CODE: Record<string, ApiErrorCode>;
4
11
  export declare function wrapError(error: unknown): TriggerXError;
12
+ export declare function extractHttpStatusCode(error: any): HttpStatusCode | undefined;
13
+ export declare function determineErrorCode(error: any, httpStatusCode?: HttpStatusCode): ApiErrorCode;
14
+ export declare class ValidationError extends TriggerXError {
15
+ readonly field: string;
16
+ constructor(field: string, message: string, details?: any, httpStatusCode?: HttpStatusCode);
17
+ }
18
+ export declare class NetworkError extends TriggerXError {
19
+ constructor(message: string, details?: any, httpStatusCode?: HttpStatusCode);
20
+ }
21
+ export declare class AuthenticationError extends TriggerXError {
22
+ constructor(message: string, details?: any, httpStatusCode?: HttpStatusCode);
23
+ }
24
+ export declare class ContractError extends TriggerXError {
25
+ constructor(message: string, details?: any, httpStatusCode?: HttpStatusCode);
26
+ }
27
+ export declare class ApiError extends TriggerXError {
28
+ constructor(message: string, details?: any, httpStatusCode?: HttpStatusCode);
29
+ }
30
+ export declare class BalanceError extends TriggerXError {
31
+ constructor(message: string, details?: any, httpStatusCode?: HttpStatusCode);
32
+ }
33
+ export declare class ConfigurationError extends TriggerXError {
34
+ constructor(message: string, details?: any, httpStatusCode?: HttpStatusCode);
35
+ }
36
+ export declare function createErrorResponse(error: TriggerXError | Error | unknown, fallbackMessage?: string): {
37
+ success: false;
38
+ error: string;
39
+ errorCode: ApiErrorCode;
40
+ httpStatusCode?: HttpStatusCode;
41
+ errorType: 'VALIDATION_ERROR' | 'NETWORK_ERROR' | 'AUTHENTICATION_ERROR' | 'CONTRACT_ERROR' | 'API_ERROR' | 'BALANCE_ERROR' | 'CONFIGURATION_ERROR' | 'UNKNOWN_ERROR';
42
+ details?: any;
43
+ };
@@ -1,17 +1,240 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.TriggerXError = void 0;
3
+ exports.ConfigurationError = exports.BalanceError = exports.ApiError = exports.ContractError = exports.AuthenticationError = exports.NetworkError = exports.ValidationError = exports.ERROR_PATTERN_TO_CODE = exports.HTTP_STATUS_TO_ERROR_CODE = exports.TriggerXError = void 0;
4
4
  exports.wrapError = wrapError;
5
+ exports.extractHttpStatusCode = extractHttpStatusCode;
6
+ exports.determineErrorCode = determineErrorCode;
7
+ exports.createErrorResponse = createErrorResponse;
5
8
  class TriggerXError extends Error {
6
- constructor(message) {
9
+ constructor(message, errorCode, errorType, details, httpStatusCode) {
7
10
  super(message);
8
11
  this.name = 'TriggerXError';
12
+ this.errorCode = errorCode;
13
+ this.errorType = errorType;
14
+ this.details = details;
15
+ this.httpStatusCode = httpStatusCode;
9
16
  }
10
17
  }
11
18
  exports.TriggerXError = TriggerXError;
19
+ // HTTP Status Code to Error Code Mapping
20
+ exports.HTTP_STATUS_TO_ERROR_CODE = {
21
+ // 4xx Client Errors
22
+ 400: 'BAD_REQUEST',
23
+ 401: 'UNAUTHORIZED',
24
+ 402: 'PAYMENT_REQUIRED',
25
+ 403: 'FORBIDDEN',
26
+ 404: 'NOT_FOUND',
27
+ 405: 'METHOD_NOT_ALLOWED',
28
+ 406: 'NOT_ACCEPTABLE',
29
+ 407: 'PROXY_AUTHENTICATION_REQUIRED',
30
+ 408: 'REQUEST_TIMEOUT',
31
+ 409: 'CONFLICT',
32
+ 410: 'GONE',
33
+ 411: 'LENGTH_REQUIRED',
34
+ 412: 'PRECONDITION_FAILED',
35
+ 413: 'PAYLOAD_TOO_LARGE',
36
+ 414: 'URI_TOO_LONG',
37
+ 415: 'UNSUPPORTED_MEDIA_TYPE',
38
+ 416: 'RANGE_NOT_SATISFIABLE',
39
+ 417: 'EXPECTATION_FAILED',
40
+ 418: 'IM_A_TEAPOT',
41
+ 421: 'MISDIRECTED_REQUEST',
42
+ 422: 'UNPROCESSABLE_ENTITY',
43
+ 423: 'LOCKED',
44
+ 424: 'FAILED_DEPENDENCY',
45
+ 425: 'TOO_EARLY',
46
+ 426: 'UPGRADE_REQUIRED',
47
+ 428: 'PRECONDITION_REQUIRED',
48
+ 429: 'TOO_MANY_REQUESTS',
49
+ 431: 'REQUEST_HEADER_FIELDS_TOO_LARGE',
50
+ 451: 'UNAVAILABLE_FOR_LEGAL_REASONS',
51
+ // 5xx Server Errors
52
+ 500: 'INTERNAL_SERVER_ERROR',
53
+ 501: 'NOT_IMPLEMENTED',
54
+ 502: 'BAD_GATEWAY',
55
+ 503: 'SERVICE_UNAVAILABLE',
56
+ 504: 'GATEWAY_TIMEOUT',
57
+ 505: 'HTTP_VERSION_NOT_SUPPORTED',
58
+ 506: 'VARIANT_ALSO_NEGOTIATES',
59
+ 507: 'INSUFFICIENT_STORAGE',
60
+ 508: 'LOOP_DETECTED',
61
+ 510: 'NOT_EXTENDED',
62
+ 511: 'NETWORK_AUTHENTICATION_REQUIRED'
63
+ };
64
+ // Error message patterns to error code mapping
65
+ exports.ERROR_PATTERN_TO_CODE = {
66
+ 'network': 'NETWORK_ERROR',
67
+ 'timeout': 'REQUEST_TIMEOUT',
68
+ 'connection': 'NETWORK_ERROR',
69
+ 'unauthorized': 'UNAUTHORIZED',
70
+ 'forbidden': 'FORBIDDEN',
71
+ 'not found': 'NOT_FOUND',
72
+ 'bad request': 'BAD_REQUEST',
73
+ 'validation': 'VALIDATION_ERROR',
74
+ 'invalid': 'VALIDATION_ERROR',
75
+ 'missing': 'VALIDATION_ERROR',
76
+ 'required': 'VALIDATION_ERROR',
77
+ 'insufficient': 'INSUFFICIENT_FUNDS',
78
+ 'balance': 'BALANCE_ERROR',
79
+ 'contract': 'CONTRACT_ERROR',
80
+ 'transaction': 'TRANSACTION_FAILED',
81
+ 'gas': 'GAS_ESTIMATION_FAILED',
82
+ 'nonce': 'NONCE_TOO_LOW',
83
+ 'revert': 'CONTRACT_REVERT',
84
+ 'rate limit': 'RATE_LIMIT_EXCEEDED',
85
+ 'too many': 'TOO_MANY_REQUESTS',
86
+ 'server error': 'INTERNAL_SERVER_ERROR',
87
+ 'service unavailable': 'SERVICE_UNAVAILABLE',
88
+ 'bad gateway': 'BAD_GATEWAY',
89
+ 'gateway timeout': 'GATEWAY_TIMEOUT'
90
+ };
12
91
  function wrapError(error) {
92
+ if (error instanceof TriggerXError) {
93
+ return error;
94
+ }
13
95
  if (error instanceof Error) {
14
- return new TriggerXError(error.message);
96
+ return new TriggerXError(error.message, 'UNKNOWN_ERROR', 'UNKNOWN_ERROR');
97
+ }
98
+ return new TriggerXError('Unknown error', 'UNKNOWN_ERROR', 'UNKNOWN_ERROR');
99
+ }
100
+ // Helper function to extract HTTP status code from error
101
+ function extractHttpStatusCode(error) {
102
+ if (error?.response?.status) {
103
+ return error.response.status;
104
+ }
105
+ if (error?.status) {
106
+ return error.status;
107
+ }
108
+ if (error?.code && typeof error.code === 'number') {
109
+ return error.code;
110
+ }
111
+ return undefined;
112
+ }
113
+ // Helper function to determine error code from error message and status
114
+ function determineErrorCode(error, httpStatusCode) {
115
+ // First check if we have an HTTP status code
116
+ if (httpStatusCode && exports.HTTP_STATUS_TO_ERROR_CODE[httpStatusCode]) {
117
+ return exports.HTTP_STATUS_TO_ERROR_CODE[httpStatusCode];
118
+ }
119
+ // Extract status code from error if not provided
120
+ const statusCode = httpStatusCode || extractHttpStatusCode(error);
121
+ if (statusCode && exports.HTTP_STATUS_TO_ERROR_CODE[statusCode]) {
122
+ return exports.HTTP_STATUS_TO_ERROR_CODE[statusCode];
123
+ }
124
+ // Check error message patterns
125
+ const message = error?.message?.toLowerCase() || '';
126
+ for (const [pattern, code] of Object.entries(exports.ERROR_PATTERN_TO_CODE)) {
127
+ if (message.includes(pattern)) {
128
+ return code;
129
+ }
130
+ }
131
+ return 'UNKNOWN_ERROR';
132
+ }
133
+ class ValidationError extends TriggerXError {
134
+ constructor(field, message, details, httpStatusCode) {
135
+ super(message, 'VALIDATION_ERROR', 'VALIDATION_ERROR', details, httpStatusCode);
136
+ this.name = 'ValidationError';
137
+ this.field = field;
138
+ }
139
+ }
140
+ exports.ValidationError = ValidationError;
141
+ class NetworkError extends TriggerXError {
142
+ constructor(message, details, httpStatusCode) {
143
+ super(message, 'NETWORK_ERROR', 'NETWORK_ERROR', details, httpStatusCode);
144
+ this.name = 'NetworkError';
145
+ }
146
+ }
147
+ exports.NetworkError = NetworkError;
148
+ class AuthenticationError extends TriggerXError {
149
+ constructor(message, details, httpStatusCode) {
150
+ super(message, 'AUTHENTICATION_ERROR', 'AUTHENTICATION_ERROR', details, httpStatusCode);
151
+ this.name = 'AuthenticationError';
152
+ }
153
+ }
154
+ exports.AuthenticationError = AuthenticationError;
155
+ class ContractError extends TriggerXError {
156
+ constructor(message, details, httpStatusCode) {
157
+ super(message, 'CONTRACT_ERROR', 'CONTRACT_ERROR', details, httpStatusCode);
158
+ this.name = 'ContractError';
159
+ }
160
+ }
161
+ exports.ContractError = ContractError;
162
+ class ApiError extends TriggerXError {
163
+ constructor(message, details, httpStatusCode) {
164
+ super(message, 'INTERNAL_SERVER_ERROR', 'API_ERROR', details, httpStatusCode);
165
+ this.name = 'ApiError';
166
+ }
167
+ }
168
+ exports.ApiError = ApiError;
169
+ class BalanceError extends TriggerXError {
170
+ constructor(message, details, httpStatusCode) {
171
+ super(message, 'BALANCE_ERROR', 'BALANCE_ERROR', details, httpStatusCode);
172
+ this.name = 'BalanceError';
173
+ }
174
+ }
175
+ exports.BalanceError = BalanceError;
176
+ class ConfigurationError extends TriggerXError {
177
+ constructor(message, details, httpStatusCode) {
178
+ super(message, 'CONFIGURATION_ERROR', 'CONFIGURATION_ERROR', details, httpStatusCode);
179
+ this.name = 'ConfigurationError';
180
+ }
181
+ }
182
+ exports.ConfigurationError = ConfigurationError;
183
+ // Helper function to create error response
184
+ function createErrorResponse(error, fallbackMessage = 'An unexpected error occurred') {
185
+ if (error instanceof TriggerXError) {
186
+ return {
187
+ success: false,
188
+ error: error.message,
189
+ errorCode: error.errorCode,
190
+ httpStatusCode: error.httpStatusCode,
191
+ errorType: error.errorType,
192
+ details: error.details
193
+ };
194
+ }
195
+ if (error instanceof Error) {
196
+ const httpStatusCode = extractHttpStatusCode(error);
197
+ const errorCode = determineErrorCode(error, httpStatusCode);
198
+ const errorType = getErrorTypeFromCode(errorCode);
199
+ return {
200
+ success: false,
201
+ error: error.message,
202
+ errorCode,
203
+ httpStatusCode,
204
+ errorType,
205
+ details: { originalError: error.name }
206
+ };
207
+ }
208
+ return {
209
+ success: false,
210
+ error: fallbackMessage,
211
+ errorCode: 'UNKNOWN_ERROR',
212
+ errorType: 'UNKNOWN_ERROR',
213
+ details: { originalError: String(error) }
214
+ };
215
+ }
216
+ // Helper function to determine error type from error code
217
+ function getErrorTypeFromCode(errorCode) {
218
+ if (errorCode === 'VALIDATION_ERROR' || errorCode === 'BAD_REQUEST' || errorCode === 'UNPROCESSABLE_ENTITY') {
219
+ return 'VALIDATION_ERROR';
220
+ }
221
+ if (errorCode === 'NETWORK_ERROR' || errorCode === 'REQUEST_TIMEOUT' || errorCode === 'SERVICE_UNAVAILABLE' || errorCode === 'BAD_GATEWAY' || errorCode === 'GATEWAY_TIMEOUT') {
222
+ return 'NETWORK_ERROR';
223
+ }
224
+ if (errorCode === 'AUTHENTICATION_ERROR' || errorCode === 'UNAUTHORIZED' || errorCode === 'FORBIDDEN' || errorCode === 'PROXY_AUTHENTICATION_REQUIRED') {
225
+ return 'AUTHENTICATION_ERROR';
226
+ }
227
+ if (errorCode === 'CONTRACT_ERROR' || errorCode === 'TRANSACTION_FAILED' || errorCode === 'CONTRACT_REVERT' || errorCode === 'GAS_ESTIMATION_FAILED' || errorCode === 'NONCE_TOO_LOW' || errorCode === 'NONCE_TOO_HIGH' || errorCode === 'REPLACEMENT_UNDERPRICED') {
228
+ return 'CONTRACT_ERROR';
229
+ }
230
+ if (errorCode === 'BALANCE_ERROR' || errorCode === 'INSUFFICIENT_FUNDS') {
231
+ return 'BALANCE_ERROR';
232
+ }
233
+ if (errorCode === 'CONFIGURATION_ERROR') {
234
+ return 'CONFIGURATION_ERROR';
235
+ }
236
+ if (errorCode.includes('API') || errorCode === 'INTERNAL_SERVER_ERROR' || errorCode === 'NOT_IMPLEMENTED' || errorCode === 'NOT_FOUND' || errorCode === 'METHOD_NOT_ALLOWED' || errorCode === 'CONFLICT' || errorCode === 'TOO_MANY_REQUESTS' || errorCode === 'RATE_LIMIT_EXCEEDED') {
237
+ return 'API_ERROR';
15
238
  }
16
- return new TriggerXError('Unknown error');
239
+ return 'UNKNOWN_ERROR';
17
240
  }
@@ -0,0 +1,5 @@
1
+ import { TimeBasedJobInput, EventBasedJobInput, ConditionBasedJobInput } from '../types';
2
+ export declare function validateTimeBasedJobInput(input: TimeBasedJobInput, argType: 'static' | 'dynamic' | 1 | 2 | undefined): void;
3
+ export declare function validateEventBasedJobInput(input: EventBasedJobInput, argType: 'static' | 'dynamic' | 1 | 2 | undefined): void;
4
+ export declare function validateConditionBasedJobInput(input: ConditionBasedJobInput, argType: 'static' | 'dynamic' | 1 | 2 | undefined): void;
5
+ export declare function validateJobInput(jobInput: TimeBasedJobInput | EventBasedJobInput | ConditionBasedJobInput, argType?: 'static' | 'dynamic' | 1 | 2): void;