@seljs/runtime 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/LICENSE.md +190 -0
  3. package/README.md +5 -0
  4. package/dist/analysis/call-collector.d.ts +20 -0
  5. package/dist/analysis/call-collector.d.ts.map +1 -0
  6. package/dist/analysis/call-collector.js +272 -0
  7. package/dist/analysis/dependency-analyzer.d.ts +14 -0
  8. package/dist/analysis/dependency-analyzer.d.ts.map +1 -0
  9. package/dist/analysis/dependency-analyzer.js +76 -0
  10. package/dist/analysis/index.d.ts +2 -0
  11. package/dist/analysis/index.d.ts.map +1 -0
  12. package/dist/analysis/index.js +1 -0
  13. package/dist/analysis/round-planner.d.ts +32 -0
  14. package/dist/analysis/round-planner.d.ts.map +1 -0
  15. package/dist/analysis/round-planner.js +69 -0
  16. package/dist/analysis/types.d.ts +113 -0
  17. package/dist/analysis/types.d.ts.map +1 -0
  18. package/dist/analysis/types.js +1 -0
  19. package/dist/debug.d.ts +13 -0
  20. package/dist/debug.d.ts.map +1 -0
  21. package/dist/debug.js +12 -0
  22. package/dist/environment/context.d.ts +3 -0
  23. package/dist/environment/context.d.ts.map +1 -0
  24. package/dist/environment/context.js +8 -0
  25. package/dist/environment/contract-caller.d.ts +25 -0
  26. package/dist/environment/contract-caller.d.ts.map +1 -0
  27. package/dist/environment/contract-caller.js +85 -0
  28. package/dist/environment/environment.d.ts +81 -0
  29. package/dist/environment/environment.d.ts.map +1 -0
  30. package/dist/environment/environment.js +279 -0
  31. package/dist/environment/error-wrapper.d.ts +11 -0
  32. package/dist/environment/error-wrapper.d.ts.map +1 -0
  33. package/dist/environment/error-wrapper.js +33 -0
  34. package/dist/environment/index.d.ts +3 -0
  35. package/dist/environment/index.d.ts.map +1 -0
  36. package/dist/environment/index.js +2 -0
  37. package/dist/environment/replay-cache.d.ts +23 -0
  38. package/dist/environment/replay-cache.d.ts.map +1 -0
  39. package/dist/environment/replay-cache.js +51 -0
  40. package/dist/environment/types.d.ts +57 -0
  41. package/dist/environment/types.d.ts.map +1 -0
  42. package/dist/environment/types.js +1 -0
  43. package/dist/errors/errors.d.ts +63 -0
  44. package/dist/errors/errors.d.ts.map +1 -0
  45. package/dist/errors/errors.js +63 -0
  46. package/dist/errors/index.d.ts +2 -0
  47. package/dist/errors/index.d.ts.map +1 -0
  48. package/dist/errors/index.js +1 -0
  49. package/dist/execution/index.d.ts +2 -0
  50. package/dist/execution/index.d.ts.map +1 -0
  51. package/dist/execution/index.js +1 -0
  52. package/dist/execution/multi-round-executor.d.ts +17 -0
  53. package/dist/execution/multi-round-executor.d.ts.map +1 -0
  54. package/dist/execution/multi-round-executor.js +47 -0
  55. package/dist/execution/multicall-batcher.d.ts +14 -0
  56. package/dist/execution/multicall-batcher.d.ts.map +1 -0
  57. package/dist/execution/multicall-batcher.js +53 -0
  58. package/dist/execution/multicall.d.ts +42 -0
  59. package/dist/execution/multicall.d.ts.map +1 -0
  60. package/dist/execution/multicall.js +29 -0
  61. package/dist/execution/result-cache.d.ts +47 -0
  62. package/dist/execution/result-cache.d.ts.map +1 -0
  63. package/dist/execution/result-cache.js +65 -0
  64. package/dist/execution/round-executor.d.ts +18 -0
  65. package/dist/execution/round-executor.d.ts.map +1 -0
  66. package/dist/execution/round-executor.js +95 -0
  67. package/dist/execution/types.d.ts +55 -0
  68. package/dist/execution/types.d.ts.map +1 -0
  69. package/dist/execution/types.js +1 -0
  70. package/dist/factory.d.ts +3 -0
  71. package/dist/factory.d.ts.map +1 -0
  72. package/dist/factory.js +2 -0
  73. package/dist/index.d.ts +10 -0
  74. package/dist/index.d.ts.map +1 -0
  75. package/dist/index.js +7 -0
  76. package/package.json +76 -0
@@ -0,0 +1,47 @@
1
+ import { getBlockNumber } from "viem/actions";
2
+ import { MulticallBatcher } from "./multicall-batcher.js";
3
+ import { ResultCache } from "./result-cache.js";
4
+ import { RoundExecutor } from "./round-executor.js";
5
+ import { createLogger } from "../debug.js";
6
+ const debug = createLogger("execute");
7
+ export class MultiRoundExecutor {
8
+ client;
9
+ multicallOptions;
10
+ contracts;
11
+ constructor(client, contracts, multicallOptions) {
12
+ this.client = client;
13
+ this.multicallOptions = multicallOptions;
14
+ this.contracts = contracts;
15
+ }
16
+ async execute(plan, variables = {}, blockNumber) {
17
+ const lockedBlockNumber = blockNumber ?? (await getBlockNumber(this.client));
18
+ debug("start: %d rounds, %d calls, block=%s", plan.rounds.length, plan.totalCalls, String(lockedBlockNumber));
19
+ const cache = new ResultCache();
20
+ const batcher = new MulticallBatcher(this.client, this.multicallOptions);
21
+ const executor = new RoundExecutor(this.contracts, cache, batcher);
22
+ const context = {
23
+ client: this.client,
24
+ blockNumber: lockedBlockNumber,
25
+ variables,
26
+ };
27
+ for (const round of plan.rounds) {
28
+ debug("round %d: %d calls", round.roundNumber, round.calls.length);
29
+ await executor.executeRound(round, context);
30
+ }
31
+ const results = new Map();
32
+ for (const round of plan.rounds) {
33
+ for (const call of round.calls) {
34
+ results.set(call.id, cache.get(call.id));
35
+ }
36
+ }
37
+ debug("complete: %d results collected", results.size);
38
+ return {
39
+ results,
40
+ meta: {
41
+ roundsExecuted: plan.rounds.length,
42
+ totalCalls: plan.totalCalls,
43
+ blockNumber: lockedBlockNumber,
44
+ },
45
+ };
46
+ }
47
+ }
@@ -0,0 +1,14 @@
1
+ import { type MulticallCall, type MulticallResult } from "./multicall.js";
2
+ import type { Address, PublicClient } from "viem";
3
+ export declare class MulticallBatcher {
4
+ private readonly client;
5
+ private readonly address;
6
+ private readonly batchSize;
7
+ constructor(client: PublicClient, options?: {
8
+ address?: Address;
9
+ batchSize?: number;
10
+ });
11
+ executeBatch(calls: MulticallCall[], blockNumber: bigint): Promise<MulticallResult[]>;
12
+ private executeChunk;
13
+ }
14
+ //# sourceMappingURL=multicall-batcher.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"multicall-batcher.d.ts","sourceRoot":"","sources":["../../src/execution/multicall-batcher.ts"],"names":[],"mappings":"AAEA,OAAO,EAEN,KAAK,aAAa,EAClB,KAAK,eAAe,EAEpB,MAAM,gBAAgB,CAAC;AAIxB,OAAO,KAAK,EAAE,OAAO,EAAO,YAAY,EAAE,MAAM,MAAM,CAAC;AAIvD,qBAAa,gBAAgB;IAK3B,OAAO,CAAC,QAAQ,CAAC,MAAM;IAJxB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAU;IAClC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;gBAGjB,MAAM,EAAE,YAAY,EACrC,OAAO,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,OAAO,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE;IAMvC,YAAY,CACxB,KAAK,EAAE,aAAa,EAAE,EACtB,WAAW,EAAE,MAAM,GACjB,OAAO,CAAC,eAAe,EAAE,CAAC;YA+Bf,YAAY;CAuB1B"}
@@ -0,0 +1,53 @@
1
+ import { readContract } from "viem/actions";
2
+ import { MULTICALL3_ADDRESS, multicall3Abi, } from "./multicall.js";
3
+ import { createLogger } from "../debug.js";
4
+ import { MulticallBatchError } from "../errors/index.js";
5
+ const debug = createLogger("execute:multicall");
6
+ export class MulticallBatcher {
7
+ client;
8
+ address;
9
+ batchSize;
10
+ constructor(client, options) {
11
+ this.client = client;
12
+ this.address = options?.address ?? MULTICALL3_ADDRESS;
13
+ this.batchSize = options?.batchSize ?? 200;
14
+ }
15
+ async executeBatch(calls, blockNumber) {
16
+ if (calls.length === 0) {
17
+ return [];
18
+ }
19
+ if (calls.length <= this.batchSize) {
20
+ debug("batch: %d calls (single chunk)", calls.length);
21
+ return await this.executeChunk(calls, blockNumber);
22
+ }
23
+ debug("batch: %d calls (chunked, batchSize=%d)", calls.length, this.batchSize);
24
+ const results = [];
25
+ for (let i = 0; i < calls.length; i += this.batchSize) {
26
+ const chunk = calls.slice(i, i + this.batchSize);
27
+ debug("chunk %d/%d", i / this.batchSize + 1, Math.ceil(calls.length / this.batchSize));
28
+ const chunkResults = await this.executeChunk(chunk, blockNumber);
29
+ results.push(...chunkResults);
30
+ }
31
+ return results;
32
+ }
33
+ async executeChunk(calls, blockNumber) {
34
+ try {
35
+ const result = (await readContract(this.client, {
36
+ address: this.address,
37
+ abi: multicall3Abi,
38
+ functionName: "aggregate3",
39
+ args: [calls],
40
+ blockNumber,
41
+ }));
42
+ return result.map((r) => ({
43
+ success: r.success,
44
+ returnData: r.returnData,
45
+ }));
46
+ }
47
+ catch (error) {
48
+ throw new MulticallBatchError("Multicall3 aggregate3 call failed", {
49
+ cause: error,
50
+ });
51
+ }
52
+ }
53
+ }
@@ -0,0 +1,42 @@
1
+ import type { Address, Hex } from "viem";
2
+ export declare const MULTICALL3_ADDRESS: Address;
3
+ export declare const multicall3Abi: readonly [{
4
+ readonly name: "aggregate3";
5
+ readonly type: "function";
6
+ readonly stateMutability: "payable";
7
+ readonly inputs: readonly [{
8
+ readonly name: "calls";
9
+ readonly type: "tuple[]";
10
+ readonly components: readonly [{
11
+ readonly name: "target";
12
+ readonly type: "address";
13
+ }, {
14
+ readonly name: "allowFailure";
15
+ readonly type: "bool";
16
+ }, {
17
+ readonly name: "callData";
18
+ readonly type: "bytes";
19
+ }];
20
+ }];
21
+ readonly outputs: readonly [{
22
+ readonly name: "returnData";
23
+ readonly type: "tuple[]";
24
+ readonly components: readonly [{
25
+ readonly name: "success";
26
+ readonly type: "bool";
27
+ }, {
28
+ readonly name: "returnData";
29
+ readonly type: "bytes";
30
+ }];
31
+ }];
32
+ }];
33
+ export interface MulticallCall {
34
+ target: Address;
35
+ allowFailure: boolean;
36
+ callData: Hex;
37
+ }
38
+ export interface MulticallResult {
39
+ success: boolean;
40
+ returnData: Hex;
41
+ }
42
+ //# sourceMappingURL=multicall.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"multicall.d.ts","sourceRoot":"","sources":["../../src/execution/multicall.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,MAAM,CAAC;AAEzC,eAAO,MAAM,kBAAkB,EAAE,OACY,CAAC;AAE9C,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA2BhB,CAAC;AAEX,MAAM,WAAW,aAAa;IAC7B,MAAM,EAAE,OAAO,CAAC;IAChB,YAAY,EAAE,OAAO,CAAC;IACtB,QAAQ,EAAE,GAAG,CAAC;CACd;AAED,MAAM,WAAW,eAAe;IAC/B,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,GAAG,CAAC;CAChB"}
@@ -0,0 +1,29 @@
1
+ export const MULTICALL3_ADDRESS = "0xcA11bde05977b3631167028862bE2a173976CA11";
2
+ export const multicall3Abi = [
3
+ {
4
+ name: "aggregate3",
5
+ type: "function",
6
+ stateMutability: "payable",
7
+ inputs: [
8
+ {
9
+ name: "calls",
10
+ type: "tuple[]",
11
+ components: [
12
+ { name: "target", type: "address" },
13
+ { name: "allowFailure", type: "bool" },
14
+ { name: "callData", type: "bytes" },
15
+ ],
16
+ },
17
+ ],
18
+ outputs: [
19
+ {
20
+ name: "returnData",
21
+ type: "tuple[]",
22
+ components: [
23
+ { name: "success", type: "bool" },
24
+ { name: "returnData", type: "bytes" },
25
+ ],
26
+ },
27
+ ],
28
+ },
29
+ ];
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Cache for storing contract call results during expression evaluation.
3
+ *
4
+ * Uses Map-based storage with deterministic call IDs for efficient
5
+ * lookup and deduplication of repeated contract calls.
6
+ */
7
+ export declare class ResultCache {
8
+ private readonly cache;
9
+ /**
10
+ * Generate a deterministic call ID from contract details.
11
+ *
12
+ * The ID format is `contract:method:serializedArgs` where args are
13
+ * JSON-stringified with special handling for bigint values.
14
+ *
15
+ * @param contract - Contract name (e.g., "token", "vault")
16
+ * @param method - Method name (e.g., "balanceOf", "totalSupply")
17
+ * @param args - Method arguments
18
+ * @returns Deterministic call ID string
19
+ */
20
+ generateCallId(contract: string, method: string, args: unknown[]): string;
21
+ /**
22
+ * Store a result in the cache.
23
+ *
24
+ * @param callId - The call ID (from generateCallId)
25
+ * @param result - The result to cache
26
+ */
27
+ set(callId: string, result: unknown): void;
28
+ /**
29
+ * Retrieve a cached result.
30
+ *
31
+ * @param callId - The call ID to look up
32
+ * @returns The cached result, or undefined if not found
33
+ */
34
+ get(callId: string): unknown;
35
+ /**
36
+ * Check if a result is cached.
37
+ *
38
+ * @param callId - The call ID to check
39
+ * @returns true if cached, false otherwise
40
+ */
41
+ has(callId: string): boolean;
42
+ /**
43
+ * Clear all cached results.
44
+ */
45
+ clear(): void;
46
+ }
47
+ //# sourceMappingURL=result-cache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"result-cache.d.ts","sourceRoot":"","sources":["../../src/execution/result-cache.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,qBAAa,WAAW;IACvB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA8B;IAEpD;;;;;;;;;;OAUG;IACI,cAAc,CACpB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,OAAO,EAAE,GACb,MAAM;IAoBT;;;;;OAKG;IACI,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,IAAI;IAIjD;;;;;OAKG;IACI,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO;IAInC;;;;;OAKG;IACI,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO;IAInC;;OAEG;IACI,KAAK,IAAI,IAAI;CAGpB"}
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Cache for storing contract call results during expression evaluation.
3
+ *
4
+ * Uses Map-based storage with deterministic call IDs for efficient
5
+ * lookup and deduplication of repeated contract calls.
6
+ */
7
+ export class ResultCache {
8
+ cache = new Map();
9
+ /**
10
+ * Generate a deterministic call ID from contract details.
11
+ *
12
+ * The ID format is `contract:method:serializedArgs` where args are
13
+ * JSON-stringified with special handling for bigint values.
14
+ *
15
+ * @param contract - Contract name (e.g., "token", "vault")
16
+ * @param method - Method name (e.g., "balanceOf", "totalSupply")
17
+ * @param args - Method arguments
18
+ * @returns Deterministic call ID string
19
+ */
20
+ generateCallId(contract, method, args) {
21
+ const argKey = JSON.stringify(args, (_, v) => {
22
+ if (typeof v === "bigint") {
23
+ return `${String(v)}n`;
24
+ }
25
+ if (typeof v === "object" && v !== null && !Array.isArray(v)) {
26
+ return Object.fromEntries(Object.entries(v).sort(([a], [b]) => a.localeCompare(b)));
27
+ }
28
+ return v;
29
+ });
30
+ return `${contract}:${method}:${argKey}`;
31
+ }
32
+ /**
33
+ * Store a result in the cache.
34
+ *
35
+ * @param callId - The call ID (from generateCallId)
36
+ * @param result - The result to cache
37
+ */
38
+ set(callId, result) {
39
+ this.cache.set(callId, result);
40
+ }
41
+ /**
42
+ * Retrieve a cached result.
43
+ *
44
+ * @param callId - The call ID to look up
45
+ * @returns The cached result, or undefined if not found
46
+ */
47
+ get(callId) {
48
+ return this.cache.get(callId);
49
+ }
50
+ /**
51
+ * Check if a result is cached.
52
+ *
53
+ * @param callId - The call ID to check
54
+ * @returns true if cached, false otherwise
55
+ */
56
+ has(callId) {
57
+ return this.cache.has(callId);
58
+ }
59
+ /**
60
+ * Clear all cached results.
61
+ */
62
+ clear() {
63
+ this.cache.clear();
64
+ }
65
+ }
@@ -0,0 +1,18 @@
1
+ import { type Abi, type Address } from "viem";
2
+ import type { MulticallBatcher } from "./multicall-batcher.js";
3
+ import type { ResultCache } from "./result-cache.js";
4
+ import type { ExecutionContext } from "./types.js";
5
+ import type { ExecutionRound } from "../analysis/types.js";
6
+ export interface ContractInfo {
7
+ abi: Abi;
8
+ address: Address;
9
+ }
10
+ export declare class RoundExecutor {
11
+ private readonly contracts;
12
+ private readonly cache;
13
+ private readonly batcher;
14
+ constructor(contracts: Map<string, ContractInfo>, cache: ResultCache, batcher: MulticallBatcher);
15
+ executeRound(round: ExecutionRound, context: ExecutionContext): Promise<void>;
16
+ private resolveArgs;
17
+ }
18
+ //# sourceMappingURL=round-executor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"round-executor.d.ts","sourceRoot":"","sources":["../../src/execution/round-executor.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,KAAK,GAAG,EACR,KAAK,OAAO,EAGZ,MAAM,MAAM,CAAC;AAKd,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE/D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AACnD,OAAO,KAAK,EAAgB,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAIzE,MAAM,WAAW,YAAY;IAC5B,GAAG,EAAE,GAAG,CAAC;IACT,OAAO,EAAE,OAAO,CAAC;CACjB;AAED,qBAAa,aAAa;IAExB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAFP,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,EACpC,KAAK,EAAE,WAAW,EAClB,OAAO,EAAE,gBAAgB;IAG9B,YAAY,CACxB,KAAK,EAAE,cAAc,EACrB,OAAO,EAAE,gBAAgB,GACvB,OAAO,CAAC,IAAI,CAAC;IA2EhB,OAAO,CAAC,WAAW;CA2BnB"}
@@ -0,0 +1,95 @@
1
+ import { decodeFunctionResult, encodeFunctionData, } from "viem";
2
+ import { createLogger } from "../debug.js";
3
+ import { MulticallBatchError } from "../errors/index.js";
4
+ const debug = createLogger("execute:round");
5
+ export class RoundExecutor {
6
+ contracts;
7
+ cache;
8
+ batcher;
9
+ constructor(contracts, cache, batcher) {
10
+ this.contracts = contracts;
11
+ this.cache = cache;
12
+ this.batcher = batcher;
13
+ }
14
+ async executeRound(round, context) {
15
+ const encodedCalls = [];
16
+ let failedCallIndex;
17
+ let failedCallContract;
18
+ let failedCallMethod;
19
+ try {
20
+ for (const [i, call] of round.calls.entries()) {
21
+ failedCallIndex = i;
22
+ failedCallContract = call.contract;
23
+ failedCallMethod = call.method;
24
+ const contract = this.contracts.get(call.contract);
25
+ if (!contract) {
26
+ throw new Error(`No ABI registered for contract "${call.contract}"`);
27
+ }
28
+ const resolvedArgs = this.resolveArgs(call.args, context);
29
+ encodedCalls.push({
30
+ target: contract.address,
31
+ allowFailure: false,
32
+ callData: encodeFunctionData({
33
+ abi: contract.abi,
34
+ functionName: call.method,
35
+ args: resolvedArgs,
36
+ }),
37
+ });
38
+ }
39
+ }
40
+ catch (error) {
41
+ if (error instanceof MulticallBatchError) {
42
+ throw error;
43
+ }
44
+ throw new MulticallBatchError("Failed to encode call", {
45
+ cause: error,
46
+ failedCallIndex,
47
+ contractName: failedCallContract,
48
+ methodName: failedCallMethod,
49
+ });
50
+ }
51
+ debug("encoding %d calls for multicall", encodedCalls.length);
52
+ const results = await this.batcher.executeBatch(encodedCalls, context.blockNumber);
53
+ for (const [i, call] of round.calls.entries()) {
54
+ const contract = this.contracts.get(call.contract);
55
+ if (!contract) {
56
+ throw new Error(`No ABI registered for contract "${call.contract}"`);
57
+ }
58
+ const result = results[i];
59
+ if (!result?.success) {
60
+ throw new MulticallBatchError(`Call failed: ${call.contract}.${call.method}`, {
61
+ failedCallIndex: i,
62
+ contractName: call.contract,
63
+ methodName: call.method,
64
+ });
65
+ }
66
+ const decoded = decodeFunctionResult({
67
+ abi: contract.abi,
68
+ functionName: call.method,
69
+ data: result.returnData,
70
+ });
71
+ debug("decoded %s.%s -> %o", call.contract, call.method, decoded);
72
+ this.cache.set(call.id, decoded);
73
+ }
74
+ }
75
+ resolveArgs(args, context) {
76
+ return args.map((arg) => {
77
+ if (arg.type === "literal") {
78
+ return arg.value;
79
+ }
80
+ if (arg.type === "variable") {
81
+ const name = arg.variableName;
82
+ if (!name) {
83
+ return undefined;
84
+ }
85
+ return context.variables[name];
86
+ }
87
+ // arg.type === "call_result"
88
+ const id = arg.dependsOnCallId;
89
+ if (!id) {
90
+ return undefined;
91
+ }
92
+ return this.cache.get(id);
93
+ });
94
+ }
95
+ }
@@ -0,0 +1,55 @@
1
+ import type { PublicClient } from "viem";
2
+ /**
3
+ * Metadata about the execution.
4
+ * Contains statistics and block information from the execution run.
5
+ */
6
+ export interface ExecutionMeta {
7
+ /** Number of rounds executed (topological depth) */
8
+ roundsExecuted: number;
9
+ /** Total number of contract calls executed */
10
+ totalCalls: number;
11
+ /** Block number at which calls were executed */
12
+ blockNumber: bigint;
13
+ }
14
+ /**
15
+ * Result of executing an SEL expression with contract calls.
16
+ * Maps call IDs to their decoded results.
17
+ */
18
+ export interface ExecutionResult {
19
+ /** Map of callId to decoded result value */
20
+ results: Map<string, unknown>;
21
+ /** Execution metadata */
22
+ meta: ExecutionMeta;
23
+ }
24
+ /**
25
+ * Context passed to the executor for running contract calls.
26
+ * Contains the client, block number, and variable bindings.
27
+ */
28
+ export interface ExecutionContext {
29
+ /** Viem public client for making contract calls */
30
+ client: PublicClient;
31
+ /** Block number for consistent reads across all calls */
32
+ blockNumber: bigint;
33
+ /** Variable name to value mapping from evaluate() context */
34
+ variables: Record<string, unknown>;
35
+ }
36
+ /**
37
+ * Options for the evaluate() call.
38
+ */
39
+ export interface EvaluateOptions {
40
+ /** Override viem client for this evaluation */
41
+ client?: PublicClient;
42
+ }
43
+ /**
44
+ * Result of evaluating a SEL expression.
45
+ *
46
+ * Always returned by `evaluate()`. The `meta` field is present when
47
+ * contract calls were executed, absent for pure CEL expressions.
48
+ */
49
+ export interface EvaluateResult<T = unknown> {
50
+ /** The evaluated result value */
51
+ value: T;
52
+ /** Execution metadata, present when contract calls were executed */
53
+ meta?: ExecutionMeta;
54
+ }
55
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/execution/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,MAAM,CAAC;AAEzC;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC7B,oDAAoD;IACpD,cAAc,EAAE,MAAM,CAAC;IAEvB,8CAA8C;IAC9C,UAAU,EAAE,MAAM,CAAC;IAEnB,gDAAgD;IAChD,WAAW,EAAE,MAAM,CAAC;CACpB;AAED;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC/B,4CAA4C;IAC5C,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAE9B,yBAAyB;IACzB,IAAI,EAAE,aAAa,CAAC;CACpB;AAED;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAChC,mDAAmD;IACnD,MAAM,EAAE,YAAY,CAAC;IAErB,yDAAyD;IACzD,WAAW,EAAE,MAAM,CAAC;IAEpB,6DAA6D;IAC7D,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC/B,+CAA+C;IAC/C,MAAM,CAAC,EAAE,YAAY,CAAC;CACtB;AAED;;;;;GAKG;AACH,MAAM,WAAW,cAAc,CAAC,CAAC,GAAG,OAAO;IAC1C,iCAAiC;IACjC,KAAK,EAAE,CAAC,CAAC;IAET,oEAAoE;IACpE,IAAI,CAAC,EAAE,aAAa,CAAC;CACrB"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,3 @@
1
+ import { SELRuntime, type SELRuntimeConfig } from "./environment/index.js";
2
+ export declare const createSEL: (config: SELRuntimeConfig) => SELRuntime;
3
+ //# sourceMappingURL=factory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../src/factory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,KAAK,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE3E,eAAO,MAAM,SAAS,GAAI,QAAQ,gBAAgB,KAAG,UAC9B,CAAC"}
@@ -0,0 +1,2 @@
1
+ import { SELRuntime } from "./environment/index.js";
2
+ export const createSEL = (config) => new SELRuntime(config);
@@ -0,0 +1,10 @@
1
+ /**
2
+ * SEL (Solidity Expression Language) - CEL-based queries for EVM contracts.
3
+ * @module @seljs/runtime
4
+ */
5
+ export * from "./environment/index.js";
6
+ export * from "./errors/index.js";
7
+ export * from "./factory.js";
8
+ export type * from "./analysis/index.js";
9
+ export type * from "./execution/index.js";
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,cAAc,wBAAwB,CAAC;AACvC,cAAc,mBAAmB,CAAC;AAClC,cAAc,cAAc,CAAC;AAG7B,mBAAmB,qBAAqB,CAAC;AACzC,mBAAmB,sBAAsB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,7 @@
1
+ /**
2
+ * SEL (Solidity Expression Language) - CEL-based queries for EVM contracts.
3
+ * @module @seljs/runtime
4
+ */
5
+ export * from "./environment/index.js";
6
+ export * from "./errors/index.js";
7
+ export * from "./factory.js";
package/package.json ADDED
@@ -0,0 +1,76 @@
1
+ {
2
+ "name": "@seljs/runtime",
3
+ "version": "1.0.0",
4
+ "license": "Apache-2.0",
5
+ "author": {
6
+ "name": "abi group GmbH",
7
+ "email": "info@abigroup.io",
8
+ "url": "https://abigroup.io/"
9
+ },
10
+ "repository": {
11
+ "url": "https://github.com/abinnovision/seljs"
12
+ },
13
+ "type": "module",
14
+ "exports": {
15
+ ".": {
16
+ "import": "./dist/index.js",
17
+ "types": "./dist/index.d.ts"
18
+ }
19
+ },
20
+ "main": "./dist/index.js",
21
+ "types": "./dist/index.d.ts",
22
+ "files": [
23
+ "dist",
24
+ "LICENSE.md"
25
+ ],
26
+ "scripts": {
27
+ "build": "tsc -p tsconfig.build.json",
28
+ "format:check": "prettier --check '{{src,test}/**/*,*}.{{t,j}s{,x},json{,5},md,y{,a}ml}'",
29
+ "format:fix": "prettier --write '{{src,test}/**/*,*}.{{t,j}s{,x},json{,5},md,y{,a}ml}'",
30
+ "lint:check": "eslint '{{src,test}/**/*,*}.{t,j}s{,x}'",
31
+ "lint:fix": "eslint '{{src,test}/**/*,*}.{t,j}s{,x}' --fix",
32
+ "test-integration": "vitest run --config test/integration/vitest.config.ts",
33
+ "test-unit": "vitest run",
34
+ "test-unit:watch": "vitest watch",
35
+ "typecheck": "tsc --noEmit"
36
+ },
37
+ "dependencies": {
38
+ "@marcbachmann/cel-js": "^7.5.2",
39
+ "@seljs/checker": "1.0.0",
40
+ "@seljs/common": "1.0.0",
41
+ "@seljs/env": "1.0.0",
42
+ "@seljs/schema": "1.0.0",
43
+ "@seljs/types": "1.0.0",
44
+ "debug": "^4.4.3",
45
+ "viem": "^2.47.2"
46
+ },
47
+ "lint-staged": {
48
+ "{{src,test}/**/*,*}.{{t,j}s{,x},json{,5},md,y{,a}ml}": [
49
+ "prettier --write"
50
+ ],
51
+ "{{src,test}/**/*,*}.{t,j}s{,x}": [
52
+ "eslint --fix"
53
+ ]
54
+ },
55
+ "devDependencies": {
56
+ "@abinnovision/eslint-config-base": "^3.2.0",
57
+ "@abinnovision/prettier-config": "^2.1.5",
58
+ "@seljs-internal/fixtures": "0.0.0",
59
+ "@seljs-internal/tsconfig": "^0.0.0",
60
+ "@types/debug": "^4.1.12",
61
+ "concurrently": "^9.2.1",
62
+ "eslint": "^9.39.4",
63
+ "prettier": "^3.8.1",
64
+ "typescript": "^5.9.3",
65
+ "vitest": "^4.0.18",
66
+ "zod": "^4.3.6"
67
+ },
68
+ "peerDependencies": {
69
+ "typescript": "^5",
70
+ "zod": "^4.0.0"
71
+ },
72
+ "publishConfig": {
73
+ "npm": true,
74
+ "npmAccess": "public"
75
+ }
76
+ }