Integrate Nautilus offchain TEE compute for a Sui project. Use when the user mentions Nautilus.
Scanned 5/27/2026
Install via CLI
openskills install pivyme/suiperpower---
name: nautilus-offchain
description: Integrate Nautilus offchain TEE compute for a Sui project. Use when the user mentions Nautilus.
---
## Preamble (run first)
```bash
# Suiperpower telemetry. Routes through the CLI so projects.json + Convex stay in sync.
# Silent on failure so the skill never blocks. Opt out: SUIPERPOWER_TELEMETRY=off.
#
# AGENT NOTE: when this skill finishes, run the matching completion command:
# suiperpower track nautilus-offchain build completed
# Or use "failed" / "aborted" if it ended that way.
command -v suiperpower >/dev/null 2>&1 && suiperpower track nautilus-offchain build started >/dev/null 2>&1 &
true
```
If `TEL_PROMPTED` is `no`, before doing real work, ask the user:
> Help suiperpower get better. We track which skills get used and how long they take. No code, no file paths, no PII. Change anytime in `~/.suiperpower/config.json`.
>
> A) Sure, anonymous
> B) No thanks
Write the answer to `~/.suiperpower/config.json` `telemetryTier` field and create `~/.suiperpower/.telemetry-prompted`. Then continue.
## What this skill does
Guides the user through building verifiable off-chain computation on Sui using Nautilus. The result is a Rust server running inside an AWS Nitro Enclave whose outputs are cryptographically verified by a Move contract on chain. Covers both the enclave-side Rust code and the on-chain Move verification logic.
## When to use it
- The project needs computation that cannot run on chain (API calls, heavy ML inference, private data processing).
- The user wants verifiable off-chain results posted back to Sui with cryptographic proof.
- The user mentions TEEs, Nitro Enclaves, or Nautilus.
- The user needs an oracle-like pattern where off-chain data must be trusted on chain.
## When NOT to use it
- If the user has not picked a project yet, use `find-next-sui-idea` first.
- If the user has not scaffolded a project, use `scaffold-project` first.
- If the logic can run entirely on chain in Move, use `build-with-move` instead.
- If the user only needs price feeds, use `pyth-oracle` instead.
- If the user wants zero-knowledge proofs (not TEE attestation), this is the wrong tool. Point them to ZK resources.
If you activated this and the user actually wants something else, consult `skills/SKILL_ROUTER.md` and hand off.
## Inputs
- A Sui project (Move package and/or TS frontend).
- Optional: `.suiperpower/build-context.md` from `scaffold-project`. Read it if present.
- A description of what computation needs to happen off chain and what result goes on chain.
If unclear, interview the user for:
- What computation runs off chain? (API call, ML model, data aggregation, random number generation)
- What data does the on-chain contract need from the enclave? (a price, a score, a boolean, arbitrary bytes)
- Does the enclave need to read on-chain state before computing?
- What is the trust model? (Who runs the enclave? Single operator or decentralized?)
## Outputs
- A Move module using `enclave::enclave` to register and verify enclave signatures.
- A Rust server (Axum) implementing the enclave logic with Nautilus SDK endpoints.
- Integration code: PTB or TS that calls the enclave server, posts verified results on chain.
- Append to `.suiperpower/build-context.md`:
```markdown
## nautilus-offchain session, <timestamp>
- enclave logic: <what it computes>
- move module: <module::name>
- rust server endpoints: <list>
- pcr values: <pending build | recorded>
- deployment: <local | AWS Nitro>
- open issues: <list>
```
## Workflow
1. **Decide if TEE is needed**
- Use the decision table below. If the computation can run on chain, steer the user to `build-with-move`.
- If the user needs verifiable randomness only, check if Sui's native randomness module suffices first.
- Confirm with the user before proceeding.
2. **Design the enclave logic**
- Define what the Rust server computes: inputs it receives via POST, outputs it returns.
- Define the BCS payload struct. Field order matters: Rust and Move must match exactly.
- Sketch the endpoints: health check, attestation, and the custom processing endpoint.
3. **Write the Move contract**
- Use `enclave::enclave` module functions. See `references/nautilus-architecture.md` for the full API.
- Implement OTW pattern with `new_cap<T>` for admin capabilities.
- Create `EnclaveConfig` with expected PCR values via `create_enclave_config`.
- Write a function that calls `verify_signature` to validate enclave output before acting on it.
- Add timestamp freshness checks manually (`verify_signature` does not enforce this).
4. **Build the Rust enclave server**
- Clone the Nautilus repo: `git clone https://github.com/MystenLabs/nautilus`.
- Use the Axum server template. Implement GET `/health_check`, GET `/get_attestation`, and POST endpoint for the custom logic.
- Ensure BCS serialization of the response payload matches the Move struct field order exactly.
- Sign the payload with the enclave's ephemeral Ed25519 keypair.
5. **Deploy the Move package**
- Run `sui move build` and `sui client publish`.
- Call `create_enclave_config` with the PCR values from the built enclave image.
- Record the package ID and config object ID.
6. **Deploy the enclave**
- Build the Docker image for the Nitro Enclave.
- Extract PCR0, PCR1, PCR2 values from the built image.
- Deploy to AWS Nitro Enclave instance.
- Call `register_enclave` on chain with the attestation document.
7. **Register on chain**
- Fetch the attestation from the running enclave via GET `/get_attestation`.
- Call `register_enclave<T>(config, attestation_doc, ctx)` to register the enclave's public key.
- Verify registration succeeded by checking the on-chain enclave object.
8. **Verify the integration**
- Send a real request to the enclave's processing endpoint.
- Submit the signed response to the Move contract's verify function.
- Confirm the on-chain state updated correctly.
- Test with a tampered signature and confirm rejection.
9. **Closing handoff**
- If `.suiperpower/intent.md` exists and the session was non-trivial (new module, new sponsor integration, or material changes to public functions), recommend `verify-against-intent` as the next step so drift is caught before shipping.
- If no `intent.md` exists and the session was non-trivial, surface that gap once: offer `clarify-intent` to backfill, do not force it.
## Decision table: when to use Nautilus
| Scenario | Use Nautilus? | Alternative |
|---|---|---|
| Heavy computation (ML, data processing) | Yes | None on chain |
| External API calls (web2 data) | Yes | Pyth for price feeds specifically |
| Private data processing | Yes | Seal for encryption-only use cases |
| Simple on-chain logic | No | `build-with-move` |
| Price feeds only | No | `pyth-oracle` |
| Verifiable randomness only | No | Sui native randomness module |
| ZK proof generation | No | ZK tooling (Circom, Noir) |
## Quality gate (anti-slop)
Before reporting done, the skill asks itself the following and refuses to declare success if any answer is no:
- Does the Move package compile with `sui move build`?
- Does `verify_signature` include a manual timestamp freshness check?
- Do the BCS struct field orders match exactly between Rust and Move?
- Was a real round-trip tested (enclave processes data, Move contract verifies signature)?
- Was signature rejection tested (tampered or expired data fails verification)?
- Are PCR values documented and the user understands they must rebuild and re-register on any code change?
- Is the ephemeral keypair lifecycle documented (new key on every boot, must re-register)?
If any answer is no, the skill reports the gap and works through it before claiming the integration is complete.
## References
On-demand references (load when relevant to the user's question):
- `references/nautilus-architecture.md`: Move module API (`enclave::enclave`), Rust server setup, deployment flow.
- `references/nautilus-pitfalls.md`: Key pitfalls with PCR values, BCS ordering, ephemeral keys, and timestamp freshness.
External docs (fetch at runtime for the latest API surface):
- Nautilus repo and examples: https://github.com/MystenLabs/nautilus
- Nautilus developer guide: https://docs.sui.io/guides/developer/nautilus
## Use in your agent
- Claude Code: `claude "/suiper:nautilus-offchain <your message>"`
- Codex: `codex "/nautilus-offchain <your message>"`
- Cursor: paste a chat message that includes a phrase like "off-chain compute" or "Nautilus TEE", or load `~/.cursor/rules/nautilus-offchain.mdc` and reference it.
If you activated this and the user actually wants something else, consult `skills/SKILL_ROUTER.md` and hand off.
No comments yet. Be the first to comment!