Files
motr-enclave/AGENTS.md

4.6 KiB

Agent Guidelines for Motr Enclave

Generated: 2026-01-10 | Commit: 1c8b908 | Branch: main

Overview

Go 1.25+ Extism WASM plugin (wasip1) providing encrypted key storage for Nebula wallet. SQLite-centric architecture where database acts as "DID CPU" with custom crypto functions.

Structure

motr-enclave/
├── cmd/enclave/           # WASM entry: generate, load, exec, query, ping
├── internal/
│   ├── keybase/           # DB layer + SQLite functions + action handlers
│   ├── crypto/{mpc,ucan,bip44}  # Threshold sigs, UCAN v1.0.0-rc.1, derivation
│   ├── types/             # JSON I/O structs
│   ├── state/             # WASM singleton state
│   └── migrations/        # Schema + SQLC queries (embedded)
├── src/                   # TypeScript SDK (@sonr/motr-enclave)
└── example/               # Browser demo (Vite)

Where to Look

Task Location Notes
Add WASM export cmd/enclave/main.go //go:wasmexport + pdk pattern
Add exec action internal/keybase/exec.go Add to handlers map
New action handler internal/keybase/actions_*.go handle<Resource><Action> signature
SQLite custom func internal/keybase/functions.go conn.CreateFunction pattern
DB schema change internal/migrations/schema.sql Then make generate
New query internal/migrations/query.sql SQLC annotations
MPC operations internal/crypto/mpc/ 2-of-2 threshold ECDSA
UCAN builders internal/crypto/ucan/ v1.0.0-rc.1 DAG-CBOR
SDK wrapper src/enclave.ts Extism JSON bridge

Code Map

WASM Exports (cmd/enclave/main.go)

Function Purpose
ping Health check
generate Create identity + MPC key from WebAuthn credential
load Hydrate from encrypted DB blob
exec Resource-action dispatcher
query Return DID document

Exec Filter Syntax

resource:<name> action:<action> [subject:<value>]
Resource Actions
accounts list, get, sign
enclaves list, get, sign, rotate, archive, delete
delegations list, list_received, list_command, get, revoke, verify, cleanup
credentials list, get
sessions list, revoke
grants list, revoke
services list, get, get_by_id

SQLite Functions (DID CPU)

Function Purpose
bip44_derive(pubkey_hex, chain) Address from pubkey
bip44_derive_from_enclave(id, chain) Address from stored enclave
mpc_sign(enclave_id, data) Threshold signature

Conventions

Import Order

import (
    "stdlib"

    "external/deps"

    "enclave/internal"
)

Naming

  • Types: PascalCase | JSON: snake_case
  • Handlers: handle<Resource><Action>
  • Errors: prefix with function name

Extism Plugin Pattern

//go:wasmexport functionName
func functionName() int32 {
    pdk.Log(pdk.LogInfo, "functionName: starting")
    var input InputType
    if err := pdk.InputJSON(&input); err != nil {
        pdk.SetError(fmt.Errorf("functionName: %w", err))
        return 1
    }
    // ...
    pdk.OutputJSON(output)
    return 0
}

ActionManager Pattern

func (am *ActionManager) DoThing(ctx context.Context, params) (Result, error) {
    am.kb.mu.RLock()  // or Lock() for writes
    defer am.kb.mu.RUnlock()
    return am.queries.SomeQuery(ctx, params)
}

Anti-Patterns

Forbidden Reason
Edit *.sql.go files SQLC generated - make generate
as any / type suppression Type safety critical for crypto
Log/return raw key material Security - shares never leave enclave
Skip mutex in ActionManager WASM single-threaded but state persists

Commands

make build          # GOOS=wasip1 GOARCH=wasm
make generate       # SQLC code gen
make test-plugin    # Extism CLI validation
make sdk            # Build TypeScript SDK
make start          # Full setup + dev server

Data Boundaries

Stored in Enclave

  • WebAuthn credentials, MPC key shares, UCAN delegations
  • Sessions, grants, DID document cache, multi-chain accounts

NOT in Enclave (fetch from APIs)

  • Token balances, transaction history, NFT holdings, prices

Build Constraints

  • cmd/enclave/, internal/state/: //go:build wasip1 only
  • Target: GOOS=wasip1 GOARCH=wasm -buildmode=c-shared
  • Encryption: AES-256-GCM via WebAuthn PRF key derivation

Notes

  • No *_test.go files currently - tests in example/ browser suite
  • UCAN uses DAG-CBOR envelopes, not JWT (v1.0.0-rc.1)
  • Database serialized as single encrypted blob for storage