Build, Deploy & Register Enclave
The enclave is the core component that fetches prices and signs them. You can use Rust, Node.js, or Python - pick based on your preference.
Build the Enclave Image
The project uses Nix for reproducible builds. This ensures the code running in the cloud matches what you built locally. The nix.sh helper runs Nix inside Docker, so you don't need Nix installed.
From the repo root, run the build for your chosen language and architecture:
# Rust (ARM64 — for c6g/c7g instances)
./nix.sh build-rust-arm64
# Node.js (ARM64)
./nix.sh build-node-arm64
# Python (ARM64)
./nix.sh build-python-arm64
For AMD64 instances (c6a.xlarge), use the corresponding -amd64 variants.
Load the resulting tarball into Docker:
docker load < ./rust-arm64-image.tar.gz
Push to a Registry
Tag and push the image to Docker Hub or another registry:
docker tag sui-price-oracle:rust-reproducible-arm64 <YOUR_REGISTRY>/sui-price-oracle:rust-reproducible-arm64
docker push <YOUR_REGISTRY>/sui-price-oracle:rust-reproducible-arm64
Update docker-compose.yml
Get the image digest:
docker inspect --format='{{index .RepoDigests 0}}' <YOUR_REGISTRY>/sui-price-oracle:rust-reproducible-arm64
Update docker-compose.yml to use the digest instead of a tag:
services:
oracle:
image: <YOUR_REGISTRY>/sui-price-oracle@sha256:abc123...
Using the SHA256 digest pins your enclave to an exact image version, which is recommended for production. However, mutable tags like :latest can also be used if you prefer flexibility over strict version locking. PCR16 is generated based on the docker-compose file contents, so as long as the tag name doesn't change, PCR16 remains the same - even if the underlying image is updated.
Deploy to Oyster
Deploy the enclave using the Oyster CLI:
# Export the private key of the wallet with Sui and USDC used for deployments
export PRIVATE_KEY="suiprivkey......."
# Deploy in ARM64
oyster-cvm deploy \
--wallet-private-key $PRIVATE_KEY \
--docker-compose ./enclave_rust/docker-compose.yml \
--instance-type c6g.xlarge \
--duration-in-minutes 60 \
--deployment sui
# Deploy in AMD64
oyster-cvm deploy \
--wallet-private-key $PRIVATE_KEY \
--docker-compose ./enclave_rust/docker-compose.yml \
--instance-type c6a.xlarge \
--duration-in-minutes 60 \
--deployment sui \
--arch amd64
Save the PUBLIC_IP from the output:
export PUBLIC_IP=<ip-address>
Verify the Enclave
Query the enclave to verify it's running:
# Get attestation document
curl http://$PUBLIC_IP:1301/attestation/hex
# Verify PCR values
oyster-cvm verify --enclave-ip $PUBLIC_IP
Record the PCR values: PCR0, PCR1, PCR2, and PCR16.
Register in the Enclave Registry
The enclave registry is a shared, application-independent contract already deployed on-chain. Use the following registry addresses:
| Network | REGISTRY_PACKAGE_ID | REGISTRY_ID |
|---|---|---|
| Mainnet | 0x8df76b79118ffad2bacb55705c84474802ddb3d62199b98db720c5088e161ab8 | 0xf67a9392da1749e8442d71eb6139a9dc1c199b88ef3da49385eeda175246d9d0 |
| Testnet | 0x05cd5a306375c49727fc2f1e667df8bcc1f5b52ad07e850074d330afda932761 | 0x7ebc3f9bc7a0cf0820d241ad767036483b885bbd62636fb9446bb0d99d2ed091 |
Export the registry addresses for your target network:
export REGISTRY_PACKAGE_ID=0x...
export REGISTRY_ID=0x...
Register the enclave (from the repository root):
Mainnet:
oyster-cvm register \
--enclave-ip $PUBLIC_IP \
--wallet-priv-key $PRIVATE_KEY
Testnet:
sh contracts/script/register_enclave.sh \
$REGISTRY_PACKAGE_ID \
$REGISTRY_ID \
$PUBLIC_IP
This fetches the attestation document from the enclave, verifies it on-chain, and stores the public key along with its PCR values in the registry. Once registered, any application can look up this enclave's PCRs.