@seljs/runtime 1.3.0-beta.2 → 1.3.0-beta.3

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.
@@ -196,6 +196,25 @@ const collectCalls = (ast, registry) => {
196
196
  return;
197
197
  }
198
198
  if (!receiverName || !registry.get(receiverName)) {
199
+ if (method === "balance" && args.length === 0) {
200
+ const receiverNode = node.args[1];
201
+ const { arg: receiverArg, traversed } = classifyArg(receiverNode);
202
+ if (receiverArg) {
203
+ const call = {
204
+ id: generateCallId("__multicall3", "getEthBalance", [receiverArg]),
205
+ contract: "__multicall3",
206
+ method: "getEthBalance",
207
+ args: [receiverArg],
208
+ astNode: node
209
+ };
210
+ calls.push(call);
211
+ debug("found address accessor %s (id=%s)", "balance", call.id);
212
+ return call;
213
+ }
214
+ deferredNodes.add(node);
215
+ if (!traversed) traverse(receiverNode);
216
+ return;
217
+ }
199
218
  handleNonContractRCall(node, method, args);
200
219
  return;
201
220
  }
@@ -195,6 +195,25 @@ const collectCalls = (ast, registry) => {
195
195
  return;
196
196
  }
197
197
  if (!receiverName || !registry.get(receiverName)) {
198
+ if (method === "balance" && args.length === 0) {
199
+ const receiverNode = node.args[1];
200
+ const { arg: receiverArg, traversed } = classifyArg(receiverNode);
201
+ if (receiverArg) {
202
+ const call = {
203
+ id: generateCallId("__multicall3", "getEthBalance", [receiverArg]),
204
+ contract: "__multicall3",
205
+ method: "getEthBalance",
206
+ args: [receiverArg],
207
+ astNode: node
208
+ };
209
+ calls.push(call);
210
+ debug("found address accessor %s (id=%s)", "balance", call.id);
211
+ return call;
212
+ }
213
+ deferredNodes.add(node);
214
+ if (!traversed) traverse(receiverNode);
215
+ return;
216
+ }
198
217
  handleNonContractRCall(node, method, args);
199
218
  return;
200
219
  }
@@ -0,0 +1,22 @@
1
+ const require_multicall = require("../execution/multicall.cjs");
2
+ //#region src/environment/builtin-contracts.ts
3
+ /**
4
+ * Returns built-in contract schemas that are always available in the runtime.
5
+ * These are internal contracts not defined by the user schema but required
6
+ * for built-in features like address accessors.
7
+ */
8
+ const getBuiltinContracts = (multicall) => [{
9
+ name: "__multicall3",
10
+ address: multicall?.address ?? "0xcA11bde05977b3631167028862bE2a173976CA11",
11
+ methods: [{
12
+ name: "getEthBalance",
13
+ params: [{
14
+ name: "addr",
15
+ type: "sol_address"
16
+ }],
17
+ returns: "sol_int",
18
+ abi: require_multicall.getEthBalanceAbi
19
+ }]
20
+ }];
21
+ //#endregion
22
+ exports.getBuiltinContracts = getBuiltinContracts;
@@ -0,0 +1,22 @@
1
+ import { getEthBalanceAbi } from "../execution/multicall.mjs";
2
+ //#region src/environment/builtin-contracts.ts
3
+ /**
4
+ * Returns built-in contract schemas that are always available in the runtime.
5
+ * These are internal contracts not defined by the user schema but required
6
+ * for built-in features like address accessors.
7
+ */
8
+ const getBuiltinContracts = (multicall) => [{
9
+ name: "__multicall3",
10
+ address: multicall?.address ?? "0xcA11bde05977b3631167028862bE2a173976CA11",
11
+ methods: [{
12
+ name: "getEthBalance",
13
+ params: [{
14
+ name: "addr",
15
+ type: "sol_address"
16
+ }],
17
+ returns: "sol_int",
18
+ abi: getEthBalanceAbi
19
+ }]
20
+ }];
21
+ //#endregion
22
+ export { getBuiltinContracts };
@@ -1,4 +1,5 @@
1
1
  require("../_virtual/_rolldown/runtime.cjs");
2
+ const require_builtin_contracts = require("./builtin-contracts.cjs");
2
3
  const require_errors = require("../errors/errors.cjs");
3
4
  require("../errors/index.cjs");
4
5
  const require_client = require("./client.cjs");
@@ -73,16 +74,20 @@ var SELRuntime = class {
73
74
  this.multicallOptions = config.multicall;
74
75
  if (config.client) require_client.validateClient(config.client);
75
76
  this.client = config.client;
76
- this.schema = config.schema;
77
+ this.schema = {
78
+ ...config.schema,
79
+ contracts: [...config.schema.contracts, ...require_builtin_contracts.getBuiltinContracts(config.multicall)]
80
+ };
77
81
  const handler = (contractName, methodName, args) => {
78
- const contract = this.findContract(contractName);
79
- if (!contract) throw new require_errors.SELContractError(`Unknown contract "${contractName}"`, { contractName });
80
- const method = contract.methods.find((m) => m.name === methodName);
81
- if (!method) throw new require_errors.SELContractError(`Unknown method "${contractName}.${methodName}"`, {
82
- contractName,
83
- methodName
82
+ const resolved = this.resolveCall(contractName, methodName, args);
83
+ const contract = this.findContract(resolved.contractName);
84
+ if (!contract) throw new require_errors.SELContractError(`Unknown contract "${resolved.contractName}"`, { contractName: resolved.contractName });
85
+ const method = contract.methods.find((m) => m.name === resolved.methodName);
86
+ if (!method) throw new require_errors.SELContractError(`Unknown method "${resolved.contractName}.${resolved.methodName}"`, {
87
+ contractName: resolved.contractName,
88
+ methodName: resolved.methodName
84
89
  });
85
- return require_contract_caller.executeContractCall(contract, method, args, {
90
+ return require_contract_caller.executeContractCall(contract, method, resolved.args, {
86
91
  executionCache: this.currentCache,
87
92
  client: this.currentClient ?? this.client,
88
93
  codecRegistry: this.codecRegistry,
@@ -247,6 +252,22 @@ var SELRuntime = class {
247
252
  throw require_error_wrapper.wrapError(error);
248
253
  }
249
254
  }
255
+ /**
256
+ * Remaps receiver method calls to their underlying contract calls.
257
+ * e.g., sol_address.balance() → __multicall3.getEthBalance(addr)
258
+ */
259
+ resolveCall(contractName, methodName, args) {
260
+ if (contractName === "sol_address" && methodName === "balance") return {
261
+ contractName: "__multicall3",
262
+ methodName: "getEthBalance",
263
+ args
264
+ };
265
+ return {
266
+ contractName,
267
+ methodName,
268
+ args
269
+ };
270
+ }
250
271
  findContract(name) {
251
272
  return this.schema.contracts.find((c) => c.name === name);
252
273
  }
@@ -79,6 +79,11 @@ declare class SELRuntime {
79
79
  private planExecution;
80
80
  private executeContractCalls;
81
81
  private doEvaluate;
82
+ /**
83
+ * Remaps receiver method calls to their underlying contract calls.
84
+ * e.g., sol_address.balance() → __multicall3.getEthBalance(addr)
85
+ */
86
+ private resolveCall;
82
87
  private findContract;
83
88
  }
84
89
  //#endregion
@@ -79,6 +79,11 @@ declare class SELRuntime {
79
79
  private planExecution;
80
80
  private executeContractCalls;
81
81
  private doEvaluate;
82
+ /**
83
+ * Remaps receiver method calls to their underlying contract calls.
84
+ * e.g., sol_address.balance() → __multicall3.getEthBalance(addr)
85
+ */
86
+ private resolveCall;
82
87
  private findContract;
83
88
  }
84
89
  //#endregion
@@ -1,3 +1,4 @@
1
+ import { getBuiltinContracts } from "./builtin-contracts.mjs";
1
2
  import { MulticallBatchError, SELContractError, SELLintError, SELTypeError } from "../errors/errors.mjs";
2
3
  import "../errors/index.mjs";
3
4
  import { validateClient } from "./client.mjs";
@@ -71,16 +72,20 @@ var SELRuntime = class {
71
72
  this.multicallOptions = config.multicall;
72
73
  if (config.client) validateClient(config.client);
73
74
  this.client = config.client;
74
- this.schema = config.schema;
75
+ this.schema = {
76
+ ...config.schema,
77
+ contracts: [...config.schema.contracts, ...getBuiltinContracts(config.multicall)]
78
+ };
75
79
  const handler = (contractName, methodName, args) => {
76
- const contract = this.findContract(contractName);
77
- if (!contract) throw new SELContractError(`Unknown contract "${contractName}"`, { contractName });
78
- const method = contract.methods.find((m) => m.name === methodName);
79
- if (!method) throw new SELContractError(`Unknown method "${contractName}.${methodName}"`, {
80
- contractName,
81
- methodName
80
+ const resolved = this.resolveCall(contractName, methodName, args);
81
+ const contract = this.findContract(resolved.contractName);
82
+ if (!contract) throw new SELContractError(`Unknown contract "${resolved.contractName}"`, { contractName: resolved.contractName });
83
+ const method = contract.methods.find((m) => m.name === resolved.methodName);
84
+ if (!method) throw new SELContractError(`Unknown method "${resolved.contractName}.${resolved.methodName}"`, {
85
+ contractName: resolved.contractName,
86
+ methodName: resolved.methodName
82
87
  });
83
- return executeContractCall(contract, method, args, {
88
+ return executeContractCall(contract, method, resolved.args, {
84
89
  executionCache: this.currentCache,
85
90
  client: this.currentClient ?? this.client,
86
91
  codecRegistry: this.codecRegistry,
@@ -245,6 +250,22 @@ var SELRuntime = class {
245
250
  throw wrapError(error);
246
251
  }
247
252
  }
253
+ /**
254
+ * Remaps receiver method calls to their underlying contract calls.
255
+ * e.g., sol_address.balance() → __multicall3.getEthBalance(addr)
256
+ */
257
+ resolveCall(contractName, methodName, args) {
258
+ if (contractName === "sol_address" && methodName === "balance") return {
259
+ contractName: "__multicall3",
260
+ methodName: "getEthBalance",
261
+ args
262
+ };
263
+ return {
264
+ contractName,
265
+ methodName,
266
+ args
267
+ };
268
+ }
248
269
  findContract(name) {
249
270
  return this.schema.contracts.find((c) => c.name === name);
250
271
  }
@@ -1,8 +1,8 @@
1
1
  require("../_virtual/_rolldown/runtime.cjs");
2
+ const require_multicall = require("./multicall.cjs");
2
3
  const require_errors = require("../errors/errors.cjs");
3
4
  require("../errors/index.cjs");
4
5
  const require_debug = require("../debug.cjs");
5
- const require_multicall = require("./multicall.cjs");
6
6
  let ox = require("ox");
7
7
  //#region src/execution/multicall-batcher.ts
8
8
  const debug = require_debug.createLogger("execute:multicall");
@@ -1,7 +1,7 @@
1
+ import { multicall3Function } from "./multicall.mjs";
1
2
  import { MulticallBatchError } from "../errors/errors.mjs";
2
3
  import "../errors/index.mjs";
3
4
  import { createLogger } from "../debug.mjs";
4
- import { multicall3Function } from "./multicall.mjs";
5
5
  import { AbiFunction } from "ox";
6
6
  //#region src/execution/multicall-batcher.ts
7
7
  const debug = createLogger("execute:multicall");
@@ -40,6 +40,24 @@ const MULTICALL3_ADDRESS = "0xcA11bde05977b3631167028862bE2a173976CA11";
40
40
  * Pre-parsed Multicall3 aggregate3 ABI function for ox encoding/decoding.
41
41
  */
42
42
  const multicall3Function = ox.AbiFunction.from(aggregate3Abi);
43
+ /**
44
+ * Multicall3 getEthBalance ABI — returns native ETH balance for an address.
45
+ * Used by the sol_address.balance() accessor.
46
+ */
47
+ const getEthBalanceAbi = {
48
+ name: "getEthBalance",
49
+ type: "function",
50
+ stateMutability: "view",
51
+ inputs: [{
52
+ name: "addr",
53
+ type: "address"
54
+ }],
55
+ outputs: [{
56
+ name: "balance",
57
+ type: "uint256"
58
+ }]
59
+ };
43
60
  //#endregion
44
61
  exports.MULTICALL3_ADDRESS = MULTICALL3_ADDRESS;
62
+ exports.getEthBalanceAbi = getEthBalanceAbi;
45
63
  exports.multicall3Function = multicall3Function;
@@ -39,5 +39,22 @@ const MULTICALL3_ADDRESS = "0xcA11bde05977b3631167028862bE2a173976CA11";
39
39
  * Pre-parsed Multicall3 aggregate3 ABI function for ox encoding/decoding.
40
40
  */
41
41
  const multicall3Function = AbiFunction.from(aggregate3Abi);
42
+ /**
43
+ * Multicall3 getEthBalance ABI — returns native ETH balance for an address.
44
+ * Used by the sol_address.balance() accessor.
45
+ */
46
+ const getEthBalanceAbi = {
47
+ name: "getEthBalance",
48
+ type: "function",
49
+ stateMutability: "view",
50
+ inputs: [{
51
+ name: "addr",
52
+ type: "address"
53
+ }],
54
+ outputs: [{
55
+ name: "balance",
56
+ type: "uint256"
57
+ }]
58
+ };
42
59
  //#endregion
43
- export { MULTICALL3_ADDRESS, multicall3Function };
60
+ export { MULTICALL3_ADDRESS, getEthBalanceAbi, multicall3Function };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@seljs/runtime",
3
- "version": "1.3.0-beta.2",
3
+ "version": "1.3.0-beta.3",
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.2",
54
- "@seljs/common": "1.3.0-beta.2",
55
- "@seljs/env": "1.3.0-beta.2",
53
+ "@seljs/checker": "1.3.0-beta.3",
54
+ "@seljs/common": "1.3.0-beta.3",
55
+ "@seljs/env": "1.3.0-beta.3",
56
56
  "@seljs/schema": "1.2.0",
57
- "@seljs/types": "1.3.0-beta.2",
57
+ "@seljs/types": "1.3.0-beta.3",
58
58
  "debug": "^4.4.3",
59
59
  "ox": "^0.14.7"
60
60
  },