@rootzero/contracts 0.7.2 → 0.9.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 (71) hide show
  1. package/Commands.sol +15 -20
  2. package/Core.sol +3 -4
  3. package/Cursors.sol +3 -2
  4. package/Events.sol +1 -1
  5. package/Queries.sol +3 -3
  6. package/README.md +18 -19
  7. package/Utils.sol +3 -3
  8. package/blocks/Cursors.sol +937 -551
  9. package/blocks/Keys.sol +60 -34
  10. package/blocks/Schema.sol +112 -122
  11. package/blocks/Writers.sol +476 -301
  12. package/commands/Base.sol +32 -22
  13. package/commands/Burn.sol +14 -12
  14. package/commands/Credit.sol +16 -15
  15. package/commands/Debit.sol +14 -12
  16. package/commands/Deposit.sol +30 -37
  17. package/commands/Pipe.sol +14 -20
  18. package/commands/Provision.sol +19 -49
  19. package/commands/Transfer.sol +9 -18
  20. package/commands/Withdraw.sol +15 -14
  21. package/commands/admin/AllowAssets.sol +3 -3
  22. package/commands/admin/Allowance.sol +43 -0
  23. package/commands/admin/Authorize.sol +4 -4
  24. package/commands/admin/DenyAssets.sol +3 -3
  25. package/commands/admin/Destroy.sol +10 -8
  26. package/commands/admin/Execute.sol +38 -0
  27. package/commands/admin/Init.sol +10 -8
  28. package/commands/admin/Relocate.sol +5 -5
  29. package/commands/admin/Unauthorize.sol +4 -4
  30. package/core/Access.sol +38 -34
  31. package/core/Balances.sol +17 -18
  32. package/core/{Operation.sol → Calls.sol} +5 -8
  33. package/core/{CursorBase.sol → Context.sol} +11 -5
  34. package/core/Host.sol +11 -10
  35. package/core/Types.sol +86 -0
  36. package/docs/GETTING_STARTED.md +37 -29
  37. package/events/Asset.sol +1 -1
  38. package/events/Command.sol +10 -10
  39. package/events/Deposit.sol +3 -4
  40. package/events/Listing.sol +1 -1
  41. package/events/Peer.sol +3 -3
  42. package/events/Position.sol +21 -0
  43. package/events/Query.sol +3 -3
  44. package/events/Withdraw.sol +2 -3
  45. package/package.json +1 -1
  46. package/peer/AllowAssets.sol +1 -1
  47. package/peer/Allowance.sol +36 -0
  48. package/peer/AssetPull.sol +33 -31
  49. package/peer/Base.sol +8 -4
  50. package/peer/DenyAssets.sol +1 -1
  51. package/peer/Settle.sol +3 -4
  52. package/queries/Assets.sol +18 -16
  53. package/queries/Balances.sol +21 -19
  54. package/queries/Base.sol +2 -3
  55. package/queries/Positions.sol +32 -24
  56. package/utils/Accounts.sol +14 -13
  57. package/utils/Assets.sol +137 -62
  58. package/utils/Ids.sol +9 -9
  59. package/utils/Layout.sol +5 -3
  60. package/utils/Utils.sol +10 -0
  61. package/commands/Create.sol +0 -42
  62. package/commands/Remove.sol +0 -42
  63. package/commands/Settle.sol +0 -38
  64. package/commands/Stake.sol +0 -47
  65. package/commands/Supply.sol +0 -41
  66. package/commands/admin/Allocate.sol +0 -41
  67. package/core/HostBound.sol +0 -14
  68. package/events/Erc721.sol +0 -20
  69. package/peer/Pull.sol +0 -39
  70. package/peer/Push.sol +0 -45
  71. package/utils/State.sol +0 -22
package/blocks/Keys.sol CHANGED
@@ -1,64 +1,90 @@
1
1
  // SPDX-License-Identifier: GPL-3.0-only
2
2
  pragma solidity ^0.8.33;
3
3
 
4
+ import {Forms} from "./Schema.sol";
5
+
4
6
  /// @title Keys
5
7
  /// @notice Block type selectors for the rootzero block stream protocol.
6
8
  /// Each key is the first 4 bytes of the keccak256 hash of its schema string,
7
9
  /// matching the ABI-selector convention used in `Schemas`.
8
10
  library Keys {
9
- /// @dev Input amount (bytes32 asset, bytes32 meta, uint amount)
11
+ /// @dev Empty / unset key.
12
+ bytes4 constant Empty = bytes4(0);
13
+ /// @dev Input amount - (bytes32 asset, bytes32 meta, uint amount)
10
14
  bytes4 constant Amount = bytes4(keccak256("amount(bytes32 asset, bytes32 meta, uint amount)"));
11
- /// @dev Ledger balance (bytes32 asset, bytes32 meta, uint amount)
15
+ /// @dev Ledger balance - (bytes32 asset, bytes32 meta, uint amount)
12
16
  bytes4 constant Balance = bytes4(keccak256("balance(bytes32 asset, bytes32 meta, uint amount)"));
13
- /// @dev Cross-host custody position (uint host, bytes32 asset, bytes32 meta, uint amount)
17
+ /// @dev Host-scoped request amount - (uint host, bytes32 asset, bytes32 meta, uint amount)
18
+ bytes4 constant Allocation = bytes4(keccak256("allocation(uint host, bytes32 asset, bytes32 meta, uint amount)"));
19
+ /// @dev Host-scoped allowance cap - (uint host, bytes32 asset, bytes32 meta, uint amount)
20
+ bytes4 constant Allowance = bytes4(keccak256("allowance(uint host, bytes32 asset, bytes32 meta, uint amount)"));
21
+ /// @dev Cross-host custody state - (uint host, bytes32 asset, bytes32 meta, uint amount)
14
22
  bytes4 constant Custody = bytes4(keccak256("custody(uint host, bytes32 asset, bytes32 meta, uint amount)"));
15
- /// @dev Minimum acceptable output (bytes32 asset, bytes32 meta, uint amount)
23
+ /// @dev Minimum acceptable output - (bytes32 asset, bytes32 meta, uint amount)
16
24
  bytes4 constant Minimum = bytes4(keccak256("minimum(bytes32 asset, bytes32 meta, uint amount)"));
17
- /// @dev Pair of minimum amounts (uint a, uint b)
18
- bytes4 constant Minimums = bytes4(keccak256("minimums(uint a, uint b)"));
19
- /// @dev Maximum allowable spend — (bytes32 asset, bytes32 meta, uint amount)
25
+ /// @dev Maximum allowable spend - (bytes32 asset, bytes32 meta, uint amount)
20
26
  bytes4 constant Maximum = bytes4(keccak256("maximum(bytes32 asset, bytes32 meta, uint amount)"));
21
- /// @dev Pair of maximum amounts (uint a, uint b)
22
- bytes4 constant Maximums = bytes4(keccak256("maximums(uint a, uint b)"));
23
- /// @dev Signed min/max bounds — (int min, int max)
27
+ /// @dev Signed min/max bounds - (int min, int max)
24
28
  bytes4 constant Bounds = bytes4(keccak256("bounds(int min, int max)"));
25
- /// @dev Fee amount (uint amount)
29
+ /// @dev Fee amount - (uint amount)
26
30
  bytes4 constant Fee = bytes4(keccak256("fee(uint amount)"));
27
- /// @dev Hard stop / iteration sentinel ()
31
+ /// @dev Hard stop / iteration sentinel - ()
28
32
  bytes4 constant Break = bytes4(keccak256("break()"));
29
- /// @dev Bundle wrapper (bytes data); payload is an embedded block stream
33
+ /// @dev Bundle wrapper - (bytes data); payload is an embedded block stream
30
34
  bytes4 constant Bundle = bytes4(keccak256("bundle(bytes data)"));
31
- /// @dev Extensible routing field (bytes data); layout is command-defined
35
+ /// @dev List wrapper - (bytes data); payload is an embedded repeated block stream
36
+ bytes4 constant List = bytes4(keccak256("list(bytes data)"));
37
+ /// @dev Frame wrapper - (bytes data); payload is schema-defined concatenated member payloads
38
+ bytes4 constant Frame = bytes4(keccak256("frame(bytes data)"));
39
+ /// @dev Extensible routing field - (bytes data); layout is command-defined
32
40
  bytes4 constant Route = bytes4(keccak256("route(bytes data)"));
41
+ /// @dev Extensible list item field - (bytes data); layout is implementation-defined
42
+ bytes4 constant Item = bytes4(keccak256("item(bytes data)"));
43
+ /// @dev EVM-encoded payload field - (bytes data); layout follows standard ABI tuple encoding
44
+ bytes4 constant Evm = bytes4(keccak256("evm(bytes data)"));
33
45
  /// @dev Extensible query field - (bytes data); layout is query-defined, key is always `Keys.Query`
34
46
  bytes4 constant Query = bytes4(keccak256("query(bytes data)"));
35
47
  /// @dev Extensible response field - (bytes data); layout is response-defined, key is always `Keys.Response`
36
48
  bytes4 constant Response = bytes4(keccak256("response(bytes data)"));
37
- /// @dev Opaque path payload (bytes data); e.g. a Uniswap path encoding
38
- bytes4 constant Path = bytes4(keccak256("path(bytes data)"));
39
- /// @dev Plain scalar amount — (uint amount)
49
+ /// @dev Plain scalar amount - (uint amount)
40
50
  bytes4 constant Quantity = bytes4(keccak256("quantity(uint amount)"));
41
- /// @dev Ratio or rate value (uint value)
51
+ /// @dev Ratio or rate value - (uint value)
42
52
  bytes4 constant Rate = bytes4(keccak256("rate(uint value)"));
43
- /// @dev Counter-party account (bytes32 account)
44
- /// @dev Destination account (bytes32 account)
45
- bytes4 constant Recipient = bytes4(keccak256("recipient(bytes32 account)"));
46
- /// @dev Transfer record passed through the pipeline — (bytes32 from, bytes32 to, bytes32 asset, bytes32 meta, uint amount)
47
- bytes4 constant Transaction = bytes4(keccak256("tx(bytes32 from, bytes32 to, bytes32 asset, bytes32 meta, uint amount)"));
48
- /// @dev Sub-command invocation (uint target, uint value, bytes request)
53
+ /// @dev Account identifier - (bytes32 account)
54
+ bytes4 constant Account = bytes4(keccak256("account(bytes32 account)"));
55
+ /// @dev Transfer payout request - (bytes32 account, bytes32 asset, bytes32 meta, uint amount)
56
+ bytes4 constant Payout = bytes4(keccak256("payout(bytes32 account, bytes32 asset, bytes32 meta, uint amount)"));
57
+ /// @dev Transfer record passed through the pipeline - (bytes32 from, bytes32 to, bytes32 asset, bytes32 meta, uint amount)
58
+ bytes4 constant Transaction = bytes4(
59
+ keccak256("transaction(bytes32 from, bytes32 to, bytes32 asset, bytes32 meta, uint amount)")
60
+ );
61
+ /// @dev Sub-command invocation - (uint target, uint value, bytes request)
49
62
  bytes4 constant Step = bytes4(keccak256("step(uint target, uint value, bytes request)"));
50
- /// @dev Authentication proof (uint cid, uint deadline, bytes proof); must appear last in its segment
63
+ /// @dev Raw external call - (uint target, uint value, bytes data)
64
+ bytes4 constant Call = bytes4(keccak256("call(uint target, uint value, bytes data)"));
65
+ /// @dev Authentication proof - (uint cid, uint deadline, bytes proof); must appear last in its segment
51
66
  bytes4 constant Auth = bytes4(keccak256("auth(uint cid, uint deadline, bytes proof)"));
52
- /// @dev Asset descriptor without amount (bytes32 asset, bytes32 meta)
67
+ /// @dev Asset descriptor without amount - (bytes32 asset, bytes32 meta)
53
68
  bytes4 constant Asset = bytes4(keccak256("asset(bytes32 asset, bytes32 meta)"));
54
- /// @dev Node identifier (uint id)
69
+ /// @dev Node identifier - (uint id)
55
70
  bytes4 constant Node = bytes4(keccak256("node(uint id)"));
56
- /// @dev Cross-host asset listing (uint host, bytes32 asset, bytes32 meta)
57
- bytes4 constant Listing = bytes4(keccak256("listing(uint host, bytes32 asset, bytes32 meta)"));
58
- /// @dev Liquidity funding entry (uint host, uint amount)
59
- bytes4 constant Funding = bytes4(keccak256("funding(uint host, uint amount)"));
60
- /// @dev Cross-host allocation — (uint host, bytes32 asset, bytes32 meta, uint amount)
61
- bytes4 constant Allocation = bytes4(keccak256("allocation(uint host, bytes32 asset, bytes32 meta, uint amount)"));
62
- /// @dev Relayer bounty — (uint amount, bytes32 relayer)
71
+ /// @dev Native value relocation entry - (uint host, uint amount)
72
+ bytes4 constant Relocation = bytes4(keccak256("relocation(uint host, uint amount)"));
73
+ /// @dev Relayer bounty - (uint amount, bytes32 relayer)
63
74
  bytes4 constant Bounty = bytes4(keccak256("bounty(uint amount, bytes32 relayer)"));
75
+
76
+ /// @dev Structural status form - (bool ok)
77
+ bytes4 constant Status = bytes4(keccak256(bytes(Forms.Status)));
78
+ /// @dev Structural asset amount form - (bytes32 asset, bytes32 meta, uint amount)
79
+ bytes4 constant AssetAmount = bytes4(keccak256(bytes(Forms.AssetAmount)));
80
+ /// @dev Structural account asset form - (bytes32 account, bytes32 asset, bytes32 meta)
81
+ bytes4 constant AccountAsset = bytes4(keccak256(bytes(Forms.AccountAsset)));
82
+ /// @dev Structural account amount form - (bytes32 account, bytes32 asset, bytes32 meta, uint amount)
83
+ bytes4 constant AccountAmount = bytes4(keccak256(bytes(Forms.AccountAmount)));
84
+ /// @dev Structural host amount form - (uint host, bytes32 asset, bytes32 meta, uint amount)
85
+ bytes4 constant HostAmount = bytes4(keccak256(bytes(Forms.HostAmount)));
86
+ /// @dev Structural host account asset form - (uint host, bytes32 account, bytes32 asset, bytes32 meta)
87
+ bytes4 constant HostAccountAsset = bytes4(keccak256(bytes(Forms.HostAccountAsset)));
88
+ /// @dev Structural host account amount form - (uint host, bytes32 account, bytes32 asset, bytes32 meta, uint amount)
89
+ bytes4 constant HostAccountAmount = bytes4(keccak256(bytes(Forms.HostAccountAmount)));
64
90
  }
package/blocks/Schema.sol CHANGED
@@ -1,59 +1,6 @@
1
1
  // SPDX-License-Identifier: GPL-3.0-only
2
2
  pragma solidity ^0.8.33;
3
3
 
4
- import { Keys } from "./Keys.sol";
5
-
6
- /// @title Schemas
7
- /// @notice Human-readable ABI-signature string constants for each block type.
8
- /// These strings are the canonical source from which `Keys` constants are derived
9
- /// and are used when emitting schema descriptors in command events.
10
- library Schemas {
11
- string constant Amount = "amount(bytes32 asset, bytes32 meta, uint amount)";
12
- string constant Balance = "balance(bytes32 asset, bytes32 meta, uint amount)";
13
- string constant Custody = "custody(uint host, bytes32 asset, bytes32 meta, uint amount)";
14
- string constant Minimum = "minimum(bytes32 asset, bytes32 meta, uint amount)";
15
- string constant Minimums = "minimums(uint a, uint b)";
16
- string constant Maximum = "maximum(bytes32 asset, bytes32 meta, uint amount)";
17
- string constant Maximums = "maximums(uint a, uint b)";
18
- string constant Bounds = "bounds(int min, int max)";
19
- string constant Fee = "fee(uint amount)";
20
- string constant Break = "break()";
21
- string constant Route = "route(bytes data)";
22
- string constant Query = "query(bytes data)";
23
- string constant Response = "response(bytes data)";
24
- string constant Path = "path(bytes data)";
25
- string constant RouteEmpty = "route()";
26
- string constant Quantity = "quantity(uint amount)";
27
- string constant Rate = "rate(uint value)";
28
- string constant Recipient = "recipient(bytes32 account)";
29
- string constant Transaction = "tx(bytes32 from, bytes32 to, bytes32 asset, bytes32 meta, uint amount)";
30
- string constant Step = "step(uint target, uint value, bytes request)";
31
- string constant Auth = "auth(uint cid, uint deadline, bytes proof)";
32
- string constant Asset = "asset(bytes32 asset, bytes32 meta)";
33
- string constant Node = "node(uint id)";
34
- string constant Listing = "listing(uint host, bytes32 asset, bytes32 meta)";
35
- string constant Funding = "funding(uint host, uint amount)";
36
- string constant Allocation = "allocation(uint host, bytes32 asset, bytes32 meta, uint amount)";
37
- string constant Bounty = "bounty(uint amount, bytes32 relayer)";
38
-
39
- /// @notice Compose a route schema with one additional field.
40
- /// @param maybeRoute Existing route schema string, or empty string to start a fresh `route()`.
41
- /// @param a Schema string for the field to append.
42
- /// @return Composed schema string: `"route(...) & a"`.
43
- function route1(string memory maybeRoute, string memory a) internal pure returns (string memory) {
44
- return string.concat(bytes(maybeRoute).length == 0 ? RouteEmpty : maybeRoute, "&", a);
45
- }
46
-
47
- /// @notice Compose a route schema with two additional fields.
48
- /// @param maybeRoute Existing route schema string, or empty string to start a fresh `route()`.
49
- /// @param a Schema string for the first field to append.
50
- /// @param b Schema string for the second field to append.
51
- /// @return Composed schema string: `"route(...) & a & b"`.
52
- function route2(string memory maybeRoute, string memory a, string memory b) internal pure returns (string memory) {
53
- return string.concat(bytes(maybeRoute).length == 0 ? RouteEmpty : maybeRoute, "&", a, "&", b);
54
- }
55
- }
56
-
57
4
  // Block stream:
58
5
  // - encoding is [bytes4 key][bytes4 payloadLen][payload]
59
6
  // - `payloadLen` covers only the block payload
@@ -63,27 +10,85 @@ library Schemas {
63
10
  // - self payload may be [head][dynamic tail]
64
11
  // - head layout is implied by the block key
65
12
  // - one dynamic field may consume the rest of self payload without its own length prefix
13
+ // - reserved extensible forms keep one fixed key while their declared field list remains descriptive schema metadata
14
+ // - chain-specific payload blocks are encoded using the local chain/runtime's native conventions
15
+ // - on EVM-family chains, `evm(<fields...>)` payloads use standard ABI tuple encoding via `abi.encode(...)`
16
+ // and can be decoded with `abi.decode`
17
+ // - chain-specific payload blocks are request-only escape hatches and should never be used for pipeline state
18
+ // - prefer ordinary protocol blocks whenever possible; chain-specific payload blocks should be a last resort
66
19
  //
67
20
  // Schema DSL:
68
21
  // - `;` separates top-level sibling blocks
69
22
  // - `&` bundles adjacent blocks into one bundle block
23
+ // - `+` frames adjacent fixed-layout block payloads into one frame block
24
+ // - `&` and `+` follow the same grouping and normalization rules, except they emit different wrapper blocks
25
+ // - `name = a & b` introduces a named bundle item with a local key derived from the raw input string
26
+ // - `name = a + b` introduces a named frame item with a local key derived from the raw input string
27
+ // - `bundle = a & b` introduces an anonymous child bundle item
28
+ // - `frame = a + b` introduces an anonymous child frame item, like `bundle = ...` and `list = ...`
29
+ // - postfix `[]` marks a repeated list in the simple suffix form, e.g. `asset(...)[]`
30
+ // - `name[] = a & b` introduces a named list with a local key derived from the raw input string
31
+ // - `list = a & b` introduces an anonymous list whose repeated item is the bundled shape `a & b`
32
+ // - empty entries are ignored, but structural markers are preserved after normalization
33
+ // - grouping parentheses are not part of the DSL; parentheses are only used in block field lists
34
+ // - `+` binds tighter than `&`, so `a & b + c` normalizes as `a & (b + c)`
35
+ // - if `&` appears, the result remains a bundle even when only one non-empty child remains
36
+ // - if `+` appears, the result remains a frame even when only one non-empty child remains
37
+ // - after ignoring empty entries, repeated adjacent separators collapse while preserving bundle/frame/list shape
70
38
  // - bundled blocks preserve member order, so `a & b` differs from `b & a`
71
39
  // - a bundle block's self payload is an embedded normal block stream of its bundled members
72
40
  // - bundled members keep their ordinary block encoding, so dynamic blocks are allowed inside bundles
73
- // - `->` separates request and response shapes, appears at most once, and is omitted when no output is modeled
41
+ // - a list block's self payload is an embedded normal block stream representing the repeated items
42
+ // - a frame block's self payload is the concatenated payload fields of its framed members
43
+ // - framed members do not keep their ordinary block headers; the emitted schema defines the frame layout
44
+ // - framed members must be fixed-layout block forms because frame payloads contain no child lengths or block keys
45
+ // - frames may be bundled like ordinary block items, but bundles/lists cannot be framed
74
46
  // - top-level blocks of the same type should be grouped together
75
47
  // - primary / driving blocks should appear before auxiliary blocks
76
- // - `route(<fields...>)`, `query(<fields...>)`, and `response(<fields...>)` are reserved
77
- // extensible schema forms whose keys are always `Keys.Route`, `Keys.Query`, and
78
- // `Keys.Response` respectively
48
+ // - `route(<fields...>)`, `item(<fields...>)`, `evm(<fields...>)`, `query(<fields...>)`,
49
+ // and `response(<fields...>)` are reserved extensible schema forms whose keys are always
50
+ // `Keys.Route`, `Keys.Item`, `Keys.Evm`, `Keys.Query`, and `Keys.Response` respectively
79
51
  // - these extensible forms work like dynamic `bytes` blocks: they may carry arbitrary
80
52
  // payload bytes while keeping one fixed key per semantic block type
81
- // - `&` compiles to a `Keys.Bundle` block whose self payload is the bundled member block stream
53
+ // - `evm(<fields...>)` differs from bundle/list payloads: its bytes are not an embedded block stream
54
+ // - `evm(uint foo, uint bar)` is a schema declaration only; on-chain the block key is still `Keys.Evm`
55
+ // and the payload can be decoded from `bytes data` using the local runtime's native decoder
56
+ // - on EVM, `evm(bool flag)` occupies one full 32-byte ABI word, exactly like `abi.encode(flag)`
57
+ // - anonymous `&` compiles to a `Keys.Bundle` block whose self payload is the bundled member block stream
58
+ // - anonymous `[]` compiles to a `Keys.List` block whose self payload is the repeated item block stream
59
+ // - anonymous `+` compiles to a `Keys.Frame` block whose self payload is the framed member payload fields
60
+ // - named lists, bundles, and frames use bytes4(keccak256(bytes(rawSchemaInput))) as their block key
61
+ // - named structural keys are custom/local identifiers, not global protocol keys; formatting is part of identity
62
+ // - `asset(...)[]` means a list whose repeated item is the block `asset(...)`
63
+ // - `steps[] = asset(...) & account(...)` means a named list whose repeated item is the bundle
64
+ // `asset(...) & account(...)`
65
+ // - `payment = amount(...) + fee(...)` means a named frame whose payload is
66
+ // `asset | meta | amount | fee` and whose on-chain key is derived from that raw schema string
67
+ // - `amount(...) & fee(...) + account(...)` means `amount(...) & (fee(...) + account(...))`;
68
+ // it compiles to a bundle containing one amount block followed by one frame block
69
+ // - `bundle = account(...) & evm(bytes routeData)` means an anonymous child bundle with those bundled members
70
+ // - `frame = amount(...) + fee(...)` means an anonymous child frame with those framed payload fields
71
+ // - `list = asset(...) & account(...)` means an anonymous child list whose repeated item is the
72
+ // bundle `asset(...) & account(...)`
73
+ // - `"amount(...) &"` and `"& amount(...)"` both normalize to a bundle containing one `amount(...)` child
74
+ // - `"amount(...) +"` and `"+ amount(...)"` both normalize to a frame containing one `amount(...)` payload
82
75
  // - canonical blocks are `amount(...)` for request amounts, `balance(...)` for state balances,
76
+ // `allocation(...)` for host-scoped provision requests, `allowance(...)` for host-scoped caps,
77
+ // `custody(...)` for host-scoped state,
83
78
  // `minimum(...)` for result floors, `maximum(...)` for spend ceilings, and `quantity(...)`
84
79
  // for plain scalar amounts
85
80
  // - `auth(uint cid, uint deadline, bytes proof)` is a proof-separator block and must be emitted last
86
81
  //
82
+ // Pipeline state:
83
+ // - `balance(...)` and `custody(...)` are live, linear state in the active command pipeline
84
+ // - pipeline state belongs to the active account while the pipeline is executing
85
+ // - while a balance or custody is in-flight as pipeline state, it is not simultaneously persisted
86
+ // in another ledger/store by this protocol
87
+ // - commands must preserve, transform, settle, or intentionally consume pipeline state
88
+ // - request blocks such as `amount(...)`, `allocation(...)`, `allowance(...)`, `payout(...)`,
89
+ // `minimum(...)`, and `maximum(...)` express intent, constraints, or references
90
+ // - request and value/response blocks are not live state
91
+ //
87
92
  // Signed blocks:
88
93
  // - an authenticated input segment ends with one trailing AUTH block
89
94
  // - auth is typically grouped with the signed payload in one bundle, with AUTH as the final member
@@ -92,6 +97,53 @@ library Schemas {
92
97
  // - `cid` binds the signature to one command; `deadline` acts as expiry and nonce
93
98
  // - current helpers assume proof layout `[bytes20 signer][bytes65 sig]`
94
99
 
100
+ /// @title Schemas
101
+ /// @notice Human-readable ABI-signature string constants for each block type.
102
+ /// These strings are the canonical source from which `Keys` constants are derived
103
+ /// and are used when emitting schema descriptors in command events.
104
+ library Schemas {
105
+ string constant Node = "node(uint id)";
106
+ string constant Account = "account(bytes32 account)";
107
+ string constant Asset = "asset(bytes32 asset, bytes32 meta)";
108
+ string constant Balance = "balance(bytes32 asset, bytes32 meta, uint amount)";
109
+ string constant Amount = "amount(bytes32 asset, bytes32 meta, uint amount)";
110
+ string constant Minimum = "minimum(bytes32 asset, bytes32 meta, uint amount)";
111
+ string constant Maximum = "maximum(bytes32 asset, bytes32 meta, uint amount)";
112
+ string constant Custody = "custody(uint host, bytes32 asset, bytes32 meta, uint amount)";
113
+ string constant Payout = "payout(bytes32 account, bytes32 asset, bytes32 meta, uint amount)";
114
+ string constant Allocation = "allocation(uint host, bytes32 asset, bytes32 meta, uint amount)";
115
+ string constant Allowance = "allowance(uint host, bytes32 asset, bytes32 meta, uint amount)";
116
+ string constant Transaction = "transaction(bytes32 from, bytes32 to, bytes32 asset, bytes32 meta, uint amount)";
117
+ string constant Relocation = "relocation(uint host, uint amount)";
118
+ string constant Call = "call(uint target, uint value, bytes data)";
119
+ string constant Step = "step(uint target, uint value, bytes request)";
120
+ string constant Bounty = "bounty(uint amount, bytes32 relayer)";
121
+ string constant Quantity = "quantity(uint amount)";
122
+ string constant Fee = "fee(uint amount)";
123
+ string constant Rate = "rate(uint value)";
124
+ string constant Bounds = "bounds(int min, int max)";
125
+ string constant Auth = "auth(uint cid, uint deadline, bytes proof)";
126
+ string constant Route = "route(bytes data)";
127
+ string constant Item = "item(bytes data)";
128
+ string constant Evm = "evm(bytes data)";
129
+ string constant Query = "query(bytes data)";
130
+ string constant Response = "response(bytes data)";
131
+ string constant Break = "break()";
132
+ }
133
+
134
+ /// @title Forms
135
+ /// @notice Reusable structural block schemas for core tuple shapes.
136
+ /// These describe payload form without assigning command or query semantics.
137
+ library Forms {
138
+ string constant Status = "status(bool ok)";
139
+ string constant AssetAmount = "assetAmount(bytes32 asset, bytes32 meta, uint amount)";
140
+ string constant AccountAsset = "accountAsset(bytes32 account, bytes32 asset, bytes32 meta)";
141
+ string constant AccountAmount = "accountAmount(bytes32 account, bytes32 asset, bytes32 meta, uint amount)";
142
+ string constant HostAmount = "hostAmount(uint host, bytes32 asset, bytes32 meta, uint amount)";
143
+ string constant HostAccountAsset = "hostAccountAsset(uint host, bytes32 account, bytes32 asset, bytes32 meta)";
144
+ string constant HostAccountAmount = "hostAccountAmount(uint host, bytes32 account, bytes32 asset, bytes32 meta, uint amount)";
145
+ }
146
+
95
147
  /// @title Sizes
96
148
  /// @notice Total byte sizes for fixed-width block types, including the 8-byte header (4-byte key + 4-byte payloadLen).
97
149
  library Sizes {
@@ -117,76 +169,14 @@ library Sizes {
117
169
  uint constant Amount = B96;
118
170
  /// @dev BALANCE block: 8 header + 32 asset + 32 meta + 32 amount = 104 bytes
119
171
  uint constant Balance = B96;
120
- /// @dev MINIMUMS block: 8 header + 32 a + 32 b = 72 bytes
121
- uint constant Minimums = B64;
122
- /// @dev MAXIMUMS block: 8 header + 32 a + 32 b = 72 bytes
123
- uint constant Maximums = B64;
124
172
  /// @dev BOUNDS block: 8 header + 32 min + 32 max = 72 bytes
125
173
  uint constant Bounds = B64;
126
174
  /// @dev FEE block: 8 header + 32 amount = 40 bytes
127
175
  uint constant Fee = B32;
128
176
  /// @dev BOUNTY block: 8 header + 32 amount + 32 relayer = 72 bytes
129
177
  uint constant Bounty = B64;
130
- /// @dev CUSTODY block: 8 header + 32 host + 32 asset + 32 meta + 32 amount = 136 bytes
131
- uint constant Custody = B128;
178
+ /// @dev ALLOCATION/CUSTODY block: 8 header + 32 host + 32 asset + 32 meta + 32 amount = 136 bytes
179
+ uint constant HostAmount = B128;
132
180
  /// @dev TRANSACTION block: 8 header + 32 from + 32 to + 32 asset + 32 meta + 32 amount = 168 bytes
133
181
  uint constant Transaction = B160;
134
182
  }
135
-
136
- /// @notice Asset and amount pair; used for balance and amount blocks.
137
- struct AssetAmount {
138
- /// @dev Asset identifier (encoding depends on asset type — see `Assets` library).
139
- bytes32 asset;
140
- /// @dev Asset metadata slot (e.g. token contract address or ERC-721 token ID context).
141
- bytes32 meta;
142
- /// @dev Token amount in the asset's native units.
143
- uint amount;
144
- }
145
-
146
- /// @notice Cross-host custody value; used for custody and allocation blocks.
147
- struct HostAmount {
148
- /// @dev Host node ID that holds the custody position.
149
- uint host;
150
- /// @dev Asset identifier.
151
- bytes32 asset;
152
- /// @dev Asset metadata slot.
153
- bytes32 meta;
154
- /// @dev Token amount in the asset's native units.
155
- uint amount;
156
- }
157
-
158
- /// @notice User-scoped amount; associates an account with an asset amount.
159
- struct UserAmount {
160
- /// @dev User account identifier.
161
- bytes32 account;
162
- /// @dev Asset identifier.
163
- bytes32 asset;
164
- /// @dev Asset metadata slot.
165
- bytes32 meta;
166
- /// @dev Token amount in the asset's native units.
167
- uint amount;
168
- }
169
-
170
- /// @notice Cross-host asset descriptor without an amount.
171
- struct HostAsset {
172
- /// @dev Host node ID.
173
- uint host;
174
- /// @dev Asset identifier.
175
- bytes32 asset;
176
- /// @dev Asset metadata slot.
177
- bytes32 meta;
178
- }
179
-
180
- /// @notice Transfer payload used across the pipeline and later consumed by settlement.
181
- struct Tx {
182
- /// @dev Sender account identifier.
183
- bytes32 from;
184
- /// @dev Recipient account identifier.
185
- bytes32 to;
186
- /// @dev Asset identifier.
187
- bytes32 asset;
188
- /// @dev Asset metadata slot.
189
- bytes32 meta;
190
- /// @dev Transfer amount in the asset's native units.
191
- uint amount;
192
- }