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.
- package/README.md +95 -0
- package/dist/api/checkTgBalance.d.ts +9 -2
- package/dist/api/checkTgBalance.js +43 -24
- package/dist/api/deleteJob.d.ts +7 -1
- package/dist/api/deleteJob.js +29 -3
- package/dist/api/getJobDataById.d.ts +8 -1
- package/dist/api/getJobDataById.js +27 -3
- package/dist/api/getUserData.d.ts +8 -1
- package/dist/api/getUserData.js +27 -3
- package/dist/api/getjob.js +20 -2
- package/dist/api/jobs.js +141 -35
- package/dist/api/safeWallet.d.ts +8 -0
- package/dist/api/safeWallet.js +31 -0
- package/dist/api/topupTg.d.ts +8 -1
- package/dist/api/topupTg.js +39 -11
- package/dist/api/withdrawTg.d.ts +9 -2
- package/dist/api/withdrawTg.js +38 -13
- package/dist/config.d.ts +6 -0
- package/dist/config.js +6 -0
- package/dist/contracts/index.d.ts +3 -0
- package/dist/contracts/index.js +4 -0
- package/dist/contracts/safe/SafeFactory.d.ts +3 -0
- package/dist/contracts/safe/SafeFactory.js +33 -0
- package/dist/contracts/safe/SafeWallet.d.ts +6 -0
- package/dist/contracts/safe/SafeWallet.js +109 -0
- package/dist/types.d.ts +51 -9
- package/dist/utils/errors.d.ts +40 -1
- package/dist/utils/errors.js +227 -4
- package/dist/utils/validation.d.ts +5 -0
- package/dist/utils/validation.js +212 -0
- package/package.json +3 -3
|
@@ -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
|
|
40
|
-
targetFunction
|
|
41
|
-
abi
|
|
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
|
|
57
|
-
targetFunction
|
|
58
|
-
abi
|
|
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
|
|
76
|
-
targetFunction
|
|
77
|
-
abi
|
|
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 {
|
package/dist/utils/errors.d.ts
CHANGED
|
@@ -1,4 +1,43 @@
|
|
|
1
|
+
import { ApiErrorCode, HttpStatusCode } from '../types';
|
|
1
2
|
export declare class TriggerXError extends Error {
|
|
2
|
-
|
|
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
|
+
};
|
package/dist/utils/errors.js
CHANGED
|
@@ -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
|
|
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;
|