-
Notifications
You must be signed in to change notification settings - Fork 9
API and Security Reference
The serialized types in Serein's extensions crate are the compatibility boundary. Internal client state and egui objects are not an extension SDK.
A plugin exports:
- A 32-bit linear
memory serein_alloc(i32 length) -> i32 pointerserein_invoke(i32 pointer, i32 length) -> i64 output
The host writes bounded UTF-8 JSON into the allocated buffer. The return value packs the output pointer into the high 32 bits and output length into the low 32 bits. Each call gets a fresh instance, so its memory and ABI buffers are destroyed when the call finishes.
The maintained Rust implementation is examples/extensions/sdk. Other languages may implement the same buffer and JSON contract, but must not import WASI or host functions.
Invocation input contains the selected action, granted context, native form values, and optional storage. Output may contain:
- A native panel
- A composer replacement proposal
- Replacement plugin storage
- A bounded appearance overlay
-
preserve_deleted_messagesfrom an authorized activation action
Results are validated against the package manifest and current account/session context. Stale results are discarded. Plugins cannot invoke internal commands or send Discord requests.
Plugins have no direct access to:
- Discord REST, Gateway, voice, or user actions
- Network sockets or HTTP
- Files, directories, or environment variables
- Processes, native libraries, or system commands
- Credentials, tokens, clipboard, microphone, camera, or screen capture
- egui drawing APIs or arbitrary application layout replacement
Execution is on demand on a background worker with bounded fuel, memory, interpreter stack, I/O, panels, queues, package size, installed count, and storage. It does not run in render or audio callbacks.
- Importing validates a package but does not execute it or grant capabilities.
- Enabling requires explicit capability consent and downloads or uses the selected package bytes.
- Updates are manual and require renewed consent.
- Disabling stops accepting results, unloads execution, and removes Serein's downloaded package, temporary files, and plugin data.
- Logout invalidates results, drains bounded work, and clears that account's extension data.
- Plugin storage is local application data and is not encrypted by Serein. Never store credentials or sensitive secrets in it.
- Theme selection is a device preference. Plugin grants and data belong to the signed-in account.
Plugins with the appearance capability return the same schema used by themes. Active plugin overlays are applied in ascending plugin-ID order; later explicit values win. The user's accent setting remains authoritative. Disabling a plugin removes its overlay.
Community appearance can be reset from Settings or with Ctrl+Shift+F12.
- Community extension architecture and creator workflow
- Theme API fields and bounds
- Complete Rust starter and ABI notes
- Message delete protector example
- Current catalog schema and example
| Error | What to check |
|---|---|
| Invalid package | JSON shape, unknown fields, IDs, manifest kind, missing theme, or unexpected Wasm |
| Unsupported version |
api_version must match the current host contract |
| Capability denied | The manifest must request the capability and the user must grant it |
| Limit exceeded | Package/module size, I/O, text, panel count/depth, storage, or image bounds |
| Plugin execution failed | Wasm imports, memory/export contract, panic, fuel, or stack exhaustion |
| Catalog download rejected | HTTPS URL, exact byte count, SHA-256, source commit, or response limit |