@rootzero/contracts 1.7.0 → 1.8.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.
package/CHANGELOG.md CHANGED
@@ -3,6 +3,26 @@
3
3
  Until the protocol reaches integration-stable status, minor versions may include
4
4
  breaking API changes. Breaking changes are called out explicitly.
5
5
 
6
+ ## 1.8.0
7
+
8
+ ### Breaking Changes
9
+
10
+ - Removed per-port `IPort*` interfaces. Port callers should use port node IDs,
11
+ discovery metadata, and `PortCalls.callPort`.
12
+ - Removed unused standalone ABI encoder helpers: `encodePortCall`,
13
+ `encodeGuardCall`, and `encodeQueryCall`.
14
+ - Reworked `NodeCalls` into a low-level node-call layer:
15
+ - `callAddr` and `queryAddr` were removed.
16
+ - `callTo` and `queryTo` were removed.
17
+ - Raw node calls now use `rawCall`, `tryRawCall`, and `rawQuery`.
18
+
19
+ ### Added
20
+
21
+ - Added `trustedCall`, `tryTrustedCall`, and `trustedQuery` as shared trusted
22
+ wrappers over the raw node-call helpers.
23
+ - Added `CommandCalls.callCommand` and `PortCalls.callPort` for selector-based
24
+ trusted calls to command and port nodes.
25
+
6
26
  ## 1.7.0
7
27
 
8
28
  ### Breaking Changes
package/Core.sol CHANGED
@@ -10,7 +10,7 @@ import { Commitments } from "./core/Commitments.sol";
10
10
  import { Escrows, InsufficientEscrow } from "./core/Escrows.sol";
11
11
  import { NativeAsset, Runtime } from "./core/Runtime.sol";
12
12
  import { Host, IHostIntroduction } from "./core/Host.sol";
13
- import { FailedCall, NodeCalls } from "./core/Calls.sol";
13
+ import { CommandCalls, FailedCall, NodeCalls, PortCalls } from "./core/Calls.sol";
14
14
  import { Payable } from "./core/Payable.sol";
15
15
  import { Pipeline } from "./core/Pipeline.sol";
16
16
  import { AssetAmount, AccountAsset, AccountAmount, HostAmount, HostAccountAsset, HostAccountAmount, Tx } from "./core/Types.sol";
package/Endpoints.sol CHANGED
@@ -35,23 +35,23 @@ import { Label } from "./commands/admin/Label.sol";
35
35
  import { Unauthorize } from "./commands/admin/Unauthorize.sol";
36
36
 
37
37
  // Port endpoints
38
- import { PortBase, encodePortCall } from "./ports/Base.sol";
39
- import { PortAllowAssets, IPortAllowAssets } from "./ports/AllowAssets.sol";
40
- import { PortAllowance, IPortAllowance } from "./ports/Allowance.sol";
41
- import { PortRedeemBalance, RedeemBalanceHook, IPortRedeemBalance } from "./ports/Redeem.sol";
42
- import { PortCreditAccount, IPortCreditAccount } from "./ports/Credit.sol";
43
- import { PortDebitAccount, IPortDebitAccount } from "./ports/Debit.sol";
44
- import { PortDenyAssets, IPortDenyAssets } from "./ports/DenyAssets.sol";
45
- import { PortPipePayable, IPortPipePayable } from "./ports/Pipe.sol";
46
- import { PortDispatchPayable, IPortDispatchPayable } from "./ports/Dispatch.sol";
47
- import { PortSettle, IPortSettle } from "./ports/Settle.sol";
38
+ import { PortBase } from "./ports/Base.sol";
39
+ import { PortAllowAssets } from "./ports/AllowAssets.sol";
40
+ import { PortAllowance } from "./ports/Allowance.sol";
41
+ import { PortRedeemBalance, RedeemBalanceHook } from "./ports/Redeem.sol";
42
+ import { PortCreditAccount } from "./ports/Credit.sol";
43
+ import { PortDebitAccount } from "./ports/Debit.sol";
44
+ import { PortDenyAssets } from "./ports/DenyAssets.sol";
45
+ import { PortPipePayable } from "./ports/Pipe.sol";
46
+ import { PortDispatchPayable } from "./ports/Dispatch.sol";
47
+ import { PortSettle } from "./ports/Settle.sol";
48
48
 
49
49
  // Guard endpoints
50
- import { GuardBase, encodeGuardCall } from "./guards/Base.sol";
50
+ import { GuardBase } from "./guards/Base.sol";
51
51
  import { Revoke } from "./guards/Revoke.sol";
52
52
 
53
53
  // Query endpoints
54
- import { QueryBase, encodeQueryCall } from "./queries/Base.sol";
54
+ import { QueryBase } from "./queries/Base.sol";
55
55
  import { AssetStatus, AssetStatusHook } from "./queries/Assets.sol";
56
56
  import { GetBalances, GetBalancesHook } from "./queries/Balances.sol";
57
57
  import { GetPosition, GetPositionHook } from "./queries/Positions.sol";
@@ -5,7 +5,6 @@ import {AdminBase, CommandContext, Keys} from "./Base.sol";
5
5
  import {Payable} from "../../core/Payable.sol";
6
6
  import {Cursors, Cur, Schemas} from "../../Cursors.sol";
7
7
  import {Budget} from "../../utils/Value.sol";
8
- import {Nodes} from "../../utils/Nodes.sol";
9
8
 
10
9
  using Cursors for Cur;
11
10
 
@@ -31,8 +30,7 @@ abstract contract ExecutePayable is AdminBase, Payable {
31
30
 
32
31
  while (request.i < request.len) {
33
32
  (uint target, uint resources, bytes calldata data) = request.unpackCall();
34
- address addr = Nodes.addr(target);
35
- callAddr(addr, useValue(budget, resources), data);
33
+ rawCall(target, useValue(budget, resources), data);
36
34
  }
37
35
 
38
36
  request.complete();
package/core/Calls.sol CHANGED
@@ -12,7 +12,7 @@ import {Nodes} from "../utils/Nodes.sol";
12
12
  error FailedCall(address addr, bytes4 selector, bytes err);
13
13
 
14
14
  /// @title NodeCalls
15
- /// @notice Shared trusted inter-node call helpers for contracts that can talk to other nodes.
15
+ /// @notice Shared low-level inter-node call helpers for contracts that can talk to other nodes.
16
16
  abstract contract NodeCalls is AccessControl {
17
17
  /// @notice Return the host node ID corresponding to the current caller.
18
18
  /// @dev Encodes `msg.sender` as a host ID using the local-chain host layout.
@@ -21,64 +21,100 @@ abstract contract NodeCalls is AccessControl {
21
21
  return Nodes.toHost(msg.sender);
22
22
  }
23
23
 
24
- /// @notice Make a low-level call to an address.
25
- /// Forwards `value` ETH and `data` to `addr`.
26
- /// Reverts with `FailedCall` if the call is unsuccessful.
27
- /// @param addr Contract address to call.
24
+ /// @notice Try a raw low-level call to another node and return whether it succeeded.
25
+ /// @param node Node ID of the callee.
28
26
  /// @param value Native value to forward in wei.
29
27
  /// @param data Encoded calldata to send.
30
- /// @return out Return data from the successful call.
31
- function callAddr(address addr, uint128 value, bytes memory data) internal returns (bytes memory out) {
32
- bool success;
33
- (success, out) = payable(addr).call{value: value}(data);
34
- if (!success) revert FailedCall(addr, bytes4(data), out);
28
+ /// @return success True if the low-level call succeeded.
29
+ function tryRawCall(uint node, uint128 value, bytes memory data) internal returns (bool success) {
30
+ address addr = Nodes.addr(node);
31
+ (success, ) = payable(addr).call{value: value}(data);
35
32
  }
36
33
 
37
- /// @notice Make a low-level read-only query to an address.
38
- /// Issues a low-level `staticcall` with `data`.
39
- /// Reverts with `FailedCall` if the call is unsuccessful.
40
- /// @param addr Contract address to query.
34
+ /// @notice Try a trusted low-level call to another node and return whether it succeeded.
35
+ /// @param node Node ID of the callee.
36
+ /// @param value Native value to forward in wei.
41
37
  /// @param data Encoded calldata to send.
42
- /// @return out Return data from the successful query.
43
- function queryAddr(address addr, bytes memory data) internal view returns (bytes memory out) {
38
+ /// @return success True if the low-level call succeeded.
39
+ function tryTrustedCall(uint node, uint128 value, bytes memory data) internal returns (bool success) {
40
+ return tryRawCall(ensureTrusted(node), value, data);
41
+ }
42
+
43
+ /// @notice Make a raw low-level call to another node and revert when it fails.
44
+ /// @param node Node ID of the callee.
45
+ /// @param value Native value to forward in wei.
46
+ /// @param data Encoded calldata to send.
47
+ /// @return out Return data from the successful call.
48
+ function rawCall(uint node, uint128 value, bytes memory data) internal returns (bytes memory out) {
44
49
  bool success;
45
- (success, out) = addr.staticcall(data);
50
+ address addr = Nodes.addr(node);
51
+ (success, out) = payable(addr).call{value: value}(data);
46
52
  if (!success) revert FailedCall(addr, bytes4(data), out);
47
53
  }
48
54
 
49
- /// @notice Make a trusted call to another node in the network.
50
- /// Looks up the node's contract address via `ensureTrusted` + `Nodes.addr`,
51
- /// then issues a low-level call forwarding `value` ETH and `data`.
52
- /// @param node Node ID of the callee (must be in the authorized set).
55
+ /// @notice Make a trusted low-level call to another node and revert when it fails.
56
+ /// @param node Node ID of the callee.
53
57
  /// @param value Native value to forward in wei.
54
58
  /// @param data Encoded calldata to send.
55
59
  /// @return out Return data from the successful call.
56
- function callTo(uint node, uint128 value, bytes memory data) internal returns (bytes memory out) {
57
- ensureTrusted(node);
58
- address addr = Nodes.addr(node);
59
- return callAddr(addr, value, data);
60
+ function trustedCall(uint node, uint128 value, bytes memory data) internal returns (bytes memory out) {
61
+ return rawCall(ensureTrusted(node), value, data);
60
62
  }
61
63
 
62
- /// @notice Make a trusted query to another node in the network.
63
- /// Looks up the node's contract address via `ensureTrusted` + `Nodes.addr`,
64
- /// then issues a low-level `staticcall` with `data`.
65
- /// @param node Node ID of the callee (must be in the authorized set).
64
+ /// @notice Make a raw low-level read-only query to another node and revert when it fails.
65
+ /// @param node Node ID of the callee.
66
66
  /// @param data Encoded calldata to send.
67
67
  /// @return out Return data from the successful query.
68
- function queryTo(uint node, bytes memory data) internal view returns (bytes memory out) {
69
- ensureTrusted(node);
68
+ function rawQuery(uint node, bytes memory data) internal view returns (bytes memory out) {
69
+ bool success;
70
70
  address addr = Nodes.addr(node);
71
- return queryAddr(addr, data);
71
+ (success, out) = addr.staticcall(data);
72
+ if (!success) revert FailedCall(addr, bytes4(data), out);
73
+ }
74
+
75
+ /// @notice Make a trusted low-level read-only query to another node and revert when it fails.
76
+ /// @param node Node ID of the callee.
77
+ /// @param data Encoded calldata to send.
78
+ /// @return out Return data from the successful query.
79
+ function trustedQuery(uint node, bytes memory data) internal view returns (bytes memory out) {
80
+ return rawQuery(ensureTrusted(node), data);
72
81
  }
82
+ }
73
83
 
84
+ /// @title CommandCalls
85
+ /// @notice Trusted command-call helpers for contracts that route command nodes.
86
+ abstract contract CommandCalls is NodeCalls {
74
87
  /// @notice Encode and call a trusted command node.
75
- /// @param id Command node ID embedding the target selector.
88
+ /// @param command Command node ID embedding the target selector.
76
89
  /// @param value Native value to forward in wei.
77
- /// @param ctx Command execution context.
90
+ /// @param account Command account identifier.
91
+ /// @param state Current command state block stream.
92
+ /// @param request Command input block stream.
78
93
  /// @return Decoded command output block stream.
79
- function callCommand(uint id, uint128 value, CommandContext memory ctx) internal returns (bytes memory) {
80
- bytes4 selector = Nodes.commandSelector(id);
81
- bytes memory data = abi.encodeWithSelector(selector, ctx);
82
- return abi.decode(callTo(id, value, data), (bytes));
94
+ function callCommand(
95
+ uint command,
96
+ uint128 value,
97
+ bytes32 account,
98
+ bytes memory state,
99
+ bytes calldata request
100
+ ) internal returns (bytes memory) {
101
+ bytes4 selector = Nodes.commandSelector(command);
102
+ bytes memory data = abi.encodeWithSelector(selector, CommandContext(account, state, request));
103
+ return abi.decode(trustedCall(command, value, data), (bytes));
104
+ }
105
+ }
106
+
107
+ /// @title PortCalls
108
+ /// @notice Trusted port-call helpers for contracts that route port nodes.
109
+ abstract contract PortCalls is NodeCalls {
110
+ /// @notice Encode and call a trusted port node.
111
+ /// @param port Port node ID embedding the target selector.
112
+ /// @param value Native value to forward in wei.
113
+ /// @param input Port input block stream.
114
+ /// @return Decoded port output block stream.
115
+ function callPort(uint port, uint128 value, bytes memory input) internal returns (bytes memory) {
116
+ bytes4 selector = Nodes.portSelector(port);
117
+ bytes memory data = abi.encodeWithSelector(selector, input);
118
+ return abi.decode(trustedCall(port, value, data), (bytes));
83
119
  }
84
120
  }
package/guards/Base.sol CHANGED
@@ -6,17 +6,6 @@ import {GuardEvent} from "../events/Guard.sol";
6
6
  import {LabeledEvent} from "../events/Labeled.sol";
7
7
  import {Nodes} from "../utils/Nodes.sol";
8
8
 
9
- /// @notice ABI-encode a guard action call from a target guard ID and request block stream.
10
- /// @dev Derives the function selector from `target` via `Nodes.guardSelector(target)`.
11
- /// Reverts if `target` is not a valid guard ID.
12
- /// @param target Destination guard action node ID embedding the target selector.
13
- /// @param request Input block stream for the guard invocation.
14
- /// @return ABI-encoded calldata for the guard action entry point.
15
- function encodeGuardCall(uint target, bytes calldata request) pure returns (bytes memory) {
16
- bytes4 selector = Nodes.guardSelector(target);
17
- return abi.encodeWithSelector(selector, request);
18
- }
19
-
20
9
  /// @title GuardBase
21
10
  /// @notice Abstract base for guardian-only direct host actions.
22
11
  /// Guard actions are non-payable direct calls with no command context, state, or response.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rootzero/contracts",
3
- "version": "1.7.0",
3
+ "version": "1.8.0",
4
4
  "description": "Solidity contracts and protocol building blocks for rootzero hosts and commands.",
5
5
  "private": false,
6
6
  "license": "GPL-3.0-only",
@@ -7,14 +7,10 @@ import { Cursors, Cur, Schemas } from "../Cursors.sol";
7
7
 
8
8
  using Cursors for Cur;
9
9
 
10
- interface IPortAllowAssets {
11
- function portAllowAssets(bytes calldata data) external returns (bytes memory);
12
- }
13
-
14
10
  /// @title PortAllowAssets
15
11
  /// @notice Port that permits a list of assets on behalf of a peer host.
16
12
  /// Each ASSET block in the request calls `allowAsset`. Restricted to trusted peers.
17
- abstract contract PortAllowAssets is PortBase, AllowAssetsHook, IPortAllowAssets {
13
+ abstract contract PortAllowAssets is PortBase, AllowAssetsHook {
18
14
  uint internal immutable portAllowAssetsId = portId(this.portAllowAssets.selector);
19
15
 
20
16
  constructor() {
@@ -7,15 +7,11 @@ import {Cursors, Cur, Schemas} from "../Cursors.sol";
7
7
 
8
8
  using Cursors for Cur;
9
9
 
10
- interface IPortAllowance {
11
- function portAllowance(bytes calldata data) external returns (bytes memory);
12
- }
13
-
14
10
  /// @title PortAllowance
15
11
  /// @notice Port that lets a trusted peer host request or refresh its own allowance.
16
12
  /// Each AMOUNT block in the request is scoped to the peer host and passed to the
17
13
  /// shared allowance hook as a host-scoped allowance. Restricted to trusted peers.
18
- abstract contract PortAllowance is PortBase, AllowanceHook, IPortAllowance {
14
+ abstract contract PortAllowance is PortBase, AllowanceHook {
19
15
  uint internal immutable portAllowanceId = portId(this.portAllowance.selector);
20
16
 
21
17
  constructor() {
package/ports/Base.sol CHANGED
@@ -6,17 +6,6 @@ import { PortEvent } from "../events/Port.sol";
6
6
  import { LabeledEvent } from "../events/Labeled.sol";
7
7
  import { Nodes } from "../utils/Nodes.sol";
8
8
 
9
- /// @notice ABI-encode a port call from a target port ID and data block stream.
10
- /// @dev Derives the function selector from `target` via `Nodes.portSelector(target)`.
11
- /// Reverts if `target` is not a valid port ID.
12
- /// @param target Destination port node ID embedding the target selector.
13
- /// @param data Input block stream for the port invocation.
14
- /// @return ABI-encoded calldata for the port entry point.
15
- function encodePortCall(uint target, bytes calldata data) pure returns (bytes memory) {
16
- bytes4 selector = Nodes.portSelector(target);
17
- return abi.encodeWithSelector(selector, data);
18
- }
19
-
20
9
  /// @title PortBase
21
10
  /// @notice Abstract base for peer-facing rootzero ports.
22
11
  /// Ports handle inter-host operations between cooperating hosts.
package/ports/Credit.sol CHANGED
@@ -7,14 +7,10 @@ import { Cursors, Cur, Forms } from "../Cursors.sol";
7
7
 
8
8
  using Cursors for Cur;
9
9
 
10
- interface IPortCreditAccount {
11
- function portCreditAccount(bytes calldata data) external returns (bytes memory);
12
- }
13
-
14
10
  /// @title PortCreditAccount
15
11
  /// @notice Port that lets a trusted peer credit supplied accounts directly.
16
12
  /// Each ACCOUNT_AMOUNT block calls `creditAccount` for its account.
17
- abstract contract PortCreditAccount is PortBase, CreditAccountHook, IPortCreditAccount {
13
+ abstract contract PortCreditAccount is PortBase, CreditAccountHook {
18
14
  uint internal immutable portCreditAccountId = portId(this.portCreditAccount.selector);
19
15
 
20
16
  constructor() {
package/ports/Debit.sol CHANGED
@@ -7,14 +7,10 @@ import { Cursors, Cur, Forms } from "../Cursors.sol";
7
7
 
8
8
  using Cursors for Cur;
9
9
 
10
- interface IPortDebitAccount {
11
- function portDebitAccount(bytes calldata data) external returns (bytes memory);
12
- }
13
-
14
10
  /// @title PortDebitAccount
15
11
  /// @notice Port that lets a trusted peer debit supplied accounts directly.
16
12
  /// Each ACCOUNT_AMOUNT block calls `debitAccount` for its account.
17
- abstract contract PortDebitAccount is PortBase, DebitAccountHook, IPortDebitAccount {
13
+ abstract contract PortDebitAccount is PortBase, DebitAccountHook {
18
14
  uint internal immutable portDebitAccountId = portId(this.portDebitAccount.selector);
19
15
 
20
16
  constructor() {
@@ -7,14 +7,10 @@ import {Cursors, Cur, Schemas} from "../Cursors.sol";
7
7
 
8
8
  using Cursors for Cur;
9
9
 
10
- interface IPortDenyAssets {
11
- function portDenyAssets(bytes calldata data) external returns (bytes memory);
12
- }
13
-
14
10
  /// @title PortDenyAssets
15
11
  /// @notice Port that blocks a list of assets on behalf of a peer host.
16
12
  /// Each ASSET block in the request calls `denyAsset`. Restricted to trusted peers.
17
- abstract contract PortDenyAssets is PortBase, DenyAssetsHook, IPortDenyAssets {
13
+ abstract contract PortDenyAssets is PortBase, DenyAssetsHook {
18
14
  uint internal immutable portDenyAssetsId = portId(this.portDenyAssets.selector);
19
15
 
20
16
  constructor() {
@@ -9,13 +9,9 @@ import { Budget } from "../utils/Value.sol";
9
9
 
10
10
  using Cursors for Cur;
11
11
 
12
- interface IPortDispatchPayable {
13
- function portDispatchPayable(bytes calldata data) external payable returns (bytes memory);
14
- }
15
-
16
12
  /// @title PortDispatchPayable
17
13
  /// @notice Port endpoint that forwards DISPATCH blocks to a host-defined dispatch hook.
18
- abstract contract PortDispatchPayable is PortBase, Payable, DispatchPayableHook, IPortDispatchPayable {
14
+ abstract contract PortDispatchPayable is PortBase, Payable, DispatchPayableHook {
19
15
  uint internal immutable portDispatchPayableId = portId(this.portDispatchPayable.selector);
20
16
 
21
17
  constructor() {
package/ports/Pipe.sol CHANGED
@@ -8,14 +8,10 @@ import {Budget} from "../utils/Value.sol";
8
8
 
9
9
  using Cursors for Cur;
10
10
 
11
- interface IPortPipePayable {
12
- function portPipePayable(bytes calldata data) external payable returns (bytes memory);
13
- }
14
-
15
11
  /// @title PortPipePayable
16
12
  /// @notice Port that consumes CONTEXT blocks and executes each request as a step stream.
17
13
  /// Each context's request bytes are passed to the shared pipeline.
18
- abstract contract PortPipePayable is PortBase, Pipeline, IPortPipePayable {
14
+ abstract contract PortPipePayable is PortBase, Pipeline {
19
15
  uint internal immutable portPipePayableId = portId(this.portPipePayable.selector);
20
16
 
21
17
  constructor() {
package/ports/Redeem.sol CHANGED
@@ -6,10 +6,6 @@ import {Cursors, Cur, Schemas} from "../Cursors.sol";
6
6
 
7
7
  using Cursors for Cur;
8
8
 
9
- interface IPortRedeemBalance {
10
- function portRedeemBalance(bytes calldata data) external returns (bytes memory);
11
- }
12
-
13
9
  abstract contract RedeemBalanceHook {
14
10
  /// @notice Override to redeem one balance claim from a peer host into local assets.
15
11
  /// @param peer Peer host node ID for this request.
@@ -22,7 +18,7 @@ abstract contract RedeemBalanceHook {
22
18
  /// @notice Port that redeems balance state from a peer host into local assets.
23
19
  /// Each BALANCE block in the request calls `redeemBalance(peer, asset, amount)`.
24
20
  /// Restricted to trusted peers.
25
- abstract contract PortRedeemBalance is PortBase, RedeemBalanceHook, IPortRedeemBalance {
21
+ abstract contract PortRedeemBalance is PortBase, RedeemBalanceHook {
26
22
  uint internal immutable portRedeemBalanceId = portId(this.portRedeemBalance.selector);
27
23
 
28
24
  constructor() {
package/ports/Settle.sol CHANGED
@@ -8,14 +8,10 @@ import { Cursors, Cur, Schemas } from "../Cursors.sol";
8
8
 
9
9
  using Cursors for Cur;
10
10
 
11
- interface IPortSettle {
12
- function portSettle(bytes calldata data) external returns (bytes memory);
13
- }
14
-
15
11
  /// @title PortSettle
16
12
  /// @notice Port that consumes peer-supplied TRANSACTION blocks through debit and credit hooks.
17
13
  /// Each TRANSACTION block calls `debitAccount` for `from` and `creditAccount` for `to`.
18
- abstract contract PortSettle is PortBase, DebitAccountHook, CreditAccountHook, IPortSettle {
14
+ abstract contract PortSettle is PortBase, DebitAccountHook, CreditAccountHook {
19
15
  uint internal immutable portSettleId = portId(this.portSettle.selector);
20
16
 
21
17
  constructor() {
package/queries/Base.sol CHANGED
@@ -6,17 +6,6 @@ import { LabeledEvent } from "../events/Labeled.sol";
6
6
  import { QueryEvent } from "../events/Query.sol";
7
7
  import { Nodes } from "../utils/Nodes.sol";
8
8
 
9
- /// @notice ABI-encode a query call from a target query ID and request block stream.
10
- /// @dev Derives the function selector from `target` via `Nodes.querySelector(target)`.
11
- /// Reverts if `target` is not a valid query ID.
12
- /// @param target Destination query node ID embedding the target selector.
13
- /// @param request Input block stream for the query invocation.
14
- /// @return ABI-encoded calldata for the query entry point.
15
- function encodeQueryCall(uint target, bytes calldata request) pure returns (bytes memory) {
16
- bytes4 selector = Nodes.querySelector(target);
17
- return abi.encodeWithSelector(selector, request);
18
- }
19
-
20
9
  /// @title QueryBase
21
10
  /// @notice Abstract base for rootzero query contracts.
22
11
  /// Queries are view-only entry points that consume a block-stream request and