@agentvault/secure-channel 0.5.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +37 -16
- package/dist/channel.d.ts.map +1 -1
- package/dist/cli.js +191 -25
- package/dist/cli.js.map +4 -4
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +203 -15
- package/dist/index.js.map +4 -4
- package/dist/openclaw-entry.d.ts +16 -0
- package/dist/openclaw-entry.d.ts.map +1 -0
- package/dist/openclaw-plugin.d.ts +57 -0
- package/dist/openclaw-plugin.d.ts.map +1 -0
- package/dist/setup.d.ts +15 -0
- package/dist/setup.d.ts.map +1 -0
- package/dist/transport.d.ts +3 -1
- package/dist/transport.d.ts.map +1 -1
- package/openclaw.plugin.json +13 -0
- package/package.json +26 -3
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { SecureChannel } from "./channel.js";
|
|
2
2
|
export type { SecureChannelConfig, ChannelState, MessageMetadata, PersistedState, LegacyPersistedState, DeviceSession, HistoryEntry, } from "./types.js";
|
|
3
|
-
export
|
|
3
|
+
export { agentVaultPlugin, setOcRuntime, getActiveChannel } from "./openclaw-plugin.js";
|
|
4
|
+
export declare const VERSION = "0.5.1";
|
|
4
5
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,YAAY,EACV,mBAAmB,EACnB,YAAY,EACZ,eAAe,EACf,cAAc,EACd,oBAAoB,EACpB,aAAa,EACb,YAAY,GACb,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,YAAY,EACV,mBAAmB,EACnB,YAAY,EACZ,eAAe,EACf,cAAc,EACd,oBAAoB,EACpB,aAAa,EACb,YAAY,GACb,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAExF,eAAO,MAAM,OAAO,UAAU,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -87,7 +87,7 @@ var randomValuesStandard;
|
|
|
87
87
|
var crypto;
|
|
88
88
|
var randomValueNodeJS;
|
|
89
89
|
var _Module = Module;
|
|
90
|
-
Module.ready = new Promise(function(
|
|
90
|
+
Module.ready = new Promise(function(resolve2, reject) {
|
|
91
91
|
var Module2 = _Module;
|
|
92
92
|
Module2.onAbort = reject;
|
|
93
93
|
Module2.print = function(what) {
|
|
@@ -99,13 +99,13 @@ Module.ready = new Promise(function(resolve, reject) {
|
|
|
99
99
|
Module2.onRuntimeInitialized = function() {
|
|
100
100
|
try {
|
|
101
101
|
Module2._crypto_secretbox_keybytes();
|
|
102
|
-
|
|
102
|
+
resolve2();
|
|
103
103
|
} catch (err2) {
|
|
104
104
|
reject(err2);
|
|
105
105
|
}
|
|
106
106
|
};
|
|
107
107
|
Module2.useBackupModule = function() {
|
|
108
|
-
return new Promise(function(
|
|
108
|
+
return new Promise(function(resolve3, reject2) {
|
|
109
109
|
var Module3 = {};
|
|
110
110
|
Module3.onAbort = reject2;
|
|
111
111
|
Module3.getRandomValue = _Module.getRandomValue;
|
|
@@ -118,7 +118,7 @@ Module.ready = new Promise(function(resolve, reject) {
|
|
|
118
118
|
Object.keys(Module3).forEach(function(k2) {
|
|
119
119
|
_Module[k2] = Module3[k2];
|
|
120
120
|
});
|
|
121
|
-
|
|
121
|
+
resolve3();
|
|
122
122
|
};
|
|
123
123
|
var Module3 = typeof Module3 != "undefined" ? Module3 : {};
|
|
124
124
|
var ENVIRONMENT_IS_WEB2 = !!globalThis.window;
|
|
@@ -178,13 +178,13 @@ Module.ready = new Promise(function(resolve, reject) {
|
|
|
178
178
|
}
|
|
179
179
|
readAsync2 = async (url) => {
|
|
180
180
|
if (isFileURI2(url)) {
|
|
181
|
-
return new Promise((
|
|
181
|
+
return new Promise((resolve4, reject3) => {
|
|
182
182
|
var xhr = new XMLHttpRequest();
|
|
183
183
|
xhr.open("GET", url, true);
|
|
184
184
|
xhr.responseType = "arraybuffer";
|
|
185
185
|
xhr.onload = () => {
|
|
186
186
|
if (xhr.status == 200 || xhr.status == 0 && xhr.response) {
|
|
187
|
-
|
|
187
|
+
resolve4(xhr.response);
|
|
188
188
|
return;
|
|
189
189
|
}
|
|
190
190
|
reject3(xhr.status);
|
|
@@ -40097,9 +40097,9 @@ Module.ready = new Promise(function(resolve, reject) {
|
|
|
40097
40097
|
}
|
|
40098
40098
|
var info = getWasmImports2();
|
|
40099
40099
|
if (Module3["instantiateWasm"]) {
|
|
40100
|
-
return new Promise((
|
|
40100
|
+
return new Promise((resolve4, reject3) => {
|
|
40101
40101
|
Module3["instantiateWasm"](info, (inst, mod) => {
|
|
40102
|
-
|
|
40102
|
+
resolve4(receiveInstance(inst, mod));
|
|
40103
40103
|
});
|
|
40104
40104
|
});
|
|
40105
40105
|
}
|
|
@@ -41002,13 +41002,13 @@ Module.ready = new Promise(function(resolve, reject) {
|
|
|
41002
41002
|
}
|
|
41003
41003
|
readAsync = async (url) => {
|
|
41004
41004
|
if (isFileURI(url)) {
|
|
41005
|
-
return new Promise((
|
|
41005
|
+
return new Promise((resolve3, reject2) => {
|
|
41006
41006
|
var xhr = new XMLHttpRequest();
|
|
41007
41007
|
xhr.open("GET", url, true);
|
|
41008
41008
|
xhr.responseType = "arraybuffer";
|
|
41009
41009
|
xhr.onload = () => {
|
|
41010
41010
|
if (xhr.status == 200 || xhr.status == 0 && xhr.response) {
|
|
41011
|
-
|
|
41011
|
+
resolve3(xhr.response);
|
|
41012
41012
|
return;
|
|
41013
41013
|
}
|
|
41014
41014
|
reject2(xhr.status);
|
|
@@ -41122,9 +41122,9 @@ Module.ready = new Promise(function(resolve, reject) {
|
|
|
41122
41122
|
}
|
|
41123
41123
|
var info = getWasmImports();
|
|
41124
41124
|
if (Module2["instantiateWasm"]) {
|
|
41125
|
-
return new Promise((
|
|
41125
|
+
return new Promise((resolve3, reject2) => {
|
|
41126
41126
|
Module2["instantiateWasm"](info, (inst, mod) => {
|
|
41127
|
-
|
|
41127
|
+
resolve3(receiveInstance(inst, mod));
|
|
41128
41128
|
});
|
|
41129
41129
|
});
|
|
41130
41130
|
}
|
|
@@ -45011,6 +45011,9 @@ async function enrollDevice(apiUrl, inviteToken, identityPkHex, ephemeralPkHex,
|
|
|
45011
45011
|
}
|
|
45012
45012
|
async function pollDeviceStatus(apiUrl, deviceId) {
|
|
45013
45013
|
const res = await fetch(`${apiUrl}/api/v1/devices/${deviceId}/status`);
|
|
45014
|
+
if (res.status === 429) {
|
|
45015
|
+
return { device_id: deviceId, status: "PENDING", fingerprint: "", rateLimited: true };
|
|
45016
|
+
}
|
|
45014
45017
|
if (!res.ok) {
|
|
45015
45018
|
const detail = await res.text();
|
|
45016
45019
|
throw new Error(`Status poll failed (${res.status}): ${detail}`);
|
|
@@ -45031,7 +45034,7 @@ async function activateDevice(apiUrl, deviceId) {
|
|
|
45031
45034
|
}
|
|
45032
45035
|
|
|
45033
45036
|
// src/channel.ts
|
|
45034
|
-
var POLL_INTERVAL_MS =
|
|
45037
|
+
var POLL_INTERVAL_MS = 6e3;
|
|
45035
45038
|
var RECONNECT_BASE_MS = 1e3;
|
|
45036
45039
|
var RECONNECT_MAX_MS = 3e4;
|
|
45037
45040
|
function migratePersistedState(raw) {
|
|
@@ -45316,6 +45319,10 @@ var SecureChannel = class extends EventEmitter {
|
|
|
45316
45319
|
this.config.apiUrl,
|
|
45317
45320
|
this._deviceId
|
|
45318
45321
|
);
|
|
45322
|
+
if (status.rateLimited) {
|
|
45323
|
+
this._pollTimer = setTimeout(doPoll, POLL_INTERVAL_MS * 2);
|
|
45324
|
+
return;
|
|
45325
|
+
}
|
|
45319
45326
|
if (status.status === "APPROVED") {
|
|
45320
45327
|
await this._activate();
|
|
45321
45328
|
return;
|
|
@@ -45765,10 +45772,191 @@ var SecureChannel = class extends EventEmitter {
|
|
|
45765
45772
|
}
|
|
45766
45773
|
};
|
|
45767
45774
|
|
|
45775
|
+
// src/openclaw-plugin.ts
|
|
45776
|
+
import { resolve } from "node:path";
|
|
45777
|
+
var _ocRuntime = null;
|
|
45778
|
+
var _channels = /* @__PURE__ */ new Map();
|
|
45779
|
+
function setOcRuntime(runtime) {
|
|
45780
|
+
_ocRuntime = runtime;
|
|
45781
|
+
}
|
|
45782
|
+
function getActiveChannel(accountId = "default") {
|
|
45783
|
+
return _channels.get(accountId);
|
|
45784
|
+
}
|
|
45785
|
+
var agentVaultPlugin = {
|
|
45786
|
+
id: "agentvault",
|
|
45787
|
+
meta: {
|
|
45788
|
+
id: "agentvault",
|
|
45789
|
+
label: "AgentVault",
|
|
45790
|
+
selectionLabel: "AgentVault (E2E Encrypted)",
|
|
45791
|
+
docsPath: "https://agentvault.chat/docs",
|
|
45792
|
+
blurb: "Zero-knowledge, end-to-end encrypted messaging between owners and their AI agents.",
|
|
45793
|
+
aliases: ["av", "agent-vault"]
|
|
45794
|
+
},
|
|
45795
|
+
capabilities: {
|
|
45796
|
+
chatTypes: ["direct"]
|
|
45797
|
+
},
|
|
45798
|
+
config: {
|
|
45799
|
+
listAccountIds: (cfg) => {
|
|
45800
|
+
const av = cfg?.channels?.agentvault;
|
|
45801
|
+
return av?.dataDir ? ["default"] : [];
|
|
45802
|
+
},
|
|
45803
|
+
resolveAccount: (cfg, accountId) => {
|
|
45804
|
+
const av = cfg?.channels?.agentvault ?? {};
|
|
45805
|
+
return {
|
|
45806
|
+
accountId: accountId ?? "default",
|
|
45807
|
+
dataDir: av.dataDir ?? "~/.openclaw/agentvault",
|
|
45808
|
+
apiUrl: av.apiUrl ?? "https://api.agentvault.chat",
|
|
45809
|
+
agentName: av.agentName ?? "OpenClaw Agent",
|
|
45810
|
+
configured: Boolean(av.dataDir)
|
|
45811
|
+
};
|
|
45812
|
+
}
|
|
45813
|
+
},
|
|
45814
|
+
gateway: {
|
|
45815
|
+
startAccount: async (ctx) => {
|
|
45816
|
+
const { account, cfg, log, abortSignal } = ctx;
|
|
45817
|
+
if (!account.configured) {
|
|
45818
|
+
throw new Error(
|
|
45819
|
+
"AgentVault channel is not configured.\nRun the one-time setup: npx @agentvault/secure-channel setup --token=av_tok_...\nThen restart OpenClaw: openclaw gateway restart"
|
|
45820
|
+
);
|
|
45821
|
+
}
|
|
45822
|
+
const dataDir = resolve(account.dataDir.replace(/^~/, process.env.HOME ?? "~"));
|
|
45823
|
+
log?.(`[AgentVault] starting channel (dataDir=${dataDir})`);
|
|
45824
|
+
const channel = new SecureChannel({
|
|
45825
|
+
// No invite token needed — resuming from persisted enrolled state
|
|
45826
|
+
inviteToken: "",
|
|
45827
|
+
dataDir,
|
|
45828
|
+
apiUrl: account.apiUrl,
|
|
45829
|
+
agentName: account.agentName,
|
|
45830
|
+
onMessage: async (plaintext, metadata) => {
|
|
45831
|
+
if (!_ocRuntime) {
|
|
45832
|
+
log?.("[AgentVault] runtime not ready \u2014 dropping inbound message");
|
|
45833
|
+
return;
|
|
45834
|
+
}
|
|
45835
|
+
try {
|
|
45836
|
+
await _handleInbound({ plaintext, metadata, channel, account, cfg });
|
|
45837
|
+
} catch (err) {
|
|
45838
|
+
log?.(`[AgentVault] inbound dispatch error: ${String(err)}`);
|
|
45839
|
+
}
|
|
45840
|
+
},
|
|
45841
|
+
onStateChange: (state) => {
|
|
45842
|
+
log?.(`[AgentVault] state \u2192 ${state}`);
|
|
45843
|
+
}
|
|
45844
|
+
});
|
|
45845
|
+
_channels.set(account.accountId, channel);
|
|
45846
|
+
abortSignal?.addEventListener("abort", () => {
|
|
45847
|
+
_channels.delete(account.accountId);
|
|
45848
|
+
});
|
|
45849
|
+
await channel.start();
|
|
45850
|
+
return {
|
|
45851
|
+
stop: async () => {
|
|
45852
|
+
await channel.stop();
|
|
45853
|
+
_channels.delete(account.accountId);
|
|
45854
|
+
}
|
|
45855
|
+
};
|
|
45856
|
+
}
|
|
45857
|
+
},
|
|
45858
|
+
outbound: {
|
|
45859
|
+
deliveryMode: "direct",
|
|
45860
|
+
sendText: async ({
|
|
45861
|
+
text,
|
|
45862
|
+
accountId
|
|
45863
|
+
}) => {
|
|
45864
|
+
const channel = _channels.get(accountId ?? "default");
|
|
45865
|
+
if (!channel) {
|
|
45866
|
+
return { ok: false, error: "AgentVault channel is not connected" };
|
|
45867
|
+
}
|
|
45868
|
+
try {
|
|
45869
|
+
await channel.send(text);
|
|
45870
|
+
return { ok: true };
|
|
45871
|
+
} catch (err) {
|
|
45872
|
+
return { ok: false, error: String(err) };
|
|
45873
|
+
}
|
|
45874
|
+
}
|
|
45875
|
+
}
|
|
45876
|
+
};
|
|
45877
|
+
async function _handleInbound(params) {
|
|
45878
|
+
const { plaintext, metadata, channel, account, cfg } = params;
|
|
45879
|
+
const core = _ocRuntime;
|
|
45880
|
+
const sessionKey = `agentvault:${account.accountId}:${(metadata.conversationId ?? "default").slice(0, 8)}`;
|
|
45881
|
+
const senderId = `agentvault:owner`;
|
|
45882
|
+
const route = core.channel.routing.resolveAgentRoute({
|
|
45883
|
+
cfg,
|
|
45884
|
+
channel: "agentvault",
|
|
45885
|
+
accountId: account.accountId,
|
|
45886
|
+
peer: { kind: "direct", id: senderId }
|
|
45887
|
+
});
|
|
45888
|
+
const storePath = core.channel.session.resolveStorePath(cfg?.session?.store, {
|
|
45889
|
+
agentId: route.agentId
|
|
45890
|
+
});
|
|
45891
|
+
const envelopeOptions = core.channel.reply.resolveEnvelopeFormatOptions(cfg);
|
|
45892
|
+
const previousTimestamp = core.channel.session.readSessionUpdatedAt({
|
|
45893
|
+
storePath,
|
|
45894
|
+
sessionKey: route.sessionKey
|
|
45895
|
+
});
|
|
45896
|
+
const body = core.channel.reply.formatAgentEnvelope({
|
|
45897
|
+
channel: "AgentVault",
|
|
45898
|
+
from: "Owner",
|
|
45899
|
+
timestamp: new Date(metadata.timestamp).getTime(),
|
|
45900
|
+
previousTimestamp,
|
|
45901
|
+
envelope: envelopeOptions,
|
|
45902
|
+
body: plaintext
|
|
45903
|
+
});
|
|
45904
|
+
const ctxPayload = core.channel.reply.finalizeInboundContext({
|
|
45905
|
+
Body: body,
|
|
45906
|
+
RawBody: plaintext,
|
|
45907
|
+
CommandBody: plaintext,
|
|
45908
|
+
From: senderId,
|
|
45909
|
+
To: `agentvault:agent:${account.accountId}`,
|
|
45910
|
+
SessionKey: route.sessionKey,
|
|
45911
|
+
AccountId: account.accountId,
|
|
45912
|
+
ChatType: "direct",
|
|
45913
|
+
ConversationLabel: "AgentVault",
|
|
45914
|
+
SenderName: "Owner",
|
|
45915
|
+
SenderId: senderId,
|
|
45916
|
+
Provider: "agentvault",
|
|
45917
|
+
Surface: "agentvault",
|
|
45918
|
+
MessageSid: metadata.messageId,
|
|
45919
|
+
Timestamp: new Date(metadata.timestamp).getTime(),
|
|
45920
|
+
OriginatingChannel: "agentvault",
|
|
45921
|
+
OriginatingTo: `agentvault:agent:${account.accountId}`,
|
|
45922
|
+
// Owner is cryptographically verified via X3DH + Double Ratchet enrollment
|
|
45923
|
+
CommandAuthorized: true
|
|
45924
|
+
});
|
|
45925
|
+
await core.channel.session.recordInboundSession({
|
|
45926
|
+
storePath,
|
|
45927
|
+
sessionKey: ctxPayload.SessionKey ?? route.sessionKey,
|
|
45928
|
+
ctx: ctxPayload,
|
|
45929
|
+
onRecordError: (err) => {
|
|
45930
|
+
core.error?.(`[AgentVault] session record failed: ${String(err)}`);
|
|
45931
|
+
}
|
|
45932
|
+
});
|
|
45933
|
+
await core.channel.reply.dispatchReplyWithBufferedBlockDispatcher({
|
|
45934
|
+
ctx: ctxPayload,
|
|
45935
|
+
cfg,
|
|
45936
|
+
dispatcherOptions: {
|
|
45937
|
+
deliver: async (payload) => {
|
|
45938
|
+
const text = (payload.text ?? "").trim();
|
|
45939
|
+
if (text) {
|
|
45940
|
+
await channel.send(text);
|
|
45941
|
+
}
|
|
45942
|
+
},
|
|
45943
|
+
onError: (err, info) => {
|
|
45944
|
+
core.error?.(
|
|
45945
|
+
`[AgentVault] ${info?.kind ?? "reply"} error: ${String(err)}`
|
|
45946
|
+
);
|
|
45947
|
+
}
|
|
45948
|
+
},
|
|
45949
|
+
replyOptions: {}
|
|
45950
|
+
});
|
|
45951
|
+
}
|
|
45952
|
+
|
|
45768
45953
|
// src/index.ts
|
|
45769
|
-
var VERSION = "0.
|
|
45954
|
+
var VERSION = "0.5.1";
|
|
45770
45955
|
export {
|
|
45771
45956
|
SecureChannel,
|
|
45772
|
-
VERSION
|
|
45957
|
+
VERSION,
|
|
45958
|
+
agentVaultPlugin,
|
|
45959
|
+
getActiveChannel,
|
|
45960
|
+
setOcRuntime
|
|
45773
45961
|
};
|
|
45774
45962
|
//# sourceMappingURL=index.js.map
|