@seljs/runtime 1.3.0-beta.24 → 1.3.0-beta.28
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/dist/environment/environment.cjs +7 -1
- package/dist/environment/environment.mjs +7 -1
- package/dist/errors/errors.cjs +18 -0
- package/dist/errors/errors.d.cts +30 -0
- package/dist/errors/errors.d.mts +30 -0
- package/dist/errors/errors.mjs +18 -0
- package/dist/execution/decode-revert.cjs +67 -0
- package/dist/execution/decode-revert.mjs +66 -0
- package/dist/execution/round-executor.cjs +14 -6
- package/dist/execution/round-executor.mjs +14 -6
- package/package.json +5 -5
|
@@ -194,10 +194,16 @@ var SELRuntime = class {
|
|
|
194
194
|
} else if (typeof error.failedCallIndex === "number") failedCall = collectedCalls[error.failedCallIndex] ?? failedCall;
|
|
195
195
|
}
|
|
196
196
|
if (!failedCall) throw error;
|
|
197
|
+
const revertFields = error instanceof require_errors.MulticallBatchError ? {
|
|
198
|
+
revertReason: error.revertReason,
|
|
199
|
+
revertData: error.revertData,
|
|
200
|
+
decodedError: error.decodedError
|
|
201
|
+
} : {};
|
|
197
202
|
throw new require_errors.SELContractError(`Contract call failed: ${failedCall.contract}.${failedCall.method}`, {
|
|
198
203
|
cause: error,
|
|
199
204
|
contractName: failedCall.contract,
|
|
200
|
-
methodName: failedCall.method
|
|
205
|
+
methodName: failedCall.method,
|
|
206
|
+
...revertFields
|
|
201
207
|
});
|
|
202
208
|
}
|
|
203
209
|
return {
|
|
@@ -193,10 +193,16 @@ var SELRuntime = class {
|
|
|
193
193
|
} else if (typeof error.failedCallIndex === "number") failedCall = collectedCalls[error.failedCallIndex] ?? failedCall;
|
|
194
194
|
}
|
|
195
195
|
if (!failedCall) throw error;
|
|
196
|
+
const revertFields = error instanceof MulticallBatchError ? {
|
|
197
|
+
revertReason: error.revertReason,
|
|
198
|
+
revertData: error.revertData,
|
|
199
|
+
decodedError: error.decodedError
|
|
200
|
+
} : {};
|
|
196
201
|
throw new SELContractError(`Contract call failed: ${failedCall.contract}.${failedCall.method}`, {
|
|
197
202
|
cause: error,
|
|
198
203
|
contractName: failedCall.contract,
|
|
199
|
-
methodName: failedCall.method
|
|
204
|
+
methodName: failedCall.method,
|
|
205
|
+
...revertFields
|
|
200
206
|
});
|
|
201
207
|
}
|
|
202
208
|
return {
|
package/dist/errors/errors.cjs
CHANGED
|
@@ -4,14 +4,23 @@ let _seljs_common = require("@seljs/common");
|
|
|
4
4
|
/**
|
|
5
5
|
* Thrown when contract validation or execution fails.
|
|
6
6
|
* Includes optional contract name and method name for context.
|
|
7
|
+
* When the failure is a contract revert, the decoded revert reason and raw
|
|
8
|
+
* revert data are exposed on `revertReason` / `revertData`, and `decodedError`
|
|
9
|
+
* carries any matched custom-error name + args from the contract's ABI.
|
|
7
10
|
*/
|
|
8
11
|
var SELContractError = class extends _seljs_common.SELError {
|
|
9
12
|
contractName;
|
|
10
13
|
methodName;
|
|
14
|
+
revertReason;
|
|
15
|
+
revertData;
|
|
16
|
+
decodedError;
|
|
11
17
|
constructor(message, options) {
|
|
12
18
|
super(message, { cause: options?.cause });
|
|
13
19
|
this.contractName = options?.contractName;
|
|
14
20
|
this.methodName = options?.methodName;
|
|
21
|
+
this.revertReason = options?.revertReason;
|
|
22
|
+
this.revertData = options?.revertData;
|
|
23
|
+
this.decodedError = options?.decodedError;
|
|
15
24
|
}
|
|
16
25
|
};
|
|
17
26
|
/**
|
|
@@ -43,16 +52,25 @@ var ExecutionLimitError = class extends _seljs_common.SELError {
|
|
|
43
52
|
/**
|
|
44
53
|
* Thrown when a Multicall3 batch execution fails.
|
|
45
54
|
* Includes the failed call index and optional contract name/method name for context.
|
|
55
|
+
* When an individual sub-call reverts, `revertReason` / `revertData` carry the
|
|
56
|
+
* decoded reason text and raw return data, and `decodedError` carries any
|
|
57
|
+
* matched custom-error name + args from the contract's ABI.
|
|
46
58
|
*/
|
|
47
59
|
var MulticallBatchError = class extends _seljs_common.SELError {
|
|
48
60
|
failedCallIndex;
|
|
49
61
|
contractName;
|
|
50
62
|
methodName;
|
|
63
|
+
revertReason;
|
|
64
|
+
revertData;
|
|
65
|
+
decodedError;
|
|
51
66
|
constructor(message, options) {
|
|
52
67
|
super(message, { cause: options?.cause });
|
|
53
68
|
this.failedCallIndex = options?.failedCallIndex;
|
|
54
69
|
this.contractName = options?.contractName;
|
|
55
70
|
this.methodName = options?.methodName;
|
|
71
|
+
this.revertReason = options?.revertReason;
|
|
72
|
+
this.revertData = options?.revertData;
|
|
73
|
+
this.decodedError = options?.decodedError;
|
|
56
74
|
}
|
|
57
75
|
};
|
|
58
76
|
/**
|
package/dist/errors/errors.d.cts
CHANGED
|
@@ -5,14 +5,29 @@ import { SELError, SELEvaluationError } from "@seljs/common";
|
|
|
5
5
|
/**
|
|
6
6
|
* Thrown when contract validation or execution fails.
|
|
7
7
|
* Includes optional contract name and method name for context.
|
|
8
|
+
* When the failure is a contract revert, the decoded revert reason and raw
|
|
9
|
+
* revert data are exposed on `revertReason` / `revertData`, and `decodedError`
|
|
10
|
+
* carries any matched custom-error name + args from the contract's ABI.
|
|
8
11
|
*/
|
|
9
12
|
declare class SELContractError extends SELError {
|
|
10
13
|
readonly contractName?: string;
|
|
11
14
|
readonly methodName?: string;
|
|
15
|
+
readonly revertReason?: string;
|
|
16
|
+
readonly revertData?: `0x${string}`;
|
|
17
|
+
readonly decodedError?: {
|
|
18
|
+
name: string;
|
|
19
|
+
args: readonly unknown[];
|
|
20
|
+
};
|
|
12
21
|
constructor(message: string, options?: {
|
|
13
22
|
cause?: unknown;
|
|
14
23
|
contractName?: string;
|
|
15
24
|
methodName?: string;
|
|
25
|
+
revertReason?: string;
|
|
26
|
+
revertData?: `0x${string}`;
|
|
27
|
+
decodedError?: {
|
|
28
|
+
name: string;
|
|
29
|
+
args: readonly unknown[];
|
|
30
|
+
};
|
|
16
31
|
});
|
|
17
32
|
}
|
|
18
33
|
/**
|
|
@@ -44,16 +59,31 @@ declare class ExecutionLimitError extends SELError {
|
|
|
44
59
|
/**
|
|
45
60
|
* Thrown when a Multicall3 batch execution fails.
|
|
46
61
|
* Includes the failed call index and optional contract name/method name for context.
|
|
62
|
+
* When an individual sub-call reverts, `revertReason` / `revertData` carry the
|
|
63
|
+
* decoded reason text and raw return data, and `decodedError` carries any
|
|
64
|
+
* matched custom-error name + args from the contract's ABI.
|
|
47
65
|
*/
|
|
48
66
|
declare class MulticallBatchError extends SELError {
|
|
49
67
|
readonly failedCallIndex?: number;
|
|
50
68
|
readonly contractName?: string;
|
|
51
69
|
readonly methodName?: string;
|
|
70
|
+
readonly revertReason?: string;
|
|
71
|
+
readonly revertData?: `0x${string}`;
|
|
72
|
+
readonly decodedError?: {
|
|
73
|
+
name: string;
|
|
74
|
+
args: readonly unknown[];
|
|
75
|
+
};
|
|
52
76
|
constructor(message: string, options?: {
|
|
53
77
|
cause?: unknown;
|
|
54
78
|
failedCallIndex?: number;
|
|
55
79
|
contractName?: string;
|
|
56
80
|
methodName?: string;
|
|
81
|
+
revertReason?: string;
|
|
82
|
+
revertData?: `0x${string}`;
|
|
83
|
+
decodedError?: {
|
|
84
|
+
name: string;
|
|
85
|
+
args: readonly unknown[];
|
|
86
|
+
};
|
|
57
87
|
});
|
|
58
88
|
}
|
|
59
89
|
/**
|
package/dist/errors/errors.d.mts
CHANGED
|
@@ -5,14 +5,29 @@ import { SELError as SELError$1, SELEvaluationError } from "@seljs/common";
|
|
|
5
5
|
/**
|
|
6
6
|
* Thrown when contract validation or execution fails.
|
|
7
7
|
* Includes optional contract name and method name for context.
|
|
8
|
+
* When the failure is a contract revert, the decoded revert reason and raw
|
|
9
|
+
* revert data are exposed on `revertReason` / `revertData`, and `decodedError`
|
|
10
|
+
* carries any matched custom-error name + args from the contract's ABI.
|
|
8
11
|
*/
|
|
9
12
|
declare class SELContractError extends SELError$1 {
|
|
10
13
|
readonly contractName?: string;
|
|
11
14
|
readonly methodName?: string;
|
|
15
|
+
readonly revertReason?: string;
|
|
16
|
+
readonly revertData?: `0x${string}`;
|
|
17
|
+
readonly decodedError?: {
|
|
18
|
+
name: string;
|
|
19
|
+
args: readonly unknown[];
|
|
20
|
+
};
|
|
12
21
|
constructor(message: string, options?: {
|
|
13
22
|
cause?: unknown;
|
|
14
23
|
contractName?: string;
|
|
15
24
|
methodName?: string;
|
|
25
|
+
revertReason?: string;
|
|
26
|
+
revertData?: `0x${string}`;
|
|
27
|
+
decodedError?: {
|
|
28
|
+
name: string;
|
|
29
|
+
args: readonly unknown[];
|
|
30
|
+
};
|
|
16
31
|
});
|
|
17
32
|
}
|
|
18
33
|
/**
|
|
@@ -44,16 +59,31 @@ declare class ExecutionLimitError extends SELError$1 {
|
|
|
44
59
|
/**
|
|
45
60
|
* Thrown when a Multicall3 batch execution fails.
|
|
46
61
|
* Includes the failed call index and optional contract name/method name for context.
|
|
62
|
+
* When an individual sub-call reverts, `revertReason` / `revertData` carry the
|
|
63
|
+
* decoded reason text and raw return data, and `decodedError` carries any
|
|
64
|
+
* matched custom-error name + args from the contract's ABI.
|
|
47
65
|
*/
|
|
48
66
|
declare class MulticallBatchError extends SELError$1 {
|
|
49
67
|
readonly failedCallIndex?: number;
|
|
50
68
|
readonly contractName?: string;
|
|
51
69
|
readonly methodName?: string;
|
|
70
|
+
readonly revertReason?: string;
|
|
71
|
+
readonly revertData?: `0x${string}`;
|
|
72
|
+
readonly decodedError?: {
|
|
73
|
+
name: string;
|
|
74
|
+
args: readonly unknown[];
|
|
75
|
+
};
|
|
52
76
|
constructor(message: string, options?: {
|
|
53
77
|
cause?: unknown;
|
|
54
78
|
failedCallIndex?: number;
|
|
55
79
|
contractName?: string;
|
|
56
80
|
methodName?: string;
|
|
81
|
+
revertReason?: string;
|
|
82
|
+
revertData?: `0x${string}`;
|
|
83
|
+
decodedError?: {
|
|
84
|
+
name: string;
|
|
85
|
+
args: readonly unknown[];
|
|
86
|
+
};
|
|
57
87
|
});
|
|
58
88
|
}
|
|
59
89
|
/**
|
package/dist/errors/errors.mjs
CHANGED
|
@@ -3,14 +3,23 @@ import { SELError as SELError$1, SELEvaluationError } from "@seljs/common";
|
|
|
3
3
|
/**
|
|
4
4
|
* Thrown when contract validation or execution fails.
|
|
5
5
|
* Includes optional contract name and method name for context.
|
|
6
|
+
* When the failure is a contract revert, the decoded revert reason and raw
|
|
7
|
+
* revert data are exposed on `revertReason` / `revertData`, and `decodedError`
|
|
8
|
+
* carries any matched custom-error name + args from the contract's ABI.
|
|
6
9
|
*/
|
|
7
10
|
var SELContractError = class extends SELError$1 {
|
|
8
11
|
contractName;
|
|
9
12
|
methodName;
|
|
13
|
+
revertReason;
|
|
14
|
+
revertData;
|
|
15
|
+
decodedError;
|
|
10
16
|
constructor(message, options) {
|
|
11
17
|
super(message, { cause: options?.cause });
|
|
12
18
|
this.contractName = options?.contractName;
|
|
13
19
|
this.methodName = options?.methodName;
|
|
20
|
+
this.revertReason = options?.revertReason;
|
|
21
|
+
this.revertData = options?.revertData;
|
|
22
|
+
this.decodedError = options?.decodedError;
|
|
14
23
|
}
|
|
15
24
|
};
|
|
16
25
|
/**
|
|
@@ -42,16 +51,25 @@ var ExecutionLimitError = class extends SELError$1 {
|
|
|
42
51
|
/**
|
|
43
52
|
* Thrown when a Multicall3 batch execution fails.
|
|
44
53
|
* Includes the failed call index and optional contract name/method name for context.
|
|
54
|
+
* When an individual sub-call reverts, `revertReason` / `revertData` carry the
|
|
55
|
+
* decoded reason text and raw return data, and `decodedError` carries any
|
|
56
|
+
* matched custom-error name + args from the contract's ABI.
|
|
45
57
|
*/
|
|
46
58
|
var MulticallBatchError = class extends SELError$1 {
|
|
47
59
|
failedCallIndex;
|
|
48
60
|
contractName;
|
|
49
61
|
methodName;
|
|
62
|
+
revertReason;
|
|
63
|
+
revertData;
|
|
64
|
+
decodedError;
|
|
50
65
|
constructor(message, options) {
|
|
51
66
|
super(message, { cause: options?.cause });
|
|
52
67
|
this.failedCallIndex = options?.failedCallIndex;
|
|
53
68
|
this.contractName = options?.contractName;
|
|
54
69
|
this.methodName = options?.methodName;
|
|
70
|
+
this.revertReason = options?.revertReason;
|
|
71
|
+
this.revertData = options?.revertData;
|
|
72
|
+
this.decodedError = options?.decodedError;
|
|
55
73
|
}
|
|
56
74
|
};
|
|
57
75
|
/**
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
require("../_virtual/_rolldown/runtime.cjs");
|
|
2
|
+
let ox = require("ox");
|
|
3
|
+
//#region src/execution/decode-revert.ts
|
|
4
|
+
const ERROR_STRING_SELECTOR = "0x08c379a0";
|
|
5
|
+
const PANIC_SELECTOR = "0x4e487b71";
|
|
6
|
+
const PANIC_CODES = {
|
|
7
|
+
0: "generic panic",
|
|
8
|
+
1: "assertion failed",
|
|
9
|
+
17: "arithmetic overflow or underflow",
|
|
10
|
+
18: "division or modulo by zero",
|
|
11
|
+
33: "enum conversion out of bounds",
|
|
12
|
+
34: "incorrectly encoded storage byte array",
|
|
13
|
+
49: "pop on empty array",
|
|
14
|
+
50: "array index out of bounds",
|
|
15
|
+
65: "excessive memory allocation",
|
|
16
|
+
81: "zero-initialized internal function type"
|
|
17
|
+
};
|
|
18
|
+
const errorStringAbi = ox.AbiError.from("error Error(string reason)");
|
|
19
|
+
const panicAbi = ox.AbiError.from("error Panic(uint256 code)");
|
|
20
|
+
function decodeRevertData(data, abi) {
|
|
21
|
+
if (data === "0x" || data.length < 10) return { data };
|
|
22
|
+
const selector = data.slice(0, 10).toLowerCase();
|
|
23
|
+
if (selector === ERROR_STRING_SELECTOR) try {
|
|
24
|
+
return {
|
|
25
|
+
data,
|
|
26
|
+
reason: ox.AbiError.decode(errorStringAbi, data)
|
|
27
|
+
};
|
|
28
|
+
} catch {
|
|
29
|
+
return { data };
|
|
30
|
+
}
|
|
31
|
+
if (selector === PANIC_SELECTOR) try {
|
|
32
|
+
const code = ox.AbiError.decode(panicAbi, data);
|
|
33
|
+
const numeric = Number(code);
|
|
34
|
+
return {
|
|
35
|
+
data,
|
|
36
|
+
reason: `Panic: ${PANIC_CODES[numeric] ?? `panic code 0x${numeric.toString(16)}`}`
|
|
37
|
+
};
|
|
38
|
+
} catch {
|
|
39
|
+
return { data };
|
|
40
|
+
}
|
|
41
|
+
try {
|
|
42
|
+
const error = ox.AbiError.fromAbi(abi, data);
|
|
43
|
+
const decoded = ox.AbiError.decode(error, data);
|
|
44
|
+
const args = decoded === void 0 ? [] : Array.isArray(decoded) ? decoded : [decoded];
|
|
45
|
+
const formattedArgs = args.map(formatArg).join(", ");
|
|
46
|
+
return {
|
|
47
|
+
data,
|
|
48
|
+
reason: `${error.name}(${formattedArgs})`,
|
|
49
|
+
decodedError: {
|
|
50
|
+
name: error.name,
|
|
51
|
+
args
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
} catch {
|
|
55
|
+
return { data };
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
function formatArg(arg) {
|
|
59
|
+
if (typeof arg === "bigint") return arg.toString();
|
|
60
|
+
if (typeof arg === "string") return arg;
|
|
61
|
+
if (typeof arg === "number" || typeof arg === "boolean" || arg === null || arg === void 0) return String(arg);
|
|
62
|
+
if (Array.isArray(arg)) return `[${arg.map(formatArg).join(", ")}]`;
|
|
63
|
+
if (typeof arg === "object") return `{${Object.entries(arg).map(([k, v]) => `${k}: ${formatArg(v)}`).join(", ")}}`;
|
|
64
|
+
return "";
|
|
65
|
+
}
|
|
66
|
+
//#endregion
|
|
67
|
+
exports.decodeRevertData = decodeRevertData;
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { AbiError } from "ox";
|
|
2
|
+
//#region src/execution/decode-revert.ts
|
|
3
|
+
const ERROR_STRING_SELECTOR = "0x08c379a0";
|
|
4
|
+
const PANIC_SELECTOR = "0x4e487b71";
|
|
5
|
+
const PANIC_CODES = {
|
|
6
|
+
0: "generic panic",
|
|
7
|
+
1: "assertion failed",
|
|
8
|
+
17: "arithmetic overflow or underflow",
|
|
9
|
+
18: "division or modulo by zero",
|
|
10
|
+
33: "enum conversion out of bounds",
|
|
11
|
+
34: "incorrectly encoded storage byte array",
|
|
12
|
+
49: "pop on empty array",
|
|
13
|
+
50: "array index out of bounds",
|
|
14
|
+
65: "excessive memory allocation",
|
|
15
|
+
81: "zero-initialized internal function type"
|
|
16
|
+
};
|
|
17
|
+
const errorStringAbi = AbiError.from("error Error(string reason)");
|
|
18
|
+
const panicAbi = AbiError.from("error Panic(uint256 code)");
|
|
19
|
+
function decodeRevertData(data, abi) {
|
|
20
|
+
if (data === "0x" || data.length < 10) return { data };
|
|
21
|
+
const selector = data.slice(0, 10).toLowerCase();
|
|
22
|
+
if (selector === ERROR_STRING_SELECTOR) try {
|
|
23
|
+
return {
|
|
24
|
+
data,
|
|
25
|
+
reason: AbiError.decode(errorStringAbi, data)
|
|
26
|
+
};
|
|
27
|
+
} catch {
|
|
28
|
+
return { data };
|
|
29
|
+
}
|
|
30
|
+
if (selector === PANIC_SELECTOR) try {
|
|
31
|
+
const code = AbiError.decode(panicAbi, data);
|
|
32
|
+
const numeric = Number(code);
|
|
33
|
+
return {
|
|
34
|
+
data,
|
|
35
|
+
reason: `Panic: ${PANIC_CODES[numeric] ?? `panic code 0x${numeric.toString(16)}`}`
|
|
36
|
+
};
|
|
37
|
+
} catch {
|
|
38
|
+
return { data };
|
|
39
|
+
}
|
|
40
|
+
try {
|
|
41
|
+
const error = AbiError.fromAbi(abi, data);
|
|
42
|
+
const decoded = AbiError.decode(error, data);
|
|
43
|
+
const args = decoded === void 0 ? [] : Array.isArray(decoded) ? decoded : [decoded];
|
|
44
|
+
const formattedArgs = args.map(formatArg).join(", ");
|
|
45
|
+
return {
|
|
46
|
+
data,
|
|
47
|
+
reason: `${error.name}(${formattedArgs})`,
|
|
48
|
+
decodedError: {
|
|
49
|
+
name: error.name,
|
|
50
|
+
args
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
} catch {
|
|
54
|
+
return { data };
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
function formatArg(arg) {
|
|
58
|
+
if (typeof arg === "bigint") return arg.toString();
|
|
59
|
+
if (typeof arg === "string") return arg;
|
|
60
|
+
if (typeof arg === "number" || typeof arg === "boolean" || arg === null || arg === void 0) return String(arg);
|
|
61
|
+
if (Array.isArray(arg)) return `[${arg.map(formatArg).join(", ")}]`;
|
|
62
|
+
if (typeof arg === "object") return `{${Object.entries(arg).map(([k, v]) => `${k}: ${formatArg(v)}`).join(", ")}}`;
|
|
63
|
+
return "";
|
|
64
|
+
}
|
|
65
|
+
//#endregion
|
|
66
|
+
export { decodeRevertData };
|
|
@@ -2,6 +2,7 @@ require("../_virtual/_rolldown/runtime.cjs");
|
|
|
2
2
|
const require_errors = require("../errors/errors.cjs");
|
|
3
3
|
require("../errors/index.cjs");
|
|
4
4
|
const require_debug = require("../debug.cjs");
|
|
5
|
+
const require_decode_revert = require("./decode-revert.cjs");
|
|
5
6
|
let ox = require("ox");
|
|
6
7
|
//#region src/execution/round-executor.ts
|
|
7
8
|
const debug = require_debug.createLogger("execute:round");
|
|
@@ -26,7 +27,7 @@ var RoundExecutor = class {
|
|
|
26
27
|
const resolvedArgs = this.resolveArgs(call.args, context);
|
|
27
28
|
encodedCalls.push({
|
|
28
29
|
target: contract.address,
|
|
29
|
-
allowFailure:
|
|
30
|
+
allowFailure: true,
|
|
30
31
|
callData: ox.AbiFunction.encodeData(contract.abi, call.method, resolvedArgs)
|
|
31
32
|
});
|
|
32
33
|
}
|
|
@@ -45,11 +46,18 @@ var RoundExecutor = class {
|
|
|
45
46
|
const contract = this.contracts.get(call.contract);
|
|
46
47
|
if (!contract) throw new Error(`No ABI registered for contract "${call.contract}"`);
|
|
47
48
|
const result = results[i];
|
|
48
|
-
if (!result?.success)
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
49
|
+
if (!result?.success) {
|
|
50
|
+
const decoded = require_decode_revert.decodeRevertData(result?.returnData ?? "0x", contract.abi);
|
|
51
|
+
const suffix = decoded.reason ? ` — ${decoded.reason}` : "";
|
|
52
|
+
throw new require_errors.MulticallBatchError(`Call failed: ${call.contract}.${call.method}${suffix}`, {
|
|
53
|
+
failedCallIndex: i,
|
|
54
|
+
contractName: call.contract,
|
|
55
|
+
methodName: call.method,
|
|
56
|
+
revertReason: decoded.reason,
|
|
57
|
+
revertData: decoded.data,
|
|
58
|
+
decodedError: decoded.decodedError
|
|
59
|
+
});
|
|
60
|
+
}
|
|
53
61
|
const decoded = ox.AbiFunction.decodeResult(contract.abi, call.method, result.returnData);
|
|
54
62
|
debug("decoded %s.%s -> %o", call.contract, call.method, decoded);
|
|
55
63
|
this.cache.set(call.id, decoded);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { MulticallBatchError } from "../errors/errors.mjs";
|
|
2
2
|
import "../errors/index.mjs";
|
|
3
3
|
import { createLogger } from "../debug.mjs";
|
|
4
|
+
import { decodeRevertData } from "./decode-revert.mjs";
|
|
4
5
|
import { AbiFunction } from "ox";
|
|
5
6
|
//#region src/execution/round-executor.ts
|
|
6
7
|
const debug = createLogger("execute:round");
|
|
@@ -25,7 +26,7 @@ var RoundExecutor = class {
|
|
|
25
26
|
const resolvedArgs = this.resolveArgs(call.args, context);
|
|
26
27
|
encodedCalls.push({
|
|
27
28
|
target: contract.address,
|
|
28
|
-
allowFailure:
|
|
29
|
+
allowFailure: true,
|
|
29
30
|
callData: AbiFunction.encodeData(contract.abi, call.method, resolvedArgs)
|
|
30
31
|
});
|
|
31
32
|
}
|
|
@@ -44,11 +45,18 @@ var RoundExecutor = class {
|
|
|
44
45
|
const contract = this.contracts.get(call.contract);
|
|
45
46
|
if (!contract) throw new Error(`No ABI registered for contract "${call.contract}"`);
|
|
46
47
|
const result = results[i];
|
|
47
|
-
if (!result?.success)
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
48
|
+
if (!result?.success) {
|
|
49
|
+
const decoded = decodeRevertData(result?.returnData ?? "0x", contract.abi);
|
|
50
|
+
const suffix = decoded.reason ? ` — ${decoded.reason}` : "";
|
|
51
|
+
throw new MulticallBatchError(`Call failed: ${call.contract}.${call.method}${suffix}`, {
|
|
52
|
+
failedCallIndex: i,
|
|
53
|
+
contractName: call.contract,
|
|
54
|
+
methodName: call.method,
|
|
55
|
+
revertReason: decoded.reason,
|
|
56
|
+
revertData: decoded.data,
|
|
57
|
+
decodedError: decoded.decodedError
|
|
58
|
+
});
|
|
59
|
+
}
|
|
52
60
|
const decoded = AbiFunction.decodeResult(contract.abi, call.method, result.returnData);
|
|
53
61
|
debug("decoded %s.%s -> %o", call.contract, call.method, decoded);
|
|
54
62
|
this.cache.set(call.id, decoded);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@seljs/runtime",
|
|
3
|
-
"version": "1.3.0-beta.
|
|
3
|
+
"version": "1.3.0-beta.28",
|
|
4
4
|
"repository": {
|
|
5
5
|
"url": "https://github.com/abinnovision/seljs"
|
|
6
6
|
},
|
|
@@ -50,11 +50,11 @@
|
|
|
50
50
|
},
|
|
51
51
|
"dependencies": {
|
|
52
52
|
"@marcbachmann/cel-js": "^7.5.3",
|
|
53
|
-
"@seljs/checker": "1.3.0-beta.
|
|
54
|
-
"@seljs/common": "1.3.0-beta.
|
|
55
|
-
"@seljs/env": "1.3.0-beta.
|
|
53
|
+
"@seljs/checker": "1.3.0-beta.28",
|
|
54
|
+
"@seljs/common": "1.3.0-beta.28",
|
|
55
|
+
"@seljs/env": "1.3.0-beta.28",
|
|
56
56
|
"@seljs/schema": "1.2.0",
|
|
57
|
-
"@seljs/types": "1.3.0-beta.
|
|
57
|
+
"@seljs/types": "1.3.0-beta.28",
|
|
58
58
|
"debug": "^4.4.3",
|
|
59
59
|
"ox": "^0.14.10"
|
|
60
60
|
},
|