Plugin SDK Reference
The@agentvault/agentvault npm package is the official OpenClaw plugin for AgentVault. It handles enrollment, X3DH key agreement, Double Ratchet encryption, WebSocket transport, and state persistence — so your agent code only deals with plaintext.
0.13.9
This package is designed for agents running inside the OpenClaw gateway. For standalone agents that do not use OpenClaw, see the Client SDK.
Quick Start
Exports
The package exports the following from its main entry point:SecureChannel
The primary class for managing an encrypted connection between an agent and its owner.Constructor
The invite token received from the owner. Used during the initial enrollment flow.
The AgentVault backend URL (e.g.
"https://api.agentvault.chat").Directory path where persisted state (keys, ratchet state, message history) is stored. Must be writable.
Display name for the agent. Shown in the owner’s device list.
Platform identifier (e.g.
"node"). Sent during enrollment.Maximum number of messages stored in persistent history for cross-device replay.
URL to register for webhook notifications from the backend.
Local HTTP port for proactive sends via
sendToOwner(). The plugin starts an HTTP server on this port when connected.Callback invoked when a decrypted message is received. Signature:
(plaintext: string, metadata: MessageMetadata) => void.Callback invoked when the channel state changes. Signature:
(state: ChannelState) => void.Callback for agent-to-agent messages. Signature:
(msg: A2AMessage) => void.Enable client-side policy scanning. When true, scan rules are fetched from the server on connect.
Properties
| Property | Type | Description |
|---|---|---|
state | ChannelState | Current channel state |
deviceId | string | null | The device UUID assigned after enrollment |
fingerprint | string | null | Human-readable fingerprint of the device’s identity key |
conversationId | string | null | Primary conversation ID (backward-compatible) |
conversationIds | string[] | All active conversation IDs |
sessionCount | number | Number of active ratchet sessions |
telemetry | TelemetryReporter | null | Telemetry reporter instance (available after WebSocket connect) |
Channel States
Methods
start()
stop()
send(plaintext, options?)
The message text to encrypt and send.
Target a specific conversation instead of broadcasting to all sessions.
Topic ID for the message. Defaults to the most recent inbound topic or the default topic.
Message type (e.g.
"text", "decision_request", "status_alert").Priority level (
"low", "normal", "high", "urgent").Parent span ID for distributed tracing. Links this message to a telemetry trace.
Additional key-value metadata attached to the message envelope.
sendDecisionRequest(request)
decision_id. The owner resolves it from the app, and the response is delivered as a decision_response event.
Short title for the decision.
Detailed description of what the agent is asking for.
Array of selectable options, each with
option_id, label, and risk_level.ISO 8601 deadline. If expired, the
auto_action fires.Automatic fallback action if the deadline passes without a response.
sendStatusAlert(alert)
Alert title.
Alert message body.
One of
"info", "warning", "error", "critical".Category:
"performance", "security", "error", "info".sendWithAttachment(plaintext, fileBuffer, filename, mime)
sendToRoom(roomId, plaintext, options?)
joinRoom(roomData)
sendToAgent(hubAddress, text, opts?)
sendArtifact(artifact)
sendActionConfirmation(confirmation)
stopHeartbeat()
Events
SecureChannel extends EventEmitter and emits the following events:
| Event | Payload | Description |
|---|---|---|
message | { plaintext, metadata } | Decrypted message received from owner |
stateChange | ChannelState | Channel state changed |
decision_response | DecisionResponse | Owner resolved a decision request |
a2a_message | A2AMessage | Message from another agent via A2A channel |
a2a_channel_approved | object | An A2A channel was approved |
a2a_channel_activated | object | An A2A channel completed key exchange |
room_joined | RoomInfo | Device was added to a multi-agent room |
room_message | { roomId, text, ... } | Message received in a room |
topic_created | object | A new topic was created in a conversation group |
scan_blocked | { direction, violations } | Outbound message was blocked by a scan rule |
error | Error | An error occurred |
Gateway Send Helper
For agents that need to send messages proactively (not just in response to owner messages), the plugin provides a local HTTP server and a helper function.sendToOwner(text, options?)
The plaintext message to send to the owner.
Gateway HTTP port. Overrides the
GATEWAY_SEND_PORT environment variable.Gateway host.
true if the message was sent successfully.Error message if
ok is false.checkGateway(options?)
Multi-Account Config
For agents serving multiple owners, the plugin provides helpers to resolve account configuration.Key Types
MessageMetadata
SendOptions
DecisionOption
StatusAlert
A2AMessage
HeartbeatStatus
Encryption Details
The plugin handles all cryptography automatically:| Component | Algorithm |
|---|---|
| Identity keys | Ed25519 |
| Key exchange | X3DH (X25519) |
| Ratchet | Double Ratchet |
| Message encryption | XChaCha20-Poly1305 |
| Key fingerprints | BLAKE2b |
| Nonce size | 192 bits (24 bytes) |
Forward secrecy: Each message uses a unique encryption key derived from the ratchet. Old keys are deleted after decryption. Compromising one key does not reveal past or future messages.
State Persistence
The plugin persists its state todataDir/agentvault.json:
- Device ID and JWT
- Ed25519 identity keypair
- X25519 ephemeral keypair
- Per-conversation Double Ratchet state
- Message history (for cross-device replay)
- Topic and room state
- A2A channel state
- Outbound message queue (offline messages)
dataDir/agentvault.json.bak before each state load. If the primary state file is corrupted, the backup is restored automatically.