@rootzero/contracts 0.9.3 → 0.9.4
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/Commands.sol +3 -2
- package/Core.sol +3 -0
- package/Cursors.sol +1 -1
- package/README.md +18 -24
- package/blocks/Cursors.sol +294 -339
- package/blocks/Keys.sol +38 -57
- package/blocks/Schema.sol +55 -208
- package/blocks/Writers.sol +345 -135
- package/commands/Base.sol +6 -48
- package/commands/Burn.sol +2 -2
- package/commands/Credit.sol +3 -3
- package/commands/Debit.sol +3 -2
- package/commands/Deposit.sol +11 -8
- package/commands/Provision.sol +11 -8
- package/commands/Transfer.sol +2 -2
- package/commands/Withdraw.sol +3 -3
- package/commands/admin/AllowAssets.sol +1 -1
- package/commands/admin/Allowance.sol +1 -1
- package/commands/admin/Authorize.sol +1 -1
- package/commands/admin/DenyAssets.sol +1 -1
- package/commands/admin/Execute.sol +7 -6
- package/commands/admin/Unauthorize.sol +1 -1
- package/core/Access.sol +11 -0
- package/core/Context.sol +3 -4
- package/core/Payable.sol +57 -0
- package/core/Pipeline.sol +55 -0
- package/docs/Schema.md +194 -0
- package/events/Command.sol +1 -2
- package/package.json +2 -2
- package/peer/AllowAssets.sol +1 -1
- package/peer/Allowance.sol +1 -1
- package/peer/BalancePull.sol +1 -1
- package/peer/DenyAssets.sol +1 -1
- package/peer/Pipe.sol +38 -0
- package/peer/Settle.sol +1 -1
- package/queries/Assets.sol +4 -3
- package/queries/Balances.sol +2 -1
- package/queries/Positions.sol +12 -12
- package/utils/Value.sol +8 -14
- package/commands/Pipe.sol +0 -67
- package/docs/GETTING_STARTED.md +0 -294
package/blocks/Keys.sol
CHANGED
|
@@ -1,88 +1,69 @@
|
|
|
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
|
-
|
|
6
4
|
/// @title Keys
|
|
7
5
|
/// @notice Block type selectors for the rootzero block stream protocol.
|
|
8
|
-
/// Each key is the first 4 bytes of the keccak256 hash of its
|
|
9
|
-
/// matching the ABI-selector convention used in `Schemas`.
|
|
6
|
+
/// Each key is the first 4 bytes of the keccak256 hash of its block name.
|
|
10
7
|
library Keys {
|
|
11
8
|
/// @dev Empty / unset key.
|
|
12
9
|
bytes4 constant Empty = bytes4(0);
|
|
13
10
|
/// @dev Input amount - (bytes32 asset, bytes32 meta, uint amount)
|
|
14
|
-
bytes4 constant Amount = bytes4(keccak256("amount
|
|
11
|
+
bytes4 constant Amount = bytes4(keccak256("#amount"));
|
|
15
12
|
/// @dev Ledger balance - (bytes32 asset, bytes32 meta, uint amount)
|
|
16
|
-
bytes4 constant Balance = bytes4(keccak256("balance
|
|
13
|
+
bytes4 constant Balance = bytes4(keccak256("#balance"));
|
|
17
14
|
/// @dev Host-scoped request amount - (uint host, bytes32 asset, bytes32 meta, uint amount)
|
|
18
|
-
bytes4 constant Allocation = bytes4(keccak256("allocation
|
|
15
|
+
bytes4 constant Allocation = bytes4(keccak256("#allocation"));
|
|
19
16
|
/// @dev Host-scoped allowance cap - (uint host, bytes32 asset, bytes32 meta, uint amount)
|
|
20
|
-
bytes4 constant Allowance = bytes4(keccak256("allowance
|
|
17
|
+
bytes4 constant Allowance = bytes4(keccak256("#allowance"));
|
|
21
18
|
/// @dev Cross-host custody state - (uint host, bytes32 asset, bytes32 meta, uint amount)
|
|
22
|
-
bytes4 constant Custody = bytes4(keccak256("custody
|
|
19
|
+
bytes4 constant Custody = bytes4(keccak256("#custody"));
|
|
23
20
|
/// @dev Minimum acceptable output - (bytes32 asset, bytes32 meta, uint amount)
|
|
24
|
-
bytes4 constant Minimum = bytes4(keccak256("minimum
|
|
21
|
+
bytes4 constant Minimum = bytes4(keccak256("#minimum"));
|
|
25
22
|
/// @dev Maximum allowable spend - (bytes32 asset, bytes32 meta, uint amount)
|
|
26
|
-
bytes4 constant Maximum = bytes4(keccak256("maximum
|
|
27
|
-
/// @dev Signed min/max bounds - (int min, int max)
|
|
28
|
-
bytes4 constant Bounds = bytes4(keccak256("bounds(int min, int max)"));
|
|
23
|
+
bytes4 constant Maximum = bytes4(keccak256("#maximum"));
|
|
29
24
|
/// @dev Fee amount - (uint amount)
|
|
30
|
-
bytes4 constant Fee = bytes4(keccak256("fee
|
|
31
|
-
/// @dev
|
|
32
|
-
bytes4 constant
|
|
33
|
-
/// @dev
|
|
34
|
-
bytes4 constant
|
|
35
|
-
/// @dev
|
|
36
|
-
bytes4 constant
|
|
37
|
-
/// @dev
|
|
38
|
-
bytes4 constant
|
|
39
|
-
/// @dev Extensible routing field - (bytes data); layout is command-defined
|
|
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)"));
|
|
45
|
-
/// @dev Extensible query field - (bytes data); layout is query-defined, key is always `Keys.Query`
|
|
46
|
-
bytes4 constant Query = bytes4(keccak256("query(bytes data)"));
|
|
47
|
-
/// @dev Extensible response field - (bytes data); layout is response-defined, key is always `Keys.Response`
|
|
48
|
-
bytes4 constant Response = bytes4(keccak256("response(bytes data)"));
|
|
49
|
-
/// @dev Plain scalar amount - (uint amount)
|
|
50
|
-
bytes4 constant Quantity = bytes4(keccak256("quantity(uint amount)"));
|
|
51
|
-
/// @dev Ratio or rate value - (uint value)
|
|
52
|
-
bytes4 constant Rate = bytes4(keccak256("rate(uint value)"));
|
|
25
|
+
bytes4 constant Fee = bytes4(keccak256("#fee"));
|
|
26
|
+
/// @dev List wrapper; payload is an embedded repeated block stream
|
|
27
|
+
bytes4 constant List = bytes4(keccak256("#list"));
|
|
28
|
+
/// @dev Extensible data field; layout is schema-defined
|
|
29
|
+
bytes4 constant Data = bytes4(keccak256("#data"));
|
|
30
|
+
/// @dev EVM-encoded payload field; layout follows standard ABI tuple encoding
|
|
31
|
+
bytes4 constant Evm = bytes4(keccak256("#evm"));
|
|
32
|
+
/// @dev Reserved raw bytes child block.
|
|
33
|
+
bytes4 constant Bytes = bytes4(keccak256("#bytes"));
|
|
53
34
|
/// @dev Account identifier - (bytes32 account)
|
|
54
|
-
bytes4 constant Account = bytes4(keccak256("account
|
|
35
|
+
bytes4 constant Account = bytes4(keccak256("#account"));
|
|
55
36
|
/// @dev Transfer payout request - (bytes32 account, bytes32 asset, bytes32 meta, uint amount)
|
|
56
|
-
bytes4 constant Payout = bytes4(keccak256("payout
|
|
37
|
+
bytes4 constant Payout = bytes4(keccak256("#payout"));
|
|
57
38
|
/// @dev Transfer record passed through the pipeline - (bytes32 from, bytes32 to, bytes32 asset, bytes32 meta, uint amount)
|
|
58
|
-
bytes4 constant Transaction = bytes4(
|
|
59
|
-
|
|
60
|
-
);
|
|
61
|
-
/// @dev
|
|
62
|
-
bytes4 constant
|
|
63
|
-
/// @dev
|
|
64
|
-
bytes4 constant
|
|
65
|
-
/// @dev Authentication proof - (uint cid, uint deadline, bytes proof); must appear last in its segment
|
|
66
|
-
bytes4 constant Auth = bytes4(keccak256("auth
|
|
39
|
+
bytes4 constant Transaction = bytes4(keccak256("#transaction"));
|
|
40
|
+
/// @dev Sub-command invocation - (uint target, uint value, #bytes as request)
|
|
41
|
+
bytes4 constant Step = bytes4(keccak256("#step"));
|
|
42
|
+
/// @dev Raw external call - (uint target, uint value, #bytes as payload)
|
|
43
|
+
bytes4 constant Call = bytes4(keccak256("#call"));
|
|
44
|
+
/// @dev Command context transport - (bytes32 account, #bytes as state, #bytes as request)
|
|
45
|
+
bytes4 constant Context = bytes4(keccak256("#context"));
|
|
46
|
+
/// @dev Authentication proof - (uint cid, uint deadline, #bytes as proof); must appear last in its segment
|
|
47
|
+
bytes4 constant Auth = bytes4(keccak256("#auth"));
|
|
67
48
|
/// @dev Asset descriptor without amount - (bytes32 asset, bytes32 meta)
|
|
68
|
-
bytes4 constant Asset = bytes4(keccak256("asset
|
|
49
|
+
bytes4 constant Asset = bytes4(keccak256("#asset"));
|
|
69
50
|
/// @dev Node identifier - (uint id)
|
|
70
|
-
bytes4 constant Node = bytes4(keccak256("node
|
|
51
|
+
bytes4 constant Node = bytes4(keccak256("#node"));
|
|
71
52
|
/// @dev Relayer bounty - (uint amount, bytes32 relayer)
|
|
72
|
-
bytes4 constant Bounty = bytes4(keccak256("bounty
|
|
53
|
+
bytes4 constant Bounty = bytes4(keccak256("#bounty"));
|
|
73
54
|
|
|
74
55
|
/// @dev Structural status form - (bool ok)
|
|
75
|
-
bytes4 constant Status = bytes4(keccak256(
|
|
56
|
+
bytes4 constant Status = bytes4(keccak256("#status"));
|
|
76
57
|
/// @dev Structural asset amount form - (bytes32 asset, bytes32 meta, uint amount)
|
|
77
|
-
bytes4 constant AssetAmount = bytes4(keccak256(
|
|
58
|
+
bytes4 constant AssetAmount = bytes4(keccak256("#assetAmount"));
|
|
78
59
|
/// @dev Structural account asset form - (bytes32 account, bytes32 asset, bytes32 meta)
|
|
79
|
-
bytes4 constant AccountAsset = bytes4(keccak256(
|
|
60
|
+
bytes4 constant AccountAsset = bytes4(keccak256("#accountAsset"));
|
|
80
61
|
/// @dev Structural account amount form - (bytes32 account, bytes32 asset, bytes32 meta, uint amount)
|
|
81
|
-
bytes4 constant AccountAmount = bytes4(keccak256(
|
|
62
|
+
bytes4 constant AccountAmount = bytes4(keccak256("#accountAmount"));
|
|
82
63
|
/// @dev Structural host amount form - (uint host, bytes32 asset, bytes32 meta, uint amount)
|
|
83
|
-
bytes4 constant HostAmount = bytes4(keccak256(
|
|
64
|
+
bytes4 constant HostAmount = bytes4(keccak256("#hostAmount"));
|
|
84
65
|
/// @dev Structural host account asset form - (uint host, bytes32 account, bytes32 asset, bytes32 meta)
|
|
85
|
-
bytes4 constant HostAccountAsset = bytes4(keccak256(
|
|
66
|
+
bytes4 constant HostAccountAsset = bytes4(keccak256("#hostAccountAsset"));
|
|
86
67
|
/// @dev Structural host account amount form - (uint host, bytes32 account, bytes32 asset, bytes32 meta, uint amount)
|
|
87
|
-
bytes4 constant HostAccountAmount = bytes4(keccak256(
|
|
68
|
+
bytes4 constant HostAccountAmount = bytes4(keccak256("#hostAccountAmount"));
|
|
88
69
|
}
|
package/blocks/Schema.sol
CHANGED
|
@@ -3,174 +3,26 @@ pragma solidity ^0.8.33;
|
|
|
3
3
|
|
|
4
4
|
// Block stream:
|
|
5
5
|
// - encoding is [bytes4 key][bytes4 payloadLen][payload]
|
|
6
|
-
// - `payloadLen` covers only the block payload
|
|
6
|
+
// - `payloadLen` is big-endian and covers only the block payload
|
|
7
7
|
// - payload layout is block-specific
|
|
8
8
|
//
|
|
9
|
-
//
|
|
10
|
-
// -
|
|
11
|
-
// -
|
|
12
|
-
// -
|
|
13
|
-
// -
|
|
14
|
-
// -
|
|
15
|
-
// -
|
|
16
|
-
//
|
|
17
|
-
// -
|
|
18
|
-
// -
|
|
19
|
-
// -
|
|
20
|
-
//
|
|
21
|
-
//
|
|
22
|
-
//
|
|
23
|
-
// -
|
|
24
|
-
// -
|
|
25
|
-
//
|
|
26
|
-
// - the first top-level item is the prime item unless it is the schema-only `empty` sentinel
|
|
27
|
-
// - the prime item must have one runtime key; helpers consume the consecutive run of blocks with
|
|
28
|
-
// that key as the per-operation batch, and `Command.shape` is defined over those prime runs
|
|
29
|
-
// - `empty` emits no block, has no runtime key, and must only appear as the first top-level item
|
|
30
|
-
// before global blocks; it means the schema has no prime item
|
|
31
|
-
// - top-level items after the prime item or `empty` are global batch support blocks: they apply to
|
|
32
|
-
// the whole batch, may be searched or consumed separately by the command, and are not counted as
|
|
33
|
-
// per-operation prime blocks
|
|
34
|
-
// - `&` bundles adjacent blocks into one bundle block
|
|
35
|
-
// - `+` frames adjacent fixed-layout block payloads into one frame block
|
|
36
|
-
// - `+&` appends adjacent blocks to a frame as full block-stream items, preserving their headers
|
|
37
|
-
// - leading `&` is shorthand for an anonymous bundle
|
|
38
|
-
// - leading `+&` is shorthand for an anonymous frame with only a block-stream tail
|
|
39
|
-
// - `&`, `+`, and `+&` follow the same grouping and normalization rules, except they emit different payload forms
|
|
40
|
-
// - `name = a & b` introduces a named bundle item with a local key derived from the raw input string
|
|
41
|
-
// - `name = a + b` introduces a named frame item with a local key derived from the raw input string
|
|
42
|
-
// - `alias: item` attaches a presentation alias to the following schema item for off-chain APIs,
|
|
43
|
-
// docs, and UI labels
|
|
44
|
-
// - `bundle = a & b` introduces an anonymous child bundle item
|
|
45
|
-
// - `frame = a + b` introduces an anonymous child frame item, like `bundle = ...` and `list = ...`
|
|
46
|
-
// - `(fields...)` in item position is shorthand for an anonymous frame with those fields
|
|
47
|
-
// - `(fields...)` inside an existing frame introduces anonymous flattened frame fields without a nested frame key
|
|
48
|
-
// - postfix `[]` marks a repeated list in the simple suffix form, e.g. `asset(...)[]`
|
|
49
|
-
// - postfix `?` marks an optional item, e.g. `account(...)?`
|
|
50
|
-
// - `name[] = a & b` introduces a named list with a local key derived from the raw input string
|
|
51
|
-
// - `name? = a & b` introduces an optional named structural item
|
|
52
|
-
// - `name[]? = a & b` introduces an optional named list; `?[]` is invalid
|
|
53
|
-
// - `list = a & b` introduces an anonymous list whose repeated item is the bundled shape `a & b`
|
|
54
|
-
// - `bundle? = a & b`, `frame? = a + b`, and `list? = a & b` introduce optional anonymous structural items
|
|
55
|
-
// - empty entries are ignored, but structural markers are preserved after normalization
|
|
56
|
-
// - aliases are presentation metadata: they do not add bytes, headers, fields, or wrappers,
|
|
57
|
-
// and they do not change the payload layout of the item they label
|
|
58
|
-
// - aliases are not stripped before on-chain local-key derivation; when a named structural item is keyed by
|
|
59
|
-
// bytes4(keccak256(bytes(rawSchemaInput))), any alias text present in that raw string is part of identity
|
|
60
|
-
// - off-chain presentation should use `alias:` when present, otherwise the schema item name when available
|
|
61
|
-
// - if sibling presentation names collide, off-chain tools should append zero-based suffixes in encounter order,
|
|
62
|
-
// e.g. `amount(...) + amount(...)` presents as `amount0` and `amount1`
|
|
63
|
-
// - when possible, off-chain tools should preserve item grouping for repeated schemas, e.g. `amount0.asset`,
|
|
64
|
-
// `amount0.meta`, `amount0.amount`, then `amount1.asset`, `amount1.meta`, `amount1.amount`
|
|
65
|
-
// - if fields within one presentation group collide, off-chain tools should suffix those field names in
|
|
66
|
-
// encounter order, e.g. `(uint amount, uint amount)` presents as `amount0` and `amount1`
|
|
67
|
-
// - optionality is schema metadata only; when an optional item is present, it uses the same encoding as the
|
|
68
|
-
// non-optional form, and when absent, no placeholder block is emitted
|
|
69
|
-
// - optional children inside a present bundle, list item, or `+&` frame tail may be absent while the
|
|
70
|
-
// parent structural block is still emitted; for example `& account(...)?` and `+& account(...)?`
|
|
71
|
-
// can encode as an empty BUNDLE or empty FRAME when the account child is absent
|
|
72
|
-
// - optional `?` is not allowed on flattened `+` frame members because frame fields have no child key or length;
|
|
73
|
-
// use `(fields...)?` as an optional frame item, make the whole frame optional, or use `+&` for
|
|
74
|
-
// optional block-stream tail items
|
|
75
|
-
// - grouping parentheses are not part of the DSL; parentheses are only used in block field lists
|
|
76
|
-
// and anonymous frame field groups
|
|
77
|
-
// - anonymous frame field groups in item position are promoted to anonymous frame items, so `(fields...)[]`
|
|
78
|
-
// means a list of anonymous frame items and `(fields...)?` means an optional anonymous frame item
|
|
79
|
-
// - anonymous frame field groups inside an existing frame are flattened fields, not nested frame items, and
|
|
80
|
-
// cannot be appended with `+&`
|
|
81
|
-
// - `+` binds tighter than `&`, so `a & b + c` normalizes as `a & (b + c)`
|
|
82
|
-
// - `+&` binds like `+`, so `a & b +& c` normalizes as `a & (b +& c)`
|
|
83
|
-
// - if `&` appears, the result remains a bundle even when only one non-empty child remains
|
|
84
|
-
// - if `+` appears, the result remains a frame even when only one non-empty child remains
|
|
85
|
-
// - if `+&` appears, the result remains a frame even when only one non-empty child remains
|
|
86
|
-
// - after ignoring empty entries, repeated adjacent separators collapse while preserving bundle/frame/list shape
|
|
87
|
-
// - bundled blocks preserve member order, so `a & b` differs from `b & a`
|
|
88
|
-
// - a bundle block's self payload is an embedded normal block stream of its bundled members
|
|
89
|
-
// - bundled members keep their ordinary block encoding, so dynamic blocks are allowed inside bundles
|
|
90
|
-
// - a list block's self payload is an embedded normal block stream representing the repeated items
|
|
91
|
-
// - a frame block's self payload is the concatenated payload fields of its framed members
|
|
92
|
-
// - framed members do not keep their ordinary block headers; the emitted schema defines the frame layout
|
|
93
|
-
// - framed members must be fixed-layout block forms because frame payloads contain no child lengths or block keys
|
|
94
|
-
// - anonymous frame field groups must also be fixed-layout and contribute only their fields, in order
|
|
95
|
-
// - `+&` members keep their ordinary block encoding inside the frame payload, so dynamic blocks are allowed there
|
|
96
|
-
// - `+&` starts a block-stream tail inside the frame; fixed-layout `+` members may not follow it
|
|
97
|
-
// - frames may be bundled like ordinary block items, but bundles/lists cannot be framed
|
|
98
|
-
// - prime blocks of the same type should be grouped together so the prime run is contiguous
|
|
99
|
-
// - primary / driving blocks should be the prime item; auxiliary batch-wide blocks should follow
|
|
100
|
-
// as global `;` siblings
|
|
101
|
-
// - `route(<fields...>)`, `item(<fields...>)`, `evm(<fields...>)`, `query(<fields...>)`,
|
|
102
|
-
// and `response(<fields...>)` are reserved extensible schema forms whose keys are always
|
|
103
|
-
// `Keys.Route`, `Keys.Item`, `Keys.Evm`, `Keys.Query`, and `Keys.Response` respectively
|
|
104
|
-
// - these extensible forms work like dynamic `bytes` blocks: they may carry arbitrary
|
|
105
|
-
// payload bytes while keeping one fixed key per semantic block type
|
|
106
|
-
// - prefer `frame = ...`, `(fields...)`, and `+&` tails over `route(...)` and `item(...)` when the payload
|
|
107
|
-
// can be described by the schema DSL; frames give off-chain tools typed layouts and better generated APIs
|
|
108
|
-
// - `evm(<fields...>)` differs from bundle/list payloads: its bytes are not an embedded block stream
|
|
109
|
-
// - `evm(uint foo, uint bar)` is a schema declaration only; on-chain the block key is still `Keys.Evm`
|
|
110
|
-
// and the payload can be decoded from `bytes data` using the local runtime's native decoder
|
|
111
|
-
// - on EVM, `evm(bool flag)` occupies one full 32-byte ABI word, exactly like `abi.encode(flag)`
|
|
112
|
-
// - anonymous `&` compiles to a `Keys.Bundle` block whose self payload is the bundled member block stream
|
|
113
|
-
// - anonymous `[]` compiles to a `Keys.List` block whose self payload is the repeated item block stream
|
|
114
|
-
// - anonymous `+` compiles to a `Keys.Frame` block whose self payload is the framed member payload fields
|
|
115
|
-
// - anonymous `+&` compiles to a `Keys.Frame` block whose self payload is fixed framed fields
|
|
116
|
-
// followed by an embedded normal block-stream tail
|
|
117
|
-
// - bare `(fields...)` compiles to a `Keys.Frame` block whose self payload is those fields
|
|
118
|
-
// - named lists, bundles, and frames use bytes4(keccak256(bytes(rawSchemaInput))) as their block key
|
|
119
|
-
// - named structural keys are custom/local identifiers, not global protocol keys; formatting is part of identity
|
|
120
|
-
// - `payment: frame = amount(...) +& fee(...)` means an anonymous frame whose runtime key is still `Keys.Frame`,
|
|
121
|
-
// with `payment` as its off-chain presentation name
|
|
122
|
-
// - `quote: payment = amount(...) + fee(...)` means a named frame with presentation alias `quote`;
|
|
123
|
-
// its local runtime key is derived from the full raw schema string including `quote:`
|
|
124
|
-
// - `frame = debit: amount(...) + credit: amount(...)` means the two flattened amount groups should be
|
|
125
|
-
// presented off-chain as `debit` and `credit`, while encoding remains the same as without aliases
|
|
126
|
-
// - `frame = amount(...) + amount(...)` has the same encoding as the aliased form above, but off-chain tools
|
|
127
|
-
// should present the groups as `amount0` and `amount1`
|
|
128
|
-
// - `asset(...)[]` means a list whose repeated item is the block `asset(...)`
|
|
129
|
-
// - `account(...)?` means an optional account block
|
|
130
|
-
// - `steps[] = asset(...) & account(...)` means a named list whose repeated item is the bundle
|
|
131
|
-
// `asset(...) & account(...)`
|
|
132
|
-
// - `steps[]? = asset(...) & account(...)` means that named list may be absent
|
|
133
|
-
// - `memo? = evm(bytes data)` means an optional named local item whose payload, when present, is EVM-encoded
|
|
134
|
-
// - `payment = amount(...) + fee(...)` means a named frame whose payload is
|
|
135
|
-
// `asset | meta | amount | fee` and whose on-chain key is derived from that raw schema string
|
|
136
|
-
// - `payment = amount(...) + (uint fee, uint rate)` means a named frame whose payload is
|
|
137
|
-
// `asset | meta | amount | fee | rate`, without inventing a child block name for the extra fields
|
|
138
|
-
// - `payment = (uint fee, uint rate)` means a named frame whose payload is `fee | rate`
|
|
139
|
-
// - `payment = amount(...) +& fee(...)` means a named frame whose payload is
|
|
140
|
-
// `asset | meta | amount | [fee key | fee len | fee amount]`
|
|
141
|
-
// - `payment = amount(...) +& fee(...)?` means a named frame with an amount prefix and optional fee block tail
|
|
142
|
-
// - `payment = amount(...) +& list? = fee(...)` means a named frame with an amount prefix and
|
|
143
|
-
// an optional anonymous list block tail
|
|
144
|
-
// - `payment = amount(...)? + fee(...)` is invalid because `amount(...)` would be an optional flattened frame member
|
|
145
|
-
// - `(uint fee)` means an anonymous frame with one `fee` field
|
|
146
|
-
// - `(uint fee)[]` means a list of anonymous frames whose repeated item has one `fee` field
|
|
147
|
-
// - `(uint fee)?` means an optional anonymous frame with one `fee` field
|
|
148
|
-
// - `amount(...) & (uint fee)` means a bundle containing an amount block and an anonymous fee frame
|
|
149
|
-
// - `amount(...) +& (uint fee)` is invalid because `+&` appends existing block-stream items, not field groups
|
|
150
|
-
// - `amount(...) & fee(...) + account(...)` means `amount(...) & (fee(...) + account(...))`;
|
|
151
|
-
// it compiles to a bundle containing one amount block followed by one frame block
|
|
152
|
-
// - `amount(...) & fee(...) +& account(...)` means `amount(...) & (fee(...) +& account(...))`;
|
|
153
|
-
// it compiles to a bundle containing one amount block followed by one frame block with an account block tail
|
|
154
|
-
// - `bundle = account(...) & evm(bytes routeData)` means an anonymous child bundle with those bundled members
|
|
155
|
-
// - `bundle? = account(...) & auth(...)` means that anonymous bundle may be absent
|
|
156
|
-
// - `frame = amount(...) + fee(...)` means an anonymous child frame with those framed payload fields
|
|
157
|
-
// - `frame? = amount(...) + fee(...)` means that anonymous frame may be absent
|
|
158
|
-
// - `frame = amount(...) +& fee(...)` means an anonymous child frame with amount fields plus a fee block tail
|
|
159
|
-
// - `list = asset(...) & account(...)` means an anonymous child list whose repeated item is the
|
|
160
|
-
// bundle `asset(...) & account(...)`
|
|
161
|
-
// - `list? = fee(...)` means that anonymous list may be absent
|
|
162
|
-
// - `"amount(...) &"` and `"& amount(...)"` both normalize to a bundle containing one `amount(...)` child
|
|
163
|
-
// - `"& account(...)?"` normalizes to a bundle containing one optional `account(...)` child
|
|
164
|
-
// - `"amount(...) +"` and `"+ amount(...)"` both normalize to a frame containing one `amount(...)` payload
|
|
165
|
-
// - `"amount(...) +&"` and `"+& amount(...)"` both normalize to a frame containing one `amount(...)` block
|
|
166
|
-
// - `"+& account(...)?"` normalizes to a frame containing an optional `account(...)` block-stream tail
|
|
167
|
-
// - `"amount(...)?"` normalizes to an optional amount block; `"amount(...)?[]"` is invalid
|
|
168
|
-
// - canonical blocks are `amount(...)` for request amounts, `balance(...)` for state balances,
|
|
169
|
-
// `allocation(...)` for host-scoped provision requests, `allowance(...)` for host-scoped caps,
|
|
170
|
-
// `custody(...)` for host-scoped state,
|
|
171
|
-
// `minimum(...)` for result floors, `maximum(...)` for spend ceilings, and `quantity(...)`
|
|
172
|
-
// for plain scalar amounts
|
|
173
|
-
// - `auth(uint cid, uint deadline, bytes proof)` is a proof-separator block and must be emitted last
|
|
9
|
+
// Schema:
|
|
10
|
+
// - blocks are written as `#name { fields }`
|
|
11
|
+
// - a block without braces has no payload, e.g. `#unit`
|
|
12
|
+
// - commas separate siblings at every level
|
|
13
|
+
// - braces define parent-child boundaries
|
|
14
|
+
// - top-level item 0 is the prime item; later top-level items are globals
|
|
15
|
+
// - prime items may repeat at top level for batching
|
|
16
|
+
// - `maybe #x { ... }` marks an optional block item
|
|
17
|
+
// - `many #x { ... }` emits one generic list block containing repeated `#x` items
|
|
18
|
+
// - fixed fields are packed in declaration order
|
|
19
|
+
// - blocks have fixed fields followed by a dynamic child-block tail
|
|
20
|
+
// - child block tails are embedded directly, without an extra stream wrapper
|
|
21
|
+
// - `#bytes` is a reserved child block that stores raw bytes and has no body
|
|
22
|
+
// - generic `#data` uses the stable key derived from `#data`
|
|
23
|
+
// - generic lists use the stable key derived from `#list`
|
|
24
|
+
// - keys are derived from block names, e.g. bytes4(keccak256("#amount"))
|
|
25
|
+
// - see `docs/Schema.md` for the full working spec
|
|
174
26
|
//
|
|
175
27
|
// Pipeline state:
|
|
176
28
|
// - `balance(...)` and `custody(...)` are live, linear state in the active command pipeline
|
|
@@ -184,57 +36,52 @@ pragma solidity ^0.8.33;
|
|
|
184
36
|
//
|
|
185
37
|
// Signed blocks:
|
|
186
38
|
// - an authenticated input segment ends with one trailing AUTH block
|
|
187
|
-
// - auth is typically grouped with the signed payload in one bundle, with AUTH as the final member
|
|
188
39
|
// - only the final AUTH is treated specially; earlier AUTH blocks remain ordinary signed bytes
|
|
189
40
|
// - the signed slice runs from the segment start through the AUTH head, excluding only AUTH proof bytes
|
|
190
41
|
// - `cid` binds the signature to one command; `deadline` acts as expiry and nonce
|
|
191
42
|
// - current helpers assume proof layout `[bytes20 signer][bytes65 sig]`
|
|
192
43
|
|
|
193
44
|
/// @title Schemas
|
|
194
|
-
/// @notice Human-readable
|
|
195
|
-
/// These strings
|
|
196
|
-
///
|
|
45
|
+
/// @notice Human-readable schema string constants for each block type.
|
|
46
|
+
/// These strings describe payload layout for discovery events and docs; block
|
|
47
|
+
/// keys are derived only from block names.
|
|
197
48
|
library Schemas {
|
|
198
|
-
string constant
|
|
199
|
-
string constant Node = "node
|
|
200
|
-
string constant Account = "account
|
|
201
|
-
string constant Asset = "asset
|
|
202
|
-
string constant Balance = "balance
|
|
203
|
-
string constant Amount = "amount
|
|
204
|
-
string constant Minimum = "minimum
|
|
205
|
-
string constant Maximum = "maximum
|
|
206
|
-
string constant Custody = "custody
|
|
207
|
-
string constant Payout = "payout
|
|
208
|
-
string constant Allocation = "allocation
|
|
209
|
-
string constant Allowance = "allowance
|
|
210
|
-
string constant Transaction = "transaction
|
|
211
|
-
string constant Call = "call
|
|
212
|
-
string constant Step = "step
|
|
213
|
-
string constant
|
|
214
|
-
string constant
|
|
215
|
-
string constant Fee = "fee
|
|
216
|
-
string constant
|
|
217
|
-
string constant
|
|
218
|
-
string constant
|
|
219
|
-
string constant
|
|
220
|
-
string constant
|
|
221
|
-
string constant Evm = "evm(bytes data)";
|
|
222
|
-
string constant Query = "query(bytes data)";
|
|
223
|
-
string constant Response = "response(bytes data)";
|
|
224
|
-
string constant Break = "break()";
|
|
49
|
+
string constant Unit = "#unit";
|
|
50
|
+
string constant Node = "#node { uint id }";
|
|
51
|
+
string constant Account = "#account { bytes32 account }";
|
|
52
|
+
string constant Asset = "#asset { bytes32 asset, bytes32 meta }";
|
|
53
|
+
string constant Balance = "#balance { bytes32 asset, bytes32 meta, uint amount }";
|
|
54
|
+
string constant Amount = "#amount { bytes32 asset, bytes32 meta, uint amount }";
|
|
55
|
+
string constant Minimum = "#minimum { bytes32 asset, bytes32 meta, uint amount }";
|
|
56
|
+
string constant Maximum = "#maximum { bytes32 asset, bytes32 meta, uint amount }";
|
|
57
|
+
string constant Custody = "#custody { uint host, bytes32 asset, bytes32 meta, uint amount }";
|
|
58
|
+
string constant Payout = "#payout { bytes32 account, bytes32 asset, bytes32 meta, uint amount }";
|
|
59
|
+
string constant Allocation = "#allocation { uint host, bytes32 asset, bytes32 meta, uint amount }";
|
|
60
|
+
string constant Allowance = "#allowance { uint host, bytes32 asset, bytes32 meta, uint amount }";
|
|
61
|
+
string constant Transaction = "#transaction { bytes32 from, bytes32 to, bytes32 asset, bytes32 meta, uint amount }";
|
|
62
|
+
string constant Call = "#call { uint target, uint value, #bytes as payload }";
|
|
63
|
+
string constant Step = "#step { uint target, uint value, #bytes as request }";
|
|
64
|
+
string constant Context = "#context { bytes32 account, uint value, #bytes as state, #bytes as request }";
|
|
65
|
+
string constant Bounty = "#bounty { uint amount, bytes32 relayer }";
|
|
66
|
+
string constant Fee = "#fee { uint amount }";
|
|
67
|
+
string constant Auth = "#auth { uint cid, uint deadline, #bytes as proof }";
|
|
68
|
+
string constant Bytes = "#bytes";
|
|
69
|
+
string constant Data = "#data";
|
|
70
|
+
string constant List = "#list";
|
|
71
|
+
string constant Evm = "#evm";
|
|
225
72
|
}
|
|
226
73
|
|
|
227
74
|
/// @title Forms
|
|
228
75
|
/// @notice Reusable structural block schemas for core tuple shapes.
|
|
229
76
|
/// These describe payload form without assigning command or query semantics.
|
|
230
77
|
library Forms {
|
|
231
|
-
string constant Status = "status
|
|
232
|
-
string constant AssetAmount = "assetAmount
|
|
233
|
-
string constant AccountAsset = "accountAsset
|
|
234
|
-
string constant AccountAmount = "accountAmount
|
|
235
|
-
string constant HostAmount = "hostAmount
|
|
236
|
-
string constant HostAccountAsset = "hostAccountAsset
|
|
237
|
-
string constant HostAccountAmount = "hostAccountAmount
|
|
78
|
+
string constant Status = "#status { bool ok }";
|
|
79
|
+
string constant AssetAmount = "#assetAmount { bytes32 asset, bytes32 meta, uint amount }";
|
|
80
|
+
string constant AccountAsset = "#accountAsset { bytes32 account, bytes32 asset, bytes32 meta }";
|
|
81
|
+
string constant AccountAmount = "#accountAmount { bytes32 account, bytes32 asset, bytes32 meta, uint amount }";
|
|
82
|
+
string constant HostAmount = "#hostAmount { uint host, bytes32 asset, bytes32 meta, uint amount }";
|
|
83
|
+
string constant HostAccountAsset = "#hostAccountAsset { uint host, bytes32 account, bytes32 asset, bytes32 meta }";
|
|
84
|
+
string constant HostAccountAmount = "#hostAccountAmount { uint host, bytes32 account, bytes32 asset, bytes32 meta, uint amount }";
|
|
238
85
|
}
|
|
239
86
|
|
|
240
87
|
/// @title Sizes
|
|
@@ -256,14 +103,14 @@ library Sizes {
|
|
|
256
103
|
uint constant B160 = Header + 5 * Word;
|
|
257
104
|
/// @dev AUTH proof segment only: 20-byte signer + 65-byte signature = 85 bytes
|
|
258
105
|
uint constant Proof = 85;
|
|
259
|
-
/// @dev AUTH block: 8 header + 32 cid + 32 deadline + 85 proof =
|
|
260
|
-
uint constant Auth = B64 + Proof;
|
|
106
|
+
/// @dev AUTH block: 8 header + 32 cid + 32 deadline + nested BYTES block with 85-byte proof = 165 bytes
|
|
107
|
+
uint constant Auth = B64 + Header + Proof;
|
|
108
|
+
/// @dev STATUS block: 8 header + 1 bool byte = 9 bytes
|
|
109
|
+
uint constant Status = Header + 1;
|
|
261
110
|
/// @dev AMOUNT block: 8 header + 32 asset + 32 meta + 32 amount = 104 bytes
|
|
262
111
|
uint constant Amount = B96;
|
|
263
112
|
/// @dev BALANCE block: 8 header + 32 asset + 32 meta + 32 amount = 104 bytes
|
|
264
113
|
uint constant Balance = B96;
|
|
265
|
-
/// @dev BOUNDS block: 8 header + 32 min + 32 max = 72 bytes
|
|
266
|
-
uint constant Bounds = B64;
|
|
267
114
|
/// @dev FEE block: 8 header + 32 amount = 40 bytes
|
|
268
115
|
uint constant Fee = B32;
|
|
269
116
|
/// @dev BOUNTY block: 8 header + 32 amount + 32 relayer = 72 bytes
|