On-chain reference
Live deployment (Base mainnet, chain id 8453)
Section titled “Live deployment (Base mainnet, chain id 8453)”| Contract | Address |
|---|---|
Reference cluster (ClusterDiamond) | 0xA46273adC86c772C7D8daE896a5fbfdDA2B6ccFA |
| ClusterDiamondFactory | 0xf6E85fD138E3208d3AAE63ce4E2A33f20e82b9fb |
| ClusterMemberFactory | 0xFf9f438EFdAa197f4ae59D1d711C4f09640b8417 |
| IndexerRegistry | 0xbC003686943fB957100E517D3CEf66c52B5CDdBf |
| AttestFacet | 0x10532164ca3BdaCf1dAd13Fb534262DEc5aAA9AA |
| MessageFacet | 0x0F67cd8c1D8A2F71d2bb8091B2eb166E6b6bB564 |
| NetworkFacet | 0x6AB2b7D506c85C7A9eA22f2ECcE0cc9191006159 |
| DstackFacet (Path A build) | 0xC631793fB80d3Bc18435aAD3788B8b31B44bE255 |
| ClusterMember impl (Path A upgrade target) | 0xBe579F0B8A971d0F8b083Eb3E8bB241985A3C5C4 |
| EntryPoint v0.7 (canonical) | 0x0000000071727De22E5E9d8BAf0edAc6f37da032 |
The canonical machine-readable copy lives in the repo at
contracts/script/deployments/8453.json.
Reading cluster state
Section titled “Reading cluster state”Everything a node or operator needs is a view call away:
CLUSTER=0xA46273adC86c772C7D8daE896a5fbfdDA2B6ccFARPC=https://mainnet.base.org
cast call $CLUSTER 'memberCount()(uint256)' --rpc-url $RPCcast call $CLUSTER 'listMembers()(bytes32[])' --rpc-url $RPCcast call $CLUSTER 'memberIdOf(address)(bytes32)' <app_id> --rpc-url $RPCcast call $CLUSTER 'xPubKeyOf(bytes32)(bytes32)' <memberId> --rpc-url $RPCcast call $CLUSTER 'wgPubKeyOf(bytes32)(bytes32)' <memberId> --rpc-url $RPCcast call $CLUSTER 'meshIpOf(bytes32)(uint32)' <memberId> --rpc-url $RPCcast call $CLUSTER 'cskCommitment()(bytes32)' --rpc-url $RPCSurface summary
Section titled “Surface summary”AttestFacet — membership registry
Section titled “AttestFacet — membership registry”memberOf(address)/memberById(bytes32)→ member record (attestor id, member contract, x25519 pubkey, wg pubkey, registered-at)listMembers(),memberCount(),memberIdOf(address)meshIpOf(bytes32)— deterministic mesh IP inside the cluster CIDRcskCommitment()/setCskCommitment(bytes32)— one-shot, originator-only- Member ids:
keccak256(abi.encode(cluster, memberContract, keccak256(attestorId)))
MessageFacet — encrypted messaging
Section titled “MessageFacet — encrypted messaging”send(bytes32 recipientMemberId, bytes32 envelopeId, bytes ciphertext)— member-gated; reverts on duplicate(recipient, envelopeId)event MessageSent(bytes32 indexed sender, bytes32 indexed recipient, bytes32 indexed envelopeId, bytes ciphertext)— the transport
NetworkFacet — wireguard signalling
Section titled “NetworkFacet — wireguard signalling”publishWgKey(bytes32)and the correspondingWgKeyPublishedevent
DstackFacet — the dstack attestor
Section titled “DstackFacet — the dstack attestor”dstack_register(proof, memberContract, xPubKey, wgPubKey)— verifies the dstack KMS signature chain, admits the member- dstack
IAppAuth+IAppAuthBasicManagement:isAppAllowed,addComposeHash,addAllowedAppId, device and KMS-root allowlists — all cluster-owner-gated. This is what makes the cluster double as the KMS boot-authorization authority for its nodes.
ClusterMember — the per-node account
Section titled “ClusterMember — the per-node account”- dstack-style app proxy + EIP-4337 account on one address
execute(target, value, data)— owner-signed; the wrapper every sidecar operation uses- Bootstrap validation: the registration UserOperation is validated against the
signer recovered from its own attestation proof; registration installs that
signer as
owner cluster()— the diamond this member is bound to
IndexerRegistry
Section titled “IndexerRegistry”current()→(endpoint, codeId, pubKey, updatedAt)setIndexer(record)— owner-only