sgx-node-registry is a CosmWasm smart contract on Secret Network that maintains an on-chain registry of SGX node operators. Each operator can register one or more SGX nodes with their network endpoint and metadata. Other contracts and off-chain clients can query this registry to discover available SGX nodes.
Secret Network uses SGX (Intel Software Guard Extensions) nodes to execute secret contracts inside a Trusted Execution Environment. Non-SGX nodes and clients need to know which SGX nodes are available and how to reach them. This contract provides a permissionless, on-chain source of truth for that information.
| Field | Type | Description |
|---|---|---|
operator |
Addr |
The wallet that registered the node (owner) |
identity |
String |
Unique identifier for this node (e.g. enclave pubkey, moniker) |
grpc_endpoint |
String |
The gRPC address clients connect to (e.g. 1.2.3.4:9191) |
description |
Option<String> |
Optional human-readable description |
registered_at |
u64 |
Block timestamp (seconds) when the node was registered |
- Multiple nodes per operator — one wallet can register any number of nodes, each with a distinct
identity - Globally unique identity — two operators cannot register the same
identity - Ownership enforced — only the wallet that registered a node can update or remove it
| Network | Address |
|---|---|
| pulsar-3 (testnet) | secret1zz88n0zafj4vruqusktd4ute3cuuk08p0rkp4m |
| secret-4 (mainnet) | secret1h7xzl06j47vvp4ajwfge6la7gu8anxvpqt326k |
Prerequisites: Rust, cargo, wasm32-unknown-unknown target.
# Install wasm target (once)
rustup target add wasm32-unknown-unknown
# Run unit tests
cargo test
# Build optimized wasm + compress
make build
# Output: contract.wasm.gz (ready to store on-chain)secretcli tx compute store contract.wasm.gz \
--from <YOUR_KEY> \
--gas 1100000 \
-yQuery the tx to get the code ID:
secretcli q compute tx <TX_HASH>The instantiation message is empty. The sender becomes the contract owner (admin).
secretcli tx compute instantiate <CODE_ID> '{}' \
--from <YOUR_KEY> \
--label "sgx-node-registry" \
-yQuery the tx to get the contract address:
secretcli q compute tx <TX_HASH>
# Look for: "contract_address": "secret1..."Register a new SGX node. The identity must be unique across all operators.
secretcli tx compute execute <CONTRACT_ADDR> \
'{"register_node":{
"identity": "<UNIQUE_NODE_ID>",
"grpc_endpoint": "<IP:PORT>",
"description": "<OPTIONAL_DESCRIPTION>"
}}' \
--from <YOUR_KEY> -yExample:
secretcli tx compute execute secret1zz88n0zafj4vruqusktd4ute3cuuk08p0rkp4m \
'{"register_node":{"identity":"my-sgx-node-1","grpc_endpoint":"1.2.3.4:9191","description":"Main SGX node"}}' \
--from mykey -yErrors:
Node identity '...' is already registered— identity already taken by any operator
Update the grpc_endpoint and/or description of an existing node. Only the node's owner can call this.
secretcli tx compute execute <CONTRACT_ADDR> \
'{"update_node":{
"identity": "<NODE_ID>",
"grpc_endpoint": "<NEW_IP:PORT>",
"description": "<NEW_DESCRIPTION>"
}}' \
--from <YOUR_KEY> -yAll fields except identity are optional — omit any you don't want to change.
Example — update endpoint only:
secretcli tx compute execute secret1zz88n0zafj4vruqusktd4ute3cuuk08p0rkp4m \
'{"update_node":{"identity":"my-sgx-node-1","grpc_endpoint":"5.6.7.8:9191"}}' \
--from mykey -yErrors:
Node '...' not registered— identity does not existUnauthorized: you do not own this node— caller is not the node's owner
Permanently remove a node from the registry. Only the node's owner can call this.
secretcli tx compute execute <CONTRACT_ADDR> \
'{"remove_node":{"identity": "<NODE_ID>"}}' \
--from <YOUR_KEY> -yExample:
secretcli tx compute execute secret1zz88n0zafj4vruqusktd4ute3cuuk08p0rkp4m \
'{"remove_node":{"identity":"my-sgx-node-1"}}' \
--from mykey -yErrors:
Node '...' not registered— identity does not existUnauthorized: you do not own this node— caller is not the node's owner
Fetch a single node by its identity.
secretcli q compute query <CONTRACT_ADDR> \
'{"get_node":{"identity":"<NODE_ID>"}}'Response:
{
"node": {
"operator": "secret1...",
"identity": "my-sgx-node-1",
"grpc_endpoint": "1.2.3.4:9191",
"description": "Main SGX node",
"registered_at": 1780664239
}
}Returns "node": null if the identity is not found.
List all registered nodes globally, paginated.
secretcli q compute query <CONTRACT_ADDR> \
'{"list_nodes":{}}'
# With pagination:
secretcli q compute query <CONTRACT_ADDR> \
'{"list_nodes":{"start_after":"<LAST_IDENTITY>","limit":10}}'Default limit: 20. Maximum limit: 50.
Response:
{
"nodes": [
{
"operator": "secret1...",
"identity": "node-1",
"grpc_endpoint": "1.2.3.4:9191",
"description": null,
"registered_at": 1780664239
},
{
"operator": "secret1...",
"identity": "node-2",
"grpc_endpoint": "2.2.2.2:9191",
"description": "Backup node",
"registered_at": 1780664244
}
]
}List all nodes registered by a specific operator wallet, paginated.
secretcli q compute query <CONTRACT_ADDR> \
'{"list_nodes_by_operator":{"operator":"<WALLET_ADDRESS>"}}'Example:
secretcli q compute query secret1zz88n0zafj4vruqusktd4ute3cuuk08p0rkp4m \
'{"list_nodes_by_operator":{"operator":"secret1f2jrcqsx7glyta39c6tum2lhk5kh2a0ty6r9ms"}}'Response: same format as list_nodes.