feat(wit): add nexum:value-flow types package v0.1.0#247
Conversation
b153193 to
0f0ed06
Compare
0f0ed06 to
5c11b93
Compare
5c11b93 to
74e5e9c
Compare
74e5e9c to
3ce6d08
Compare
3ce6d08 to
6b6d8d6
Compare
6b6d8d6 to
b07179d
Compare
924d20c to
fbcf754
Compare
fbcf754 to
f7de776
Compare
f7de776 to
b80c646
Compare
b80c646 to
1f82918
Compare
1f82918 to
54e8a9a
Compare
54e8a9a to
bd20a66
Compare
bd20a66 to
ea71759
Compare
ea71759 to
371ce2c
Compare
042fc45 to
b382ce3
Compare
b382ce3 to
a094a83
Compare
a094a83 to
ca289a0
Compare
ca289a0 to
94b8bc9
Compare
94b8bc9 to
84afc84
Compare
84afc84 to
043b770
Compare
043b770 to
0c264f1
Compare
0c264f1 to
0786338
Compare
0786338 to
cefe6e8
Compare
lgahdl
left a comment
There was a problem hiding this comment.
Clean package and good hygiene gate. Three items below.
| /// `native-token` wraps `settlement` because a chain's own gas token is | ||
| /// the one asset that exists on every settlement domain. Each token | ||
| /// tuple carries raw big-endian bytes: a 20-byte address, and for the | ||
| /// NFT cases a token id of arbitrary width. | ||
| variant asset { | ||
| /// The settlement domain's own gas token (ETH, BZZ, ...). | ||
| native-token(settlement), |
There was a problem hiding this comment.
Two issues with native-token(settlement):
-
The BZZ example is wrong. BZZ is an ERC-20 on Ethereum/Gnosis Chain, not the native gas token of any chain. Correct examples: ETH, xDAI, MATIC, BNB.
-
native-token(offchain(...))is a structurally valid but semantically empty combination. No real domain has an off-chain-settled native gas token; an analyser receiving this case has no oracle, no AMM pool, and no contract address to price against. The rationale for wrappingsettlementis that each EVM chain has its own native token — that maps only tosettlement::evm-chain. Either restrictnative-tokento hold a bareu64(consistent with ERC cases), or add a comment explicitly forbidding theoffchainarm and stating what consumers must do if they see it.
| erc20(tuple<u64, list<u8>>), | ||
| /// An ERC-721 NFT: (chain id, 20-byte contract address, token id). | ||
| erc721(tuple<u64, list<u8>, list<u8>>), | ||
| /// An ERC-1155 token: (chain id, 20-byte contract address, token id). | ||
| erc1155(tuple<u64, list<u8>, list<u8>>), |
There was a problem hiding this comment.
The ERC cases use anonymous positional tuples for a package described as the "hardest-freezing contract." The second position (address) is already opaque; at a frozen interface, adding a third field means a semver bump even for optional metadata. Named records would make positions self-documenting and leave room for a non-breaking extension:
record evm-token { chain-id: u64, address: list<u8> }
record evm-nft { chain-id: u64, address: list<u8>, token-id: list<u8> }
erc20(evm-token),
erc721(evm-nft),
erc1155(evm-nft),
This is easier pre-freeze than post.
| /// field holds the pair (a header's `gives` vs `wants`), not here. | ||
| record asset-amount { | ||
| asset: asset, | ||
| amount: list<u8>, |
There was a problem hiding this comment.
The amount field is missing its doc comment — the encoding convention (big-endian, empty = zero, no negative) is documented on the record but not on the field itself. WIT tooling renders field docs separately.
| amount: list<u8>, | |
| /// Big-endian unsigned integer, most-significant byte first; empty encodes zero. | |
| amount: list<u8>, |
cefe6e8 to
31f524f
Compare
1795182 to
f7f2f3a
Compare
a8b7932 to
e04f395
Compare
e04f395 to
c0ffbc5
Compare
acaa0f8 to
4e2ce66
Compare
c0ffbc5 to
1e89474
Compare
Add the egress-neutral value-flow vocabulary at 0.1.0: the settlement domain (evm-chain or offchain), the asset variant (native-token, erc20, erc721, erc1155, service, offchain), the service and offchain descriptors, and the big-endian asset-amount. The package is dependency-free so it can outlive any interface built on it. Every identifier is vetted against WIT keywords, in-flight component-model proposals, and the nine binding-target reserved-word lists, preferring a two-word kebab id wherever a single word is a keyword anywhere: native-token over native (a Java modifier), offchain over external (a Dart keyword), value-flow over value (value-imports is circling that word). A wasmtime bindgen smoke, compiled under test in the host crate through a throwaway world, names every generated type and field by its plain Rust spelling so a keyword collision surfaces as an escaped identifier and fails the build rather than a downstream binding.
What
Adds the
nexum:value-flowWIT types package at 0.1.0, the shared,dependency-free vocabulary for value in motion (settlement, asset,
asset-amount) that intent headers, simulation balance diffs, and analyser
verdicts will all use to describe a spend the same way.
wit/nexum-value-flow/types.witdefining interfacetypeswith:settlement:evm-chain(u64)|offchain(string)service-desc:kind,summaryoffchain-desc:domain,summaryasset:native-token(settlement)|erc20/erc721/erc1155as(chain id, address[, id])tuples |service(service-desc)|offchain(offchain-desc)asset-amount:assetplus a big-endian unsigned-byte amountu64, no import ofnexum:host/types), per the zero-dependency foundation mandate.#[cfg(test)]wasmtime bindgen smoke incrates/nexum-runtime/src/bindings.rsthat imports the interface through athrowaway inline world and names every generated type, variant, and field
by its plain Rust spelling, enforcing the identifier-hygiene gate at
compile time.
Why
This is the platform's hardest-freezing contract: the vocabulary for where a
deal settles, what asset moves, and how much of it, shared by intent
headers, simulation balance diffs, and analyser verdict subjects so a spend
is written the same way everywhere. Identifier hygiene is a freeze gate:
every identifier is checked against WIT keywords (including in-flight
proposals) and against the reserved words of the nine binding-target
languages, so a two-word kebab id is preferred wherever a single word is a
keyword anywhere (
native-tokennotnative,offchainnotexternal).Getting this package right now, before anything binds to it, avoids
escaped identifiers surfacing later in generated bindings for the personas
the SDK exists to serve.
Testing
cargo test --workspace(covers the new bindgen smoke test)cargo fmt --all -- --checkcargo clippy --workspace --all-targets -- -D warningsRed-teamed with no blocker or major findings. The identifier-hygiene gate
was confirmed sensitive by injecting a Rust-keyword field name (
kindtotype), which forced anr#escape and failed compilation; the file wasthen restored to the exact committed state (
git diff HEADempty).AI Assistance
Claude (Opus) used for the implementation.
Closes #226