@seljs/runtime 1.0.0 → 1.0.1-beta.9
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/_virtual/_rolldown/runtime.cjs +23 -0
- package/dist/analysis/call-collector.cjs +233 -0
- package/dist/analysis/call-collector.mjs +232 -0
- package/dist/analysis/dependency-analyzer.cjs +68 -0
- package/dist/analysis/dependency-analyzer.mjs +68 -0
- package/dist/analysis/round-planner.cjs +65 -0
- package/dist/analysis/round-planner.mjs +65 -0
- package/dist/analysis/types.d.cts +115 -0
- package/dist/analysis/types.d.mts +115 -0
- package/dist/debug.cjs +17 -0
- package/dist/debug.mjs +15 -0
- package/dist/environment/context.cjs +11 -0
- package/dist/environment/context.mjs +11 -0
- package/dist/environment/contract-caller.cjs +81 -0
- package/dist/environment/contract-caller.mjs +77 -0
- package/dist/environment/environment.cjs +254 -0
- package/dist/environment/environment.d.cts +84 -0
- package/dist/environment/environment.d.mts +84 -0
- package/dist/environment/environment.mjs +252 -0
- package/dist/environment/error-wrapper.cjs +29 -0
- package/dist/environment/error-wrapper.mjs +27 -0
- package/dist/environment/index.cjs +1 -0
- package/dist/environment/index.d.mts +2 -0
- package/dist/environment/index.mjs +2 -0
- package/dist/environment/replay-cache.cjs +48 -0
- package/dist/environment/replay-cache.mjs +47 -0
- package/dist/environment/types.d.cts +60 -0
- package/dist/environment/types.d.mts +60 -0
- package/dist/errors/errors.cjs +68 -0
- package/dist/errors/errors.d.cts +64 -0
- package/dist/errors/errors.d.mts +64 -0
- package/dist/errors/errors.mjs +63 -0
- package/dist/errors/index.cjs +3 -0
- package/dist/errors/index.d.mts +1 -0
- package/dist/errors/index.mjs +2 -0
- package/dist/execution/multi-round-executor.cjs +45 -0
- package/dist/execution/multi-round-executor.mjs +44 -0
- package/dist/execution/multicall-batcher.cjs +51 -0
- package/dist/execution/multicall-batcher.mjs +50 -0
- package/dist/execution/multicall.cjs +39 -0
- package/dist/execution/multicall.mjs +38 -0
- package/dist/execution/result-cache.cjs +63 -0
- package/dist/execution/result-cache.mjs +63 -0
- package/dist/execution/round-executor.cjs +81 -0
- package/dist/execution/round-executor.mjs +80 -0
- package/dist/execution/types.d.cts +58 -0
- package/dist/execution/types.d.mts +58 -0
- package/dist/factory.cjs +6 -0
- package/dist/factory.d.cts +7 -0
- package/dist/factory.d.mts +6 -0
- package/dist/factory.mjs +6 -0
- package/dist/index.cjs +18 -0
- package/dist/index.d.cts +7 -0
- package/dist/index.d.mts +7 -0
- package/dist/index.mjs +6 -0
- package/package.json +26 -19
- package/dist/analysis/call-collector.d.ts +0 -20
- package/dist/analysis/call-collector.d.ts.map +0 -1
- package/dist/analysis/call-collector.js +0 -272
- package/dist/analysis/dependency-analyzer.d.ts +0 -14
- package/dist/analysis/dependency-analyzer.d.ts.map +0 -1
- package/dist/analysis/dependency-analyzer.js +0 -76
- package/dist/analysis/index.d.ts +0 -2
- package/dist/analysis/index.d.ts.map +0 -1
- package/dist/analysis/index.js +0 -1
- package/dist/analysis/round-planner.d.ts +0 -32
- package/dist/analysis/round-planner.d.ts.map +0 -1
- package/dist/analysis/round-planner.js +0 -69
- package/dist/analysis/types.d.ts +0 -113
- package/dist/analysis/types.d.ts.map +0 -1
- package/dist/analysis/types.js +0 -1
- package/dist/debug.d.ts +0 -13
- package/dist/debug.d.ts.map +0 -1
- package/dist/debug.js +0 -12
- package/dist/environment/context.d.ts +0 -3
- package/dist/environment/context.d.ts.map +0 -1
- package/dist/environment/context.js +0 -8
- package/dist/environment/contract-caller.d.ts +0 -25
- package/dist/environment/contract-caller.d.ts.map +0 -1
- package/dist/environment/contract-caller.js +0 -85
- package/dist/environment/environment.d.ts +0 -81
- package/dist/environment/environment.d.ts.map +0 -1
- package/dist/environment/environment.js +0 -279
- package/dist/environment/error-wrapper.d.ts +0 -11
- package/dist/environment/error-wrapper.d.ts.map +0 -1
- package/dist/environment/error-wrapper.js +0 -33
- package/dist/environment/index.d.ts +0 -3
- package/dist/environment/index.d.ts.map +0 -1
- package/dist/environment/index.js +0 -2
- package/dist/environment/replay-cache.d.ts +0 -23
- package/dist/environment/replay-cache.d.ts.map +0 -1
- package/dist/environment/replay-cache.js +0 -51
- package/dist/environment/types.d.ts +0 -57
- package/dist/environment/types.d.ts.map +0 -1
- package/dist/environment/types.js +0 -1
- package/dist/errors/errors.d.ts +0 -63
- package/dist/errors/errors.d.ts.map +0 -1
- package/dist/errors/errors.js +0 -63
- package/dist/errors/index.d.ts +0 -2
- package/dist/errors/index.d.ts.map +0 -1
- package/dist/errors/index.js +0 -1
- package/dist/execution/index.d.ts +0 -2
- package/dist/execution/index.d.ts.map +0 -1
- package/dist/execution/index.js +0 -1
- package/dist/execution/multi-round-executor.d.ts +0 -17
- package/dist/execution/multi-round-executor.d.ts.map +0 -1
- package/dist/execution/multi-round-executor.js +0 -47
- package/dist/execution/multicall-batcher.d.ts +0 -14
- package/dist/execution/multicall-batcher.d.ts.map +0 -1
- package/dist/execution/multicall-batcher.js +0 -53
- package/dist/execution/multicall.d.ts +0 -42
- package/dist/execution/multicall.d.ts.map +0 -1
- package/dist/execution/multicall.js +0 -29
- package/dist/execution/result-cache.d.ts +0 -47
- package/dist/execution/result-cache.d.ts.map +0 -1
- package/dist/execution/result-cache.js +0 -65
- package/dist/execution/round-executor.d.ts +0 -18
- package/dist/execution/round-executor.d.ts.map +0 -1
- package/dist/execution/round-executor.js +0 -95
- package/dist/execution/types.d.ts +0 -55
- package/dist/execution/types.d.ts.map +0 -1
- package/dist/execution/types.js +0 -1
- package/dist/factory.d.ts +0 -3
- package/dist/factory.d.ts.map +0 -1
- package/dist/factory.js +0 -2
- package/dist/index.d.ts +0 -10
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -7
package/dist/analysis/types.d.ts
DELETED
|
@@ -1,113 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Represents a contract call found in AST traversal.
|
|
3
|
-
* Contains all information needed to execute the call and track dependencies.
|
|
4
|
-
*/
|
|
5
|
-
export interface CollectedCall {
|
|
6
|
-
/**
|
|
7
|
-
* Unique identifier: "contract:method:serializedArgs"
|
|
8
|
-
*/
|
|
9
|
-
id: string;
|
|
10
|
-
/**
|
|
11
|
-
* Contract name: e.g., "erc20_usdc"
|
|
12
|
-
*/
|
|
13
|
-
contract: string;
|
|
14
|
-
/**
|
|
15
|
-
* Method name: e.g., "balanceOf"
|
|
16
|
-
*/
|
|
17
|
-
method: string;
|
|
18
|
-
/**
|
|
19
|
-
* Arguments with type and dependency information
|
|
20
|
-
*/
|
|
21
|
-
args: CallArgument[];
|
|
22
|
-
/**
|
|
23
|
-
* Reference to original AST node for error reporting
|
|
24
|
-
*/
|
|
25
|
-
astNode: unknown;
|
|
26
|
-
}
|
|
27
|
-
/**
|
|
28
|
-
* Argument to a contract call with type information.
|
|
29
|
-
* Tracks whether the argument is a literal, variable, or result of another call.
|
|
30
|
-
*/
|
|
31
|
-
export interface CallArgument {
|
|
32
|
-
/**
|
|
33
|
-
* Type of argument: literal value, variable reference, or call result
|
|
34
|
-
*/
|
|
35
|
-
type: "literal" | "variable" | "call_result";
|
|
36
|
-
/**
|
|
37
|
-
* Literal value (when type is "literal")
|
|
38
|
-
*/
|
|
39
|
-
value?: unknown;
|
|
40
|
-
/**
|
|
41
|
-
* Variable name (when type is "variable")
|
|
42
|
-
*/
|
|
43
|
-
variableName?: string;
|
|
44
|
-
/**
|
|
45
|
-
* Call ID this depends on (when type is "call_result")
|
|
46
|
-
*/
|
|
47
|
-
dependsOnCallId?: string;
|
|
48
|
-
}
|
|
49
|
-
/**
|
|
50
|
-
* Dependency graph for all collected calls.
|
|
51
|
-
* Maps call IDs to their nodes and dependency relationships.
|
|
52
|
-
*/
|
|
53
|
-
export interface DependencyGraph {
|
|
54
|
-
/**
|
|
55
|
-
* Call ID to graph node mapping
|
|
56
|
-
*/
|
|
57
|
-
nodes: Map<string, GraphNode>;
|
|
58
|
-
/**
|
|
59
|
-
* Call ID to set of call IDs it depends on
|
|
60
|
-
*/
|
|
61
|
-
edges: Map<string, Set<string>>;
|
|
62
|
-
}
|
|
63
|
-
/**
|
|
64
|
-
* Single node in the dependency graph.
|
|
65
|
-
* Tracks both incoming and outgoing dependencies.
|
|
66
|
-
*/
|
|
67
|
-
export interface GraphNode {
|
|
68
|
-
/**
|
|
69
|
-
* The original collected call
|
|
70
|
-
*/
|
|
71
|
-
call: CollectedCall;
|
|
72
|
-
/**
|
|
73
|
-
* Call IDs this call depends on (must complete first)
|
|
74
|
-
*/
|
|
75
|
-
dependsOn: string[];
|
|
76
|
-
/**
|
|
77
|
-
* Call IDs that depend on this call (will execute after)
|
|
78
|
-
*/
|
|
79
|
-
dependedOnBy: string[];
|
|
80
|
-
}
|
|
81
|
-
/**
|
|
82
|
-
* Execution plan with rounds of parallel calls.
|
|
83
|
-
* Result of topological sorting the dependency graph.
|
|
84
|
-
*/
|
|
85
|
-
export interface ExecutionPlan {
|
|
86
|
-
/**
|
|
87
|
-
* Rounds of calls to execute in sequence
|
|
88
|
-
*/
|
|
89
|
-
rounds: ExecutionRound[];
|
|
90
|
-
/**
|
|
91
|
-
* Total number of calls across all rounds
|
|
92
|
-
*/
|
|
93
|
-
totalCalls: number;
|
|
94
|
-
/**
|
|
95
|
-
* Number of rounds (maximum dependency depth)
|
|
96
|
-
*/
|
|
97
|
-
maxDepth: number;
|
|
98
|
-
}
|
|
99
|
-
/**
|
|
100
|
-
* Single round of calls that can execute in parallel.
|
|
101
|
-
* All calls in a round have no dependencies on each other.
|
|
102
|
-
*/
|
|
103
|
-
export interface ExecutionRound {
|
|
104
|
-
/**
|
|
105
|
-
* Round number (0-indexed)
|
|
106
|
-
*/
|
|
107
|
-
roundNumber: number;
|
|
108
|
-
/**
|
|
109
|
-
* Calls that can execute in parallel this round
|
|
110
|
-
*/
|
|
111
|
-
calls: CollectedCall[];
|
|
112
|
-
}
|
|
113
|
-
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/analysis/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC7B;;OAEG;IACH,EAAE,EAAE,MAAM,CAAC;IAEX;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAC;IAEjB;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC;IAEf;;OAEG;IACH,IAAI,EAAE,YAAY,EAAE,CAAC;IAErB;;OAEG;IACH,OAAO,EAAE,OAAO,CAAC;CACjB;AAED;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC5B;;OAEG;IACH,IAAI,EAAE,SAAS,GAAG,UAAU,GAAG,aAAa,CAAC;IAE7C;;OAEG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;IAEhB;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB;;OAEG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC/B;;OAEG;IACH,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAE9B;;OAEG;IACH,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;CAChC;AAED;;;GAGG;AACH,MAAM,WAAW,SAAS;IACzB;;OAEG;IACH,IAAI,EAAE,aAAa,CAAC;IAEpB;;OAEG;IACH,SAAS,EAAE,MAAM,EAAE,CAAC;IAEpB;;OAEG;IACH,YAAY,EAAE,MAAM,EAAE,CAAC;CACvB;AAED;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC7B;;OAEG;IACH,MAAM,EAAE,cAAc,EAAE,CAAC;IAEzB;;OAEG;IACH,UAAU,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAC;CACjB;AAED;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC9B;;OAEG;IACH,WAAW,EAAE,MAAM,CAAC;IAEpB;;OAEG;IACH,KAAK,EAAE,aAAa,EAAE,CAAC;CACvB"}
|
package/dist/analysis/types.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
package/dist/debug.d.ts
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import createDebug from "debug";
|
|
2
|
-
/**
|
|
3
|
-
* Creates a namespaced debug logger for a SEL module.
|
|
4
|
-
*
|
|
5
|
-
* Enable via the `DEBUG` environment variable:
|
|
6
|
-
* - `DEBUG=sel:*` — all SEL logging
|
|
7
|
-
* - `DEBUG=sel:evaluate` — only evaluate flow
|
|
8
|
-
* - `DEBUG=sel:execute:*` — all execution sub-loggers
|
|
9
|
-
*
|
|
10
|
-
* @param namespace - Module namespace (e.g. "evaluate", "execute:round")
|
|
11
|
-
*/
|
|
12
|
-
export declare const createLogger: (namespace: string) => createDebug.Debugger;
|
|
13
|
-
//# sourceMappingURL=debug.d.ts.map
|
package/dist/debug.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"debug.d.ts","sourceRoot":"","sources":["../src/debug.ts"],"names":[],"mappings":"AAAA,OAAO,WAAW,MAAM,OAAO,CAAC;AAEhC;;;;;;;;;GASG;AACH,eAAO,MAAM,YAAY,GAAI,WAAW,MAAM,KAAG,WAAW,CAAC,QAC7B,CAAC"}
|
package/dist/debug.js
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import createDebug from "debug";
|
|
2
|
-
/**
|
|
3
|
-
* Creates a namespaced debug logger for a SEL module.
|
|
4
|
-
*
|
|
5
|
-
* Enable via the `DEBUG` environment variable:
|
|
6
|
-
* - `DEBUG=sel:*` — all SEL logging
|
|
7
|
-
* - `DEBUG=sel:evaluate` — only evaluate flow
|
|
8
|
-
* - `DEBUG=sel:execute:*` — all execution sub-loggers
|
|
9
|
-
*
|
|
10
|
-
* @param namespace - Module namespace (e.g. "evaluate", "execute:round")
|
|
11
|
-
*/
|
|
12
|
-
export const createLogger = (namespace) => createDebug(`sel:${namespace}`);
|
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
import type { CelCodecRegistry } from "@seljs/checker";
|
|
2
|
-
export declare const normalizeContextForEvaluation: (context: Record<string, unknown>, variableTypes: Map<string, string>, codecRegistry: CelCodecRegistry) => Record<string, unknown>;
|
|
3
|
-
//# sourceMappingURL=context.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/environment/context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAEvD,eAAO,MAAM,6BAA6B,GACzC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,eAAe,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,EAClC,eAAe,gBAAgB,KAC7B,MAAM,CAAC,MAAM,EAAE,OAAO,CASxB,CAAC"}
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
export const normalizeContextForEvaluation = (context, variableTypes, codecRegistry) => {
|
|
2
|
-
const normalized = {};
|
|
3
|
-
for (const [key, value] of Object.entries(context)) {
|
|
4
|
-
const type = variableTypes.get(key);
|
|
5
|
-
normalized[key] = codecRegistry.resolve(type ?? "dyn").parse(value);
|
|
6
|
-
}
|
|
7
|
-
return normalized;
|
|
8
|
-
};
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import type { CelCodecRegistry } from "@seljs/checker";
|
|
2
|
-
import type { ContractSchema, MethodSchema } from "@seljs/schema";
|
|
3
|
-
import type { Abi, Address, PublicClient } from "viem";
|
|
4
|
-
/**
|
|
5
|
-
* Tracks total RPC calls (pre-executed + live) across a single evaluation.
|
|
6
|
-
* Create one per `evaluate()` call and pass it through the handler closure.
|
|
7
|
-
*/
|
|
8
|
-
export declare class CallCounter {
|
|
9
|
-
private readonly maxCalls;
|
|
10
|
-
private count;
|
|
11
|
-
constructor(maxCalls: number, initialCount?: number);
|
|
12
|
-
increment(contractName: string, methodName: string): void;
|
|
13
|
-
}
|
|
14
|
-
export declare const executeContractCall: (contract: ContractSchema, method: MethodSchema, args: unknown[], options: {
|
|
15
|
-
executionCache?: Map<string, unknown>;
|
|
16
|
-
client?: PublicClient;
|
|
17
|
-
codecRegistry?: CelCodecRegistry;
|
|
18
|
-
callCounter?: CallCounter;
|
|
19
|
-
}) => Promise<unknown>;
|
|
20
|
-
export declare const resolveExecutionBlockNumber: (client: PublicClient) => Promise<bigint | undefined>;
|
|
21
|
-
export declare const buildContractInfoMap: (contracts: ContractSchema[]) => Map<string, {
|
|
22
|
-
abi: Abi;
|
|
23
|
-
address: Address;
|
|
24
|
-
}>;
|
|
25
|
-
//# sourceMappingURL=contract-caller.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"contract-caller.d.ts","sourceRoot":"","sources":["../../src/environment/contract-caller.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACvD,OAAO,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAClE,OAAO,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,MAAM,CAAC;AAIvD;;;GAGG;AACH,qBAAa,WAAW;IAGtB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAF1B,OAAO,CAAC,KAAK,CAAK;gBAEA,QAAQ,EAAE,MAAM,EACjC,YAAY,GAAE,MAAU;IAKlB,SAAS,CAAC,YAAY,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI;CAqBhE;AAED,eAAO,MAAM,mBAAmB,GAC/B,UAAU,cAAc,EACxB,QAAQ,YAAY,EACpB,MAAM,OAAO,EAAE,EACf,SAAS;IACR,cAAc,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACtC,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,aAAa,CAAC,EAAE,gBAAgB,CAAC;IACjC,WAAW,CAAC,EAAE,WAAW,CAAC;CAC1B,KAEC,OAAO,CAAC,OAAO,CAwDjB,CAAC;AAEF,eAAO,MAAM,2BAA2B,GACvC,QAAQ,YAAY,KAClB,OAAO,CAAC,MAAM,GAAG,SAAS,CAe5B,CAAC;AAEF,eAAO,MAAM,oBAAoB,GAChC,WAAW,cAAc,EAAE,KACzB,GAAG,CAAC,MAAM,EAAE;IAAE,GAAG,EAAE,GAAG,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAQ5C,CAAC"}
|
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
import { readContract } from "viem/actions";
|
|
2
|
-
import { createReplayCallId } from "./replay-cache.js";
|
|
3
|
-
import { createLogger } from "../debug.js";
|
|
4
|
-
import { ExecutionLimitError, SELContractError } from "../errors/index.js";
|
|
5
|
-
const debug = createLogger("contract-caller");
|
|
6
|
-
/**
|
|
7
|
-
* Tracks total RPC calls (pre-executed + live) across a single evaluation.
|
|
8
|
-
* Create one per `evaluate()` call and pass it through the handler closure.
|
|
9
|
-
*/
|
|
10
|
-
export class CallCounter {
|
|
11
|
-
maxCalls;
|
|
12
|
-
count = 0;
|
|
13
|
-
constructor(maxCalls, initialCount = 0) {
|
|
14
|
-
this.maxCalls = maxCalls;
|
|
15
|
-
this.count = initialCount;
|
|
16
|
-
}
|
|
17
|
-
increment(contractName, methodName) {
|
|
18
|
-
this.count++;
|
|
19
|
-
if (this.count > this.maxCalls) {
|
|
20
|
-
throw new ExecutionLimitError(`Execution limit exceeded: ${String(this.count)} calls exceeds maxCalls (${String(this.maxCalls)})`, {
|
|
21
|
-
limitType: "maxCalls",
|
|
22
|
-
limit: this.maxCalls,
|
|
23
|
-
actual: this.count,
|
|
24
|
-
});
|
|
25
|
-
}
|
|
26
|
-
debug("call count: %d/%d (%s.%s)", this.count, this.maxCalls, contractName, methodName);
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
export const executeContractCall = async (contract, method, args, options) => {
|
|
30
|
-
const normalizedArgs = options.codecRegistry
|
|
31
|
-
? args.map((arg, i) => options.codecRegistry.encode(method.params[i]?.type ?? "dyn", arg))
|
|
32
|
-
: args;
|
|
33
|
-
if (options.executionCache) {
|
|
34
|
-
const callId = createReplayCallId(contract.name, method.name, normalizedArgs);
|
|
35
|
-
if (options.executionCache.has(callId)) {
|
|
36
|
-
debug("cache hit: %s.%s", contract.name, method.name);
|
|
37
|
-
return options.executionCache.get(callId);
|
|
38
|
-
}
|
|
39
|
-
debug("cache miss: %s.%s — executing live", contract.name, method.name);
|
|
40
|
-
}
|
|
41
|
-
if (!options.client) {
|
|
42
|
-
throw new SELContractError("No client provided for contract call. Provide a client in SELRuntime config or evaluate() context.", {
|
|
43
|
-
contractName: contract.name,
|
|
44
|
-
methodName: method.name,
|
|
45
|
-
});
|
|
46
|
-
}
|
|
47
|
-
// Count live RPC calls against the limit
|
|
48
|
-
options.callCounter?.increment(contract.name, method.name);
|
|
49
|
-
try {
|
|
50
|
-
return await readContract(options.client, {
|
|
51
|
-
address: contract.address,
|
|
52
|
-
abi: [method.abi],
|
|
53
|
-
functionName: method.name,
|
|
54
|
-
args: normalizedArgs,
|
|
55
|
-
});
|
|
56
|
-
}
|
|
57
|
-
catch (error) {
|
|
58
|
-
if (error instanceof SELContractError) {
|
|
59
|
-
throw error;
|
|
60
|
-
}
|
|
61
|
-
throw new SELContractError(`Contract call failed: ${contract.name}.${method.name}`, {
|
|
62
|
-
cause: error,
|
|
63
|
-
contractName: contract.name,
|
|
64
|
-
methodName: method.name,
|
|
65
|
-
});
|
|
66
|
-
}
|
|
67
|
-
};
|
|
68
|
-
export const resolveExecutionBlockNumber = async (client) => {
|
|
69
|
-
const clientWithGetBlockNumber = client;
|
|
70
|
-
if (typeof clientWithGetBlockNumber.getBlockNumber === "function") {
|
|
71
|
-
return await clientWithGetBlockNumber.getBlockNumber();
|
|
72
|
-
}
|
|
73
|
-
if (typeof clientWithGetBlockNumber.request === "function") {
|
|
74
|
-
return undefined;
|
|
75
|
-
}
|
|
76
|
-
return 0n;
|
|
77
|
-
};
|
|
78
|
-
export const buildContractInfoMap = (contracts) => {
|
|
79
|
-
const map = new Map();
|
|
80
|
-
for (const contract of contracts) {
|
|
81
|
-
const abi = contract.methods.map((m) => m.abi);
|
|
82
|
-
map.set(contract.name, { abi, address: contract.address });
|
|
83
|
-
}
|
|
84
|
-
return map;
|
|
85
|
-
};
|
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
import type { SELRuntimeConfig } from "./types.js";
|
|
2
|
-
import type { EvaluateOptions, EvaluateResult } from "../execution/types.js";
|
|
3
|
-
import type { TypeCheckResult } from "@marcbachmann/cel-js";
|
|
4
|
-
export declare class SELRuntime {
|
|
5
|
-
private readonly env;
|
|
6
|
-
private readonly client?;
|
|
7
|
-
private readonly schema;
|
|
8
|
-
private readonly variableTypes;
|
|
9
|
-
private readonly maxRounds;
|
|
10
|
-
private readonly maxCalls;
|
|
11
|
-
private readonly multicallOptions?;
|
|
12
|
-
private readonly contractBindings;
|
|
13
|
-
private readonly codecRegistry;
|
|
14
|
-
/**
|
|
15
|
-
* Per-evaluation mutable state.
|
|
16
|
-
*
|
|
17
|
-
* These fields are set before CEL evaluation and cleared in `finally`.
|
|
18
|
-
* They exist because the contract call handler closure (created in the
|
|
19
|
-
* constructor) needs access to per-evaluation context, but CEL's
|
|
20
|
-
* `Environment.parse()` returns a function that doesn't accept extra
|
|
21
|
-
* parameters beyond the variable bindings.
|
|
22
|
-
*
|
|
23
|
-
* Thread safety: The `mutex` field serializes concurrent `evaluate()`
|
|
24
|
-
* calls, ensuring these fields are never accessed concurrently.
|
|
25
|
-
*
|
|
26
|
-
* TODO: Consider refactoring to pass an EvaluationContext object through
|
|
27
|
-
* the handler closure instead of mutating instance state. This would
|
|
28
|
-
* eliminate the need for the mutex and make the code more testable.
|
|
29
|
-
* See .omc/drafts/context-object-spike.md for preliminary analysis.
|
|
30
|
-
*/
|
|
31
|
-
private currentCache?;
|
|
32
|
-
private currentClient?;
|
|
33
|
-
private currentCallCounter?;
|
|
34
|
-
/** Mutex to serialize concurrent evaluate() calls (protects current* fields) */
|
|
35
|
-
private mutex;
|
|
36
|
-
/**
|
|
37
|
-
* Creates a new immutable SEL runtime with Solidity types pre-registered.
|
|
38
|
-
*
|
|
39
|
-
* Initializes the underlying CEL runtime, registers all Solidity primitive types,
|
|
40
|
-
* and processes any contracts and variables from the schema. After construction,
|
|
41
|
-
* the environment is fully configured and immutable.
|
|
42
|
-
*
|
|
43
|
-
* @param config - Configuration containing the SEL schema, optional viem client,
|
|
44
|
-
* multicall settings, and CEL/execution limits (maxRounds defaults to 10, maxCalls to 100)
|
|
45
|
-
*/
|
|
46
|
-
constructor(config: SELRuntimeConfig);
|
|
47
|
-
/**
|
|
48
|
-
* Type-checks an expression against registered variables and contract methods.
|
|
49
|
-
*
|
|
50
|
-
* @param expression - A CEL expression string to type-check
|
|
51
|
-
* @returns The type-check result containing validity, inferred type, and any errors
|
|
52
|
-
* @throws {@link SELTypeError} If the expression contains unrecoverable type errors
|
|
53
|
-
*/
|
|
54
|
-
check(expression: string): TypeCheckResult;
|
|
55
|
-
/**
|
|
56
|
-
* Evaluates a SEL expression, executing any embedded contract calls on-chain.
|
|
57
|
-
*
|
|
58
|
-
* When contract calls are present, the full pipeline runs:
|
|
59
|
-
* 1. Parse the expression and collect contract calls from the AST
|
|
60
|
-
* 2. Type-check against registered variables and contract methods
|
|
61
|
-
* 3. Build a dependency graph and plan execution rounds
|
|
62
|
-
* 4. Execute contract calls via multicall3 batching at a pinned block number
|
|
63
|
-
* 5. Evaluate the CEL expression with resolved contract results and context values
|
|
64
|
-
* 6. Unwrap Solidity wrapper types back to native JS values (BigInt, string, etc.)
|
|
65
|
-
*
|
|
66
|
-
* @param expression A CEL expression string
|
|
67
|
-
* @param context Variable bindings for evaluation
|
|
68
|
-
* @param options Optional client override
|
|
69
|
-
* @returns An {@link EvaluateResult} containing the value and optional execution metadata
|
|
70
|
-
* @throws {@link SELParseError} If the expression has invalid syntax
|
|
71
|
-
* @throws {@link SELTypeError} If type-checking fails
|
|
72
|
-
* @throws {@link SELContractError} If a contract call fails or no client is available
|
|
73
|
-
* @throws {@link SELEvaluationError} If CEL evaluation fails
|
|
74
|
-
*/
|
|
75
|
-
evaluate<T = unknown>(expression: string, context?: Record<string, unknown>, options?: EvaluateOptions): Promise<EvaluateResult<T>>;
|
|
76
|
-
private planExecution;
|
|
77
|
-
private executeContractCalls;
|
|
78
|
-
private doEvaluate;
|
|
79
|
-
private findContract;
|
|
80
|
-
}
|
|
81
|
-
//# sourceMappingURL=environment.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"environment.d.ts","sourceRoot":"","sources":["../../src/environment/environment.ts"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAAoB,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAErE,OAAO,KAAK,EACX,eAAe,EACf,cAAc,EAEd,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EAAe,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAezE,qBAAa,UAAU;IACtB,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAc;IAClC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAe;IACvC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAY;IACnC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAA6B;IAC3D,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAmB;IACrD,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAA0B;IAC3D,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAmB;IAEjD;;;;;;;;;;;;;;;;OAgBG;IACH,OAAO,CAAC,YAAY,CAAC,CAAuB;IAC5C,OAAO,CAAC,aAAa,CAAC,CAAe;IACrC,OAAO,CAAC,kBAAkB,CAAC,CAAc;IAEzC,gFAAgF;IAChF,OAAO,CAAC,KAAK,CAAqB;IAElC;;;;;;;;;OASG;gBACgB,MAAM,EAAE,gBAAgB;IAgE3C;;;;;;OAMG;IACI,KAAK,CAAC,UAAU,EAAE,MAAM,GAAG,eAAe;IAQjD;;;;;;;;;;;;;;;;;;;OAmBG;IACU,QAAQ,CAAC,CAAC,GAAG,OAAO,EAChC,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjC,OAAO,CAAC,EAAE,eAAe,GACvB,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC;IAiB7B,OAAO,CAAC,aAAa;YA+CP,oBAAoB;YA0FpB,UAAU;IAyExB,OAAO,CAAC,YAAY;CAGpB"}
|
|
@@ -1,279 +0,0 @@
|
|
|
1
|
-
import { createRuntimeEnvironment } from "@seljs/checker";
|
|
2
|
-
import { normalizeContextForEvaluation } from "./context.js";
|
|
3
|
-
import { CallCounter, buildContractInfoMap, executeContractCall, resolveExecutionBlockNumber, } from "./contract-caller.js";
|
|
4
|
-
import { wrapError } from "./error-wrapper.js";
|
|
5
|
-
import { buildExecutionReplayCache } from "./replay-cache.js";
|
|
6
|
-
import { collectCalls } from "../analysis/call-collector.js";
|
|
7
|
-
import { analyzeDependencies } from "../analysis/dependency-analyzer.js";
|
|
8
|
-
import { planRounds } from "../analysis/round-planner.js";
|
|
9
|
-
import { createLogger } from "../debug.js";
|
|
10
|
-
import { MulticallBatchError, SELContractError, SELTypeError, } from "../errors/index.js";
|
|
11
|
-
import { MultiRoundExecutor } from "../execution/multi-round-executor.js";
|
|
12
|
-
/**
|
|
13
|
-
* Core SEL runtime that bridges CEL expression evaluation with EVM contract reads.
|
|
14
|
-
*
|
|
15
|
-
* Manages a CEL runtime extended with Solidity primitive types (uint256, address, bool, etc.),
|
|
16
|
-
* registered smart contracts whose view functions become callable in expressions, and typed
|
|
17
|
-
* variables that are supplied at evaluation time. Contract calls are automatically batched
|
|
18
|
-
* via multicall3 and executed in dependency-ordered rounds.
|
|
19
|
-
*/
|
|
20
|
-
const debug = createLogger("environment");
|
|
21
|
-
export class SELRuntime {
|
|
22
|
-
env;
|
|
23
|
-
client;
|
|
24
|
-
schema;
|
|
25
|
-
variableTypes = new Map();
|
|
26
|
-
maxRounds;
|
|
27
|
-
maxCalls;
|
|
28
|
-
multicallOptions;
|
|
29
|
-
contractBindings;
|
|
30
|
-
codecRegistry;
|
|
31
|
-
/**
|
|
32
|
-
* Per-evaluation mutable state.
|
|
33
|
-
*
|
|
34
|
-
* These fields are set before CEL evaluation and cleared in `finally`.
|
|
35
|
-
* They exist because the contract call handler closure (created in the
|
|
36
|
-
* constructor) needs access to per-evaluation context, but CEL's
|
|
37
|
-
* `Environment.parse()` returns a function that doesn't accept extra
|
|
38
|
-
* parameters beyond the variable bindings.
|
|
39
|
-
*
|
|
40
|
-
* Thread safety: The `mutex` field serializes concurrent `evaluate()`
|
|
41
|
-
* calls, ensuring these fields are never accessed concurrently.
|
|
42
|
-
*
|
|
43
|
-
* TODO: Consider refactoring to pass an EvaluationContext object through
|
|
44
|
-
* the handler closure instead of mutating instance state. This would
|
|
45
|
-
* eliminate the need for the mutex and make the code more testable.
|
|
46
|
-
* See .omc/drafts/context-object-spike.md for preliminary analysis.
|
|
47
|
-
*/
|
|
48
|
-
currentCache;
|
|
49
|
-
currentClient;
|
|
50
|
-
currentCallCounter;
|
|
51
|
-
/** Mutex to serialize concurrent evaluate() calls (protects current* fields) */
|
|
52
|
-
mutex = Promise.resolve();
|
|
53
|
-
/**
|
|
54
|
-
* Creates a new immutable SEL runtime with Solidity types pre-registered.
|
|
55
|
-
*
|
|
56
|
-
* Initializes the underlying CEL runtime, registers all Solidity primitive types,
|
|
57
|
-
* and processes any contracts and variables from the schema. After construction,
|
|
58
|
-
* the environment is fully configured and immutable.
|
|
59
|
-
*
|
|
60
|
-
* @param config - Configuration containing the SEL schema, optional viem client,
|
|
61
|
-
* multicall settings, and CEL/execution limits (maxRounds defaults to 10, maxCalls to 100)
|
|
62
|
-
*/
|
|
63
|
-
constructor(config) {
|
|
64
|
-
const limits = config.limits;
|
|
65
|
-
const celLimits = limits
|
|
66
|
-
? {
|
|
67
|
-
maxAstNodes: limits.maxAstNodes,
|
|
68
|
-
maxDepth: limits.maxDepth,
|
|
69
|
-
maxListElements: limits.maxListElements,
|
|
70
|
-
maxMapEntries: limits.maxMapEntries,
|
|
71
|
-
maxCallArguments: limits.maxCallArguments,
|
|
72
|
-
}
|
|
73
|
-
: undefined;
|
|
74
|
-
this.maxRounds = limits?.maxRounds ?? 10;
|
|
75
|
-
this.maxCalls = limits?.maxCalls ?? 100;
|
|
76
|
-
this.multicallOptions = config.multicall;
|
|
77
|
-
this.client = config.client;
|
|
78
|
-
this.schema = config.schema;
|
|
79
|
-
// Build handler closure that captures `this` for contract execution
|
|
80
|
-
const handler = (contractName, methodName, args) => {
|
|
81
|
-
const contract = this.findContract(contractName);
|
|
82
|
-
if (!contract) {
|
|
83
|
-
throw new SELContractError(`Unknown contract "${contractName}"`, {
|
|
84
|
-
contractName,
|
|
85
|
-
});
|
|
86
|
-
}
|
|
87
|
-
const method = contract.methods.find((m) => m.name === methodName);
|
|
88
|
-
if (!method) {
|
|
89
|
-
throw new SELContractError(`Unknown method "${contractName}.${methodName}"`, { contractName, methodName });
|
|
90
|
-
}
|
|
91
|
-
return executeContractCall(contract, method, args, {
|
|
92
|
-
executionCache: this.currentCache,
|
|
93
|
-
client: this.currentClient ?? this.client,
|
|
94
|
-
codecRegistry: this.codecRegistry,
|
|
95
|
-
callCounter: this.currentCallCounter,
|
|
96
|
-
});
|
|
97
|
-
};
|
|
98
|
-
// Create environment via unified hydration
|
|
99
|
-
const { env, contractBindings, codecRegistry } = createRuntimeEnvironment(this.schema, handler, { limits: celLimits, unlistedVariablesAreDyn: true });
|
|
100
|
-
this.env = env;
|
|
101
|
-
this.contractBindings = contractBindings;
|
|
102
|
-
this.codecRegistry = codecRegistry;
|
|
103
|
-
// Populate variableTypes from schema for normalizeContextForEvaluation
|
|
104
|
-
for (const v of this.schema.variables) {
|
|
105
|
-
this.variableTypes.set(v.name, v.type);
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
/**
|
|
109
|
-
* Type-checks an expression against registered variables and contract methods.
|
|
110
|
-
*
|
|
111
|
-
* @param expression - A CEL expression string to type-check
|
|
112
|
-
* @returns The type-check result containing validity, inferred type, and any errors
|
|
113
|
-
* @throws {@link SELTypeError} If the expression contains unrecoverable type errors
|
|
114
|
-
*/
|
|
115
|
-
check(expression) {
|
|
116
|
-
try {
|
|
117
|
-
return this.env.check(expression);
|
|
118
|
-
}
|
|
119
|
-
catch (error) {
|
|
120
|
-
throw wrapError(error);
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
/**
|
|
124
|
-
* Evaluates a SEL expression, executing any embedded contract calls on-chain.
|
|
125
|
-
*
|
|
126
|
-
* When contract calls are present, the full pipeline runs:
|
|
127
|
-
* 1. Parse the expression and collect contract calls from the AST
|
|
128
|
-
* 2. Type-check against registered variables and contract methods
|
|
129
|
-
* 3. Build a dependency graph and plan execution rounds
|
|
130
|
-
* 4. Execute contract calls via multicall3 batching at a pinned block number
|
|
131
|
-
* 5. Evaluate the CEL expression with resolved contract results and context values
|
|
132
|
-
* 6. Unwrap Solidity wrapper types back to native JS values (BigInt, string, etc.)
|
|
133
|
-
*
|
|
134
|
-
* @param expression A CEL expression string
|
|
135
|
-
* @param context Variable bindings for evaluation
|
|
136
|
-
* @param options Optional client override
|
|
137
|
-
* @returns An {@link EvaluateResult} containing the value and optional execution metadata
|
|
138
|
-
* @throws {@link SELParseError} If the expression has invalid syntax
|
|
139
|
-
* @throws {@link SELTypeError} If type-checking fails
|
|
140
|
-
* @throws {@link SELContractError} If a contract call fails or no client is available
|
|
141
|
-
* @throws {@link SELEvaluationError} If CEL evaluation fails
|
|
142
|
-
*/
|
|
143
|
-
async evaluate(expression, context, options) {
|
|
144
|
-
let release;
|
|
145
|
-
const prev = this.mutex;
|
|
146
|
-
this.mutex = new Promise((resolve) => {
|
|
147
|
-
release = resolve;
|
|
148
|
-
});
|
|
149
|
-
await prev;
|
|
150
|
-
try {
|
|
151
|
-
return await this.doEvaluate(expression, context, options);
|
|
152
|
-
}
|
|
153
|
-
finally {
|
|
154
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
155
|
-
release();
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
planExecution(expression, evaluationContext) {
|
|
159
|
-
const parseResult = this.env.parse(expression);
|
|
160
|
-
const collectedCalls = collectCalls(parseResult.ast, {
|
|
161
|
-
get: (name) => this.findContract(name),
|
|
162
|
-
});
|
|
163
|
-
debug("evaluate: collected %d calls", collectedCalls.length);
|
|
164
|
-
const normalizedContext = Object.keys(evaluationContext).length
|
|
165
|
-
? normalizeContextForEvaluation(evaluationContext, this.variableTypes, this.codecRegistry)
|
|
166
|
-
: undefined;
|
|
167
|
-
const executionVariables = Object.keys(evaluationContext).length
|
|
168
|
-
? evaluationContext
|
|
169
|
-
: {};
|
|
170
|
-
const typeCheckResult = parseResult.check();
|
|
171
|
-
if (!typeCheckResult.valid) {
|
|
172
|
-
throw new SELTypeError(typeCheckResult.error?.message ?? "Type check failed", { cause: typeCheckResult.error });
|
|
173
|
-
}
|
|
174
|
-
return {
|
|
175
|
-
parseResult,
|
|
176
|
-
collectedCalls,
|
|
177
|
-
normalizedContext,
|
|
178
|
-
executionVariables,
|
|
179
|
-
typeCheckResult,
|
|
180
|
-
};
|
|
181
|
-
}
|
|
182
|
-
async executeContractCalls(collectedCalls, executionVariables, resolvedClient) {
|
|
183
|
-
debug("evaluate: calls to execute — %o", collectedCalls.map((c) => `${c.contract}.${c.method}`));
|
|
184
|
-
const graph = analyzeDependencies(collectedCalls);
|
|
185
|
-
const plan = planRounds(graph, {
|
|
186
|
-
maxRounds: this.maxRounds,
|
|
187
|
-
maxCalls: this.maxCalls,
|
|
188
|
-
});
|
|
189
|
-
const executor = new MultiRoundExecutor(resolvedClient, buildContractInfoMap(this.schema.contracts), this.multicallOptions);
|
|
190
|
-
let executionResult;
|
|
191
|
-
try {
|
|
192
|
-
executionResult = await executor.execute(plan, executionVariables, await resolveExecutionBlockNumber(resolvedClient));
|
|
193
|
-
}
|
|
194
|
-
catch (error) {
|
|
195
|
-
let failedCall = collectedCalls[0];
|
|
196
|
-
if (error instanceof MulticallBatchError) {
|
|
197
|
-
if (error.contractName && error.methodName) {
|
|
198
|
-
const contractName = error.contractName;
|
|
199
|
-
const methodName = error.methodName;
|
|
200
|
-
const base = failedCall ?? {
|
|
201
|
-
id: "",
|
|
202
|
-
contract: contractName,
|
|
203
|
-
method: methodName,
|
|
204
|
-
args: [],
|
|
205
|
-
astNode: undefined,
|
|
206
|
-
};
|
|
207
|
-
failedCall = {
|
|
208
|
-
...base,
|
|
209
|
-
contract: contractName,
|
|
210
|
-
method: methodName,
|
|
211
|
-
};
|
|
212
|
-
}
|
|
213
|
-
else if (typeof error.failedCallIndex === "number") {
|
|
214
|
-
failedCall = collectedCalls[error.failedCallIndex] ?? failedCall;
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
if (!failedCall) {
|
|
218
|
-
throw error;
|
|
219
|
-
}
|
|
220
|
-
throw new SELContractError(`Contract call failed: ${failedCall.contract}.${failedCall.method}`, {
|
|
221
|
-
cause: error,
|
|
222
|
-
contractName: failedCall.contract,
|
|
223
|
-
methodName: failedCall.method,
|
|
224
|
-
});
|
|
225
|
-
}
|
|
226
|
-
const executionMeta = executionResult.meta;
|
|
227
|
-
const executionCache = buildExecutionReplayCache(collectedCalls, executionResult.results, executionVariables, this.codecRegistry, (contract, method) => {
|
|
228
|
-
const c = this.findContract(contract);
|
|
229
|
-
const m = c?.methods.find((m) => m.name === method);
|
|
230
|
-
return m?.params.map((p) => p.type) ?? [];
|
|
231
|
-
});
|
|
232
|
-
return { executionMeta, executionCache };
|
|
233
|
-
}
|
|
234
|
-
async doEvaluate(expression, context, options) {
|
|
235
|
-
debug("evaluate: %s", expression);
|
|
236
|
-
const resolvedClient = options?.client ?? this.client;
|
|
237
|
-
try {
|
|
238
|
-
const { parseResult, collectedCalls, normalizedContext, executionVariables, typeCheckResult, } = this.planExecution(expression, context ?? {});
|
|
239
|
-
let executionMeta;
|
|
240
|
-
let executionCache;
|
|
241
|
-
if (collectedCalls.length > 0) {
|
|
242
|
-
if (!resolvedClient) {
|
|
243
|
-
throw new SELContractError("No client provided for contract call. Provide a client in SELRuntime config or evaluate() options.", {
|
|
244
|
-
contractName: collectedCalls[0]?.contract,
|
|
245
|
-
methodName: collectedCalls[0]?.method,
|
|
246
|
-
});
|
|
247
|
-
}
|
|
248
|
-
({ executionMeta, executionCache } = await this.executeContractCalls(collectedCalls, executionVariables, resolvedClient));
|
|
249
|
-
}
|
|
250
|
-
// Set per-evaluation state for the handler closure
|
|
251
|
-
this.currentCache = executionCache;
|
|
252
|
-
this.currentClient = resolvedClient;
|
|
253
|
-
this.currentCallCounter = new CallCounter(this.maxCalls, executionMeta?.totalCalls ?? 0);
|
|
254
|
-
let result;
|
|
255
|
-
try {
|
|
256
|
-
result = await parseResult({
|
|
257
|
-
...normalizedContext,
|
|
258
|
-
...this.contractBindings,
|
|
259
|
-
});
|
|
260
|
-
}
|
|
261
|
-
finally {
|
|
262
|
-
this.currentCache = undefined;
|
|
263
|
-
this.currentClient = undefined;
|
|
264
|
-
this.currentCallCounter = undefined;
|
|
265
|
-
}
|
|
266
|
-
const value = (typeCheckResult.type
|
|
267
|
-
? this.codecRegistry.encode(typeCheckResult.type, result)
|
|
268
|
-
: result);
|
|
269
|
-
debug("evaluate: result type=%s", typeof value);
|
|
270
|
-
return executionMeta ? { value, meta: executionMeta } : { value };
|
|
271
|
-
}
|
|
272
|
-
catch (error) {
|
|
273
|
-
throw wrapError(error);
|
|
274
|
-
}
|
|
275
|
-
}
|
|
276
|
-
findContract(name) {
|
|
277
|
-
return this.schema.contracts.find((c) => c.name === name);
|
|
278
|
-
}
|
|
279
|
-
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Wraps an unknown error into a known SEL error type.
|
|
3
|
-
* - If the error is already a SEL error, it is returned as is.
|
|
4
|
-
* - If the error is a CEL error, it is wrapped into the corresponding SEL error type.
|
|
5
|
-
* - If the error is an unknown type, it is wrapped into a generic Error.
|
|
6
|
-
*
|
|
7
|
-
* @param error The error to wrap.
|
|
8
|
-
* @returns The wrapped error.
|
|
9
|
-
*/
|
|
10
|
-
export declare const wrapError: (error: unknown) => Error;
|
|
11
|
-
//# sourceMappingURL=error-wrapper.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"error-wrapper.d.ts","sourceRoot":"","sources":["../../src/environment/error-wrapper.ts"],"names":[],"mappings":"AAaA;;;;;;;;GAQG;AACH,eAAO,MAAM,SAAS,GAAI,OAAO,OAAO,KAAG,KA2B1C,CAAC"}
|