@glyphteck/veyl 0.68.0 → 0.70.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/dist/account.js +11352 -9185
- package/dist/accountprofiles.js +27 -4
- package/dist/auth.js +2 -2
- package/dist/cli.js +15890 -8210
- package/dist/index.js +15886 -8206
- package/dist/kdf-worker-thread.js +174 -143
- package/docs/agents.md +2 -2
- package/docs/api.md +28 -9
- package/docs/cli.md +4 -4
- package/docs/validation.md +1 -1
- package/examples/bot-fleet/readme.md +1 -1
- package/examples/codex-agent/readme.md +1 -1
- package/package.json +1 -1
|
@@ -48,39 +48,7 @@ var __export = (target, all) => {
|
|
|
48
48
|
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
49
49
|
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
50
50
|
|
|
51
|
-
// ../../node_modules/.bun/@noble+hashes@2.
|
|
52
|
-
function fromBig(n, le = false) {
|
|
53
|
-
if (le)
|
|
54
|
-
return { h: Number(n & U32_MASK64), l: Number(n >> _32n & U32_MASK64) };
|
|
55
|
-
return { h: Number(n >> _32n & U32_MASK64) | 0, l: Number(n & U32_MASK64) | 0 };
|
|
56
|
-
}
|
|
57
|
-
function split(lst, le = false) {
|
|
58
|
-
const len = lst.length;
|
|
59
|
-
let Ah = new Uint32Array(len);
|
|
60
|
-
let Al = new Uint32Array(len);
|
|
61
|
-
for (let i = 0;i < len; i++) {
|
|
62
|
-
const { h, l } = fromBig(lst[i], le);
|
|
63
|
-
[Ah[i], Al[i]] = [h, l];
|
|
64
|
-
}
|
|
65
|
-
return [Ah, Al];
|
|
66
|
-
}
|
|
67
|
-
function setU64FromNum(view, byteOffset, n, isLE) {
|
|
68
|
-
const h = fromNumH(n);
|
|
69
|
-
const l = fromNumL(n);
|
|
70
|
-
view.setUint32(byteOffset, isLE ? l : h, isLE);
|
|
71
|
-
view.setUint32(byteOffset + 4, isLE ? h : l, isLE);
|
|
72
|
-
}
|
|
73
|
-
function add(Ah, Al, Bh, Bl) {
|
|
74
|
-
const l = (Al >>> 0) + (Bl >>> 0);
|
|
75
|
-
return { h: Ah + Bh + (l / 2 ** 32 | 0) | 0, l: l | 0 };
|
|
76
|
-
}
|
|
77
|
-
var U32_MASK64, _32n, fromNumH = (n) => n / 2 ** 32 | 0, fromNumL = (n) => n >>> 0, shrSH = (h, _l, s) => h >>> s, shrSL = (h, l, s) => h << 32 - s | l >>> s, rotrSH = (h, l, s) => h >>> s | l << 32 - s, rotrSL = (h, l, s) => h << 32 - s | l >>> s, rotrBH = (h, l, s) => h << 64 - s | l >>> s - 32, rotrBL = (h, l, s) => h >>> s - 32 | l << 64 - s, rotr32H = (_h, l) => l, rotr32L = (h, _l) => h, add3L = (Al, Bl, Cl) => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0), add3H = (low, Ah, Bh, Ch) => Ah + Bh + Ch + (low / 2 ** 32 | 0) | 0, add4L = (Al, Bl, Cl, Dl) => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0) + (Dl >>> 0), add4H = (low, Ah, Bh, Ch, Dh) => Ah + Bh + Ch + Dh + (low / 2 ** 32 | 0) | 0, add5L = (Al, Bl, Cl, Dl, El) => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0) + (Dl >>> 0) + (El >>> 0), add5H = (low, Ah, Bh, Ch, Dh, Eh) => Ah + Bh + Ch + Dh + Eh + (low / 2 ** 32 | 0) | 0;
|
|
78
|
-
var init__u64 = __esm(() => {
|
|
79
|
-
U32_MASK64 = /* @__PURE__ */ (() => BigInt(2 ** 32 - 1))();
|
|
80
|
-
_32n = /* @__PURE__ */ BigInt(32);
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
// ../../node_modules/.bun/@noble+hashes@2.3.0/node_modules/@noble/hashes/utils.js
|
|
51
|
+
// ../../node_modules/.bun/@noble+hashes@2.4.0/node_modules/@noble/hashes/utils.js
|
|
84
52
|
function isBytes(a) {
|
|
85
53
|
return a instanceof Uint8Array || ArrayBuffer.isView(a) && a.constructor.name === "Uint8Array" && "BYTES_PER_ELEMENT" in a && a.BYTES_PER_ELEMENT === 1;
|
|
86
54
|
}
|
|
@@ -198,7 +166,12 @@ function hexToBytes(hex) {
|
|
|
198
166
|
function utf8ToBytes(str) {
|
|
199
167
|
if (typeof str !== "string")
|
|
200
168
|
throw new TypeError("string expected");
|
|
201
|
-
|
|
169
|
+
const encoded = new TextEncoder().encode(str);
|
|
170
|
+
try {
|
|
171
|
+
return new Uint8Array(encoded);
|
|
172
|
+
} finally {
|
|
173
|
+
clean(encoded);
|
|
174
|
+
}
|
|
202
175
|
}
|
|
203
176
|
function kdfInputToBytes(data, errorTitle = "") {
|
|
204
177
|
if (typeof data === "string")
|
|
@@ -221,10 +194,10 @@ function concatBytes(...arrays) {
|
|
|
221
194
|
return res;
|
|
222
195
|
}
|
|
223
196
|
function checkOpts(defaults, opts, title = "opts") {
|
|
224
|
-
|
|
197
|
+
aopts(defaults, "defaults");
|
|
225
198
|
if (opts !== undefined)
|
|
226
|
-
|
|
227
|
-
const merged = Object.assign(defaults, opts);
|
|
199
|
+
aopts(opts, title);
|
|
200
|
+
const merged = Object.assign(Object.create(null), defaults, opts);
|
|
228
201
|
return merged;
|
|
229
202
|
}
|
|
230
203
|
function createHasher(hashCons, info = {}) {
|
|
@@ -252,6 +225,13 @@ function randomBytes(bytesLength = 32) {
|
|
|
252
225
|
var atitle = (title) => title ? `"${title}" ` : "", aobject = (value, label) => {
|
|
253
226
|
if (value === null || typeof value !== "object" || Array.isArray(value))
|
|
254
227
|
throw new TypeError((label === "object" ? "" : `"${label}" `) + "expected object, got type=" + typeof value);
|
|
228
|
+
}, aopts = (value, label) => {
|
|
229
|
+
aobject(value, label);
|
|
230
|
+
const proto = Object.getPrototypeOf(value);
|
|
231
|
+
if (proto !== Object.prototype && proto !== null)
|
|
232
|
+
throw new TypeError(`"${label}" expected plain object`);
|
|
233
|
+
if (Object.hasOwn(value, "__proto__"))
|
|
234
|
+
throw new TypeError(`"${label}.__proto__" is not allowed`);
|
|
255
235
|
}, isLE, swap8IfBE, swap32IfBE, hasHexBuiltin, hexes, oidNist = (suffix) => ({
|
|
256
236
|
oid: Uint8Array.from([6, 9, 96, 134, 72, 1, 101, 3, 4, 2, suffix])
|
|
257
237
|
});
|
|
@@ -263,7 +243,39 @@ var init_utils = __esm(() => {
|
|
|
263
243
|
hexes = /* @__PURE__ */ Array.from({ length: 256 }, (_, i) => i.toString(16).padStart(2, "0"));
|
|
264
244
|
});
|
|
265
245
|
|
|
266
|
-
// ../../node_modules/.bun/@noble+hashes@2.
|
|
246
|
+
// ../../node_modules/.bun/@noble+hashes@2.4.0/node_modules/@noble/hashes/_u64.js
|
|
247
|
+
function fromBig(n, le = false) {
|
|
248
|
+
if (le)
|
|
249
|
+
return { h: Number(n & U32_MASK64), l: Number(n >> _32n & U32_MASK64) };
|
|
250
|
+
return { h: Number(n >> _32n & U32_MASK64) | 0, l: Number(n & U32_MASK64) | 0 };
|
|
251
|
+
}
|
|
252
|
+
function split(lst, le = false) {
|
|
253
|
+
const len = lst.length;
|
|
254
|
+
let Ah = new Uint32Array(len);
|
|
255
|
+
let Al = new Uint32Array(len);
|
|
256
|
+
for (let i = 0;i < len; i++) {
|
|
257
|
+
const { h, l } = fromBig(lst[i], le);
|
|
258
|
+
[Ah[i], Al[i]] = [h, l];
|
|
259
|
+
}
|
|
260
|
+
return [Ah, Al];
|
|
261
|
+
}
|
|
262
|
+
function setU64FromNum(view, byteOffset, n, isLE2) {
|
|
263
|
+
const h = fromNumH(n);
|
|
264
|
+
const l = fromNumL(n);
|
|
265
|
+
view.setUint32(byteOffset, isLE2 ? l : h, isLE2);
|
|
266
|
+
view.setUint32(byteOffset + 4, isLE2 ? h : l, isLE2);
|
|
267
|
+
}
|
|
268
|
+
function add(Ah, Al, Bh, Bl) {
|
|
269
|
+
const l = (Al >>> 0) + (Bl >>> 0);
|
|
270
|
+
return { h: Ah + Bh + (l / 2 ** 32 | 0) | 0, l: l | 0 };
|
|
271
|
+
}
|
|
272
|
+
var U32_MASK64, _32n, fromNumH = (n) => n / 2 ** 32 | 0, fromNumL = (n) => n >>> 0, shrSH = (h, _l, s) => h >>> s, shrSL = (h, l, s) => h << 32 - s | l >>> s, rotrSH = (h, l, s) => h >>> s | l << 32 - s, rotrSL = (h, l, s) => h << 32 - s | l >>> s, rotrBH = (h, l, s) => h << 64 - s | l >>> s - 32, rotrBL = (h, l, s) => h >>> s - 32 | l << 64 - s, rotr32H = (_h, l) => l, rotr32L = (h, _l) => h, add3L = (Al, Bl, Cl) => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0), add3H = (low, Ah, Bh, Ch) => Ah + Bh + Ch + (low / 2 ** 32 | 0) | 0, add4L = (Al, Bl, Cl, Dl) => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0) + (Dl >>> 0), add4H = (low, Ah, Bh, Ch, Dh) => Ah + Bh + Ch + Dh + (low / 2 ** 32 | 0) | 0, add5L = (Al, Bl, Cl, Dl, El) => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0) + (Dl >>> 0) + (El >>> 0), add5H = (low, Ah, Bh, Ch, Dh, Eh) => Ah + Bh + Ch + Dh + Eh + (low / 2 ** 32 | 0) | 0;
|
|
273
|
+
var init__u64 = __esm(() => {
|
|
274
|
+
U32_MASK64 = /* @__PURE__ */ (() => BigInt(2 ** 32 - 1))();
|
|
275
|
+
_32n = /* @__PURE__ */ BigInt(32);
|
|
276
|
+
});
|
|
277
|
+
|
|
278
|
+
// ../../node_modules/.bun/@noble+hashes@2.4.0/node_modules/@noble/hashes/_md.js
|
|
267
279
|
function Chi(a, b, c) {
|
|
268
280
|
return a & b ^ ~a & c;
|
|
269
281
|
}
|
|
@@ -402,10 +414,7 @@ var init__md = __esm(() => {
|
|
|
402
414
|
// src/runtime/kdf-worker-thread.js
|
|
403
415
|
import { parentPort } from "node:worker_threads";
|
|
404
416
|
|
|
405
|
-
// ../../node_modules/.bun/@noble+hashes@2.
|
|
406
|
-
init__u64();
|
|
407
|
-
|
|
408
|
-
// ../../node_modules/.bun/@noble+hashes@2.3.0/node_modules/@noble/hashes/_blake.js
|
|
417
|
+
// ../../node_modules/.bun/@noble+hashes@2.4.0/node_modules/@noble/hashes/_blake.js
|
|
409
418
|
var BSIGMA = /* @__PURE__ */ Uint8Array.from([
|
|
410
419
|
0,
|
|
411
420
|
1,
|
|
@@ -665,7 +674,7 @@ var BSIGMA = /* @__PURE__ */ Uint8Array.from([
|
|
|
665
674
|
9
|
|
666
675
|
]);
|
|
667
676
|
|
|
668
|
-
// ../../node_modules/.bun/@noble+hashes@2.
|
|
677
|
+
// ../../node_modules/.bun/@noble+hashes@2.4.0/node_modules/@noble/hashes/blake2.js
|
|
669
678
|
init__u64();
|
|
670
679
|
init_utils();
|
|
671
680
|
var B2B_IV = /* @__PURE__ */ Uint32Array.from([
|
|
@@ -1000,7 +1009,7 @@ class _BLAKE2b extends _BLAKE2 {
|
|
|
1000
1009
|
}
|
|
1001
1010
|
var blake2b = /* @__PURE__ */ createHasher((opts) => new _BLAKE2b(opts));
|
|
1002
1011
|
|
|
1003
|
-
// ../../node_modules/.bun/@noble+hashes@2.
|
|
1012
|
+
// ../../node_modules/.bun/@noble+hashes@2.4.0/node_modules/@noble/hashes/argon2.js
|
|
1004
1013
|
init_utils();
|
|
1005
1014
|
var AT = { Argon2d: 0, Argon2i: 1, Argon2id: 2 };
|
|
1006
1015
|
var ARGON2_SYNC_POINTS = 4;
|
|
@@ -1009,25 +1018,6 @@ var abytesOrZero = (buf, errorTitle = "") => {
|
|
|
1009
1018
|
return Uint8Array.of();
|
|
1010
1019
|
return kdfInputToBytes(buf, errorTitle);
|
|
1011
1020
|
};
|
|
1012
|
-
function mul(a, b) {
|
|
1013
|
-
const aL = a & 65535;
|
|
1014
|
-
const aH = a >>> 16;
|
|
1015
|
-
const bL = b & 65535;
|
|
1016
|
-
const bH = b >>> 16;
|
|
1017
|
-
const ll = Math.imul(aL, bL);
|
|
1018
|
-
const hl = Math.imul(aH, bL);
|
|
1019
|
-
const lh = Math.imul(aL, bH);
|
|
1020
|
-
const hh = Math.imul(aH, bH);
|
|
1021
|
-
const carry = (ll >>> 16) + (hl & 65535) + lh;
|
|
1022
|
-
const high = hh + (hl >>> 16) + (carry >>> 16) | 0;
|
|
1023
|
-
const low = carry << 16 | ll & 65535;
|
|
1024
|
-
return { h: high, l: low };
|
|
1025
|
-
}
|
|
1026
|
-
function mulHi(a, b) {
|
|
1027
|
-
const aL = a & 65535, aH = a >>> 16, bL = b & 65535, bH = b >>> 16;
|
|
1028
|
-
const carry = (Math.imul(aL, bL) >>> 16) + (Math.imul(aH, bL) & 65535) + Math.imul(aL, bH);
|
|
1029
|
-
return Math.imul(aH, bH) + (Math.imul(aH, bL) >>> 16) + (carry >>> 16) | 0;
|
|
1030
|
-
}
|
|
1031
1021
|
var A2_BUF = new Uint32Array(256);
|
|
1032
1022
|
function G(a, b, c, d) {
|
|
1033
1023
|
let Al = A2_BUF[2 * a], Ah = A2_BUF[2 * a + 1];
|
|
@@ -1036,41 +1026,41 @@ function G(a, b, c, d) {
|
|
|
1036
1026
|
let Dl = A2_BUF[2 * d], Dh = A2_BUF[2 * d + 1];
|
|
1037
1027
|
let ml = 0, mh = 0, rl = 0, xh = 0, xl = 0;
|
|
1038
1028
|
ml = Math.imul(Al, Bl);
|
|
1039
|
-
mh =
|
|
1029
|
+
mh = ((Al >>> 0) * (Bl >>> 0) - (ml >>> 0)) / 4294967296 + 0.5 | 0;
|
|
1040
1030
|
rl = (Al >>> 0) + (Bl >>> 0) + (ml << 1 >>> 0);
|
|
1041
1031
|
Ah = Ah + Bh + (mh << 1 | ml >>> 31) + (rl / 4294967296 | 0) | 0;
|
|
1042
1032
|
Al = rl | 0;
|
|
1043
1033
|
xh = Dh ^ Ah;
|
|
1044
1034
|
xl = Dl ^ Al;
|
|
1045
|
-
Dh =
|
|
1046
|
-
Dl =
|
|
1035
|
+
Dh = xl;
|
|
1036
|
+
Dl = xh;
|
|
1047
1037
|
ml = Math.imul(Cl, Dl);
|
|
1048
|
-
mh =
|
|
1038
|
+
mh = ((Cl >>> 0) * (Dl >>> 0) - (ml >>> 0)) / 4294967296 + 0.5 | 0;
|
|
1049
1039
|
rl = (Cl >>> 0) + (Dl >>> 0) + (ml << 1 >>> 0);
|
|
1050
1040
|
Ch = Ch + Dh + (mh << 1 | ml >>> 31) + (rl / 4294967296 | 0) | 0;
|
|
1051
1041
|
Cl = rl | 0;
|
|
1052
1042
|
xh = Bh ^ Ch;
|
|
1053
1043
|
xl = Bl ^ Cl;
|
|
1054
|
-
Bh =
|
|
1055
|
-
Bl =
|
|
1044
|
+
Bh = xh >>> 24 | xl << 8;
|
|
1045
|
+
Bl = xh << 8 | xl >>> 24;
|
|
1056
1046
|
ml = Math.imul(Al, Bl);
|
|
1057
|
-
mh =
|
|
1047
|
+
mh = ((Al >>> 0) * (Bl >>> 0) - (ml >>> 0)) / 4294967296 + 0.5 | 0;
|
|
1058
1048
|
rl = (Al >>> 0) + (Bl >>> 0) + (ml << 1 >>> 0);
|
|
1059
1049
|
Ah = Ah + Bh + (mh << 1 | ml >>> 31) + (rl / 4294967296 | 0) | 0;
|
|
1060
1050
|
Al = rl | 0;
|
|
1061
1051
|
xh = Dh ^ Ah;
|
|
1062
1052
|
xl = Dl ^ Al;
|
|
1063
|
-
Dh =
|
|
1064
|
-
Dl =
|
|
1053
|
+
Dh = xh >>> 16 | xl << 16;
|
|
1054
|
+
Dl = xh << 16 | xl >>> 16;
|
|
1065
1055
|
ml = Math.imul(Cl, Dl);
|
|
1066
|
-
mh =
|
|
1056
|
+
mh = ((Cl >>> 0) * (Dl >>> 0) - (ml >>> 0)) / 4294967296 + 0.5 | 0;
|
|
1067
1057
|
rl = (Cl >>> 0) + (Dl >>> 0) + (ml << 1 >>> 0);
|
|
1068
1058
|
Ch = Ch + Dh + (mh << 1 | ml >>> 31) + (rl / 4294967296 | 0) | 0;
|
|
1069
1059
|
Cl = rl | 0;
|
|
1070
1060
|
xh = Bh ^ Ch;
|
|
1071
1061
|
xl = Bl ^ Cl;
|
|
1072
|
-
Bh =
|
|
1073
|
-
Bl =
|
|
1062
|
+
Bh = xh << 1 | xl >>> 31;
|
|
1063
|
+
Bl = xh >>> 31 | xl << 1;
|
|
1074
1064
|
A2_BUF[2 * a] = Al, A2_BUF[2 * a + 1] = Ah;
|
|
1075
1065
|
A2_BUF[2 * b] = Bl, A2_BUF[2 * b + 1] = Bh;
|
|
1076
1066
|
A2_BUF[2 * c] = Cl, A2_BUF[2 * c + 1] = Ch;
|
|
@@ -1087,20 +1077,27 @@ function P(v00, v01, v02, v03, v04, v05, v06, v07, v08, v09, v10, v11, v12, v13,
|
|
|
1087
1077
|
G(v03, v04, v09, v14);
|
|
1088
1078
|
}
|
|
1089
1079
|
function block(x, xPos, yPos, outPos, needXor) {
|
|
1090
|
-
|
|
1091
|
-
|
|
1080
|
+
if (needXor) {
|
|
1081
|
+
for (let i = 0;i < 256; i++) {
|
|
1082
|
+
const r = x[xPos + i] ^ x[yPos + i];
|
|
1083
|
+
A2_BUF[i] = r;
|
|
1084
|
+
x[outPos + i] ^= r;
|
|
1085
|
+
}
|
|
1086
|
+
} else {
|
|
1087
|
+
for (let i = 0;i < 256; i++) {
|
|
1088
|
+
const r = x[xPos + i] ^ x[yPos + i];
|
|
1089
|
+
A2_BUF[i] = r;
|
|
1090
|
+
x[outPos + i] = r;
|
|
1091
|
+
}
|
|
1092
|
+
}
|
|
1092
1093
|
for (let i = 0;i < 128; i += 16) {
|
|
1093
1094
|
P(i, i + 1, i + 2, i + 3, i + 4, i + 5, i + 6, i + 7, i + 8, i + 9, i + 10, i + 11, i + 12, i + 13, i + 14, i + 15);
|
|
1094
1095
|
}
|
|
1095
1096
|
for (let i = 0;i < 16; i += 2) {
|
|
1096
1097
|
P(i, i + 1, i + 16, i + 17, i + 32, i + 33, i + 48, i + 49, i + 64, i + 65, i + 80, i + 81, i + 96, i + 97, i + 112, i + 113);
|
|
1097
1098
|
}
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
x[outPos + i] ^= A2_BUF[i] ^ x[xPos + i] ^ x[yPos + i];
|
|
1101
|
-
else
|
|
1102
|
-
for (let i = 0;i < 256; i++)
|
|
1103
|
-
x[outPos + i] = A2_BUF[i] ^ x[xPos + i] ^ x[yPos + i];
|
|
1099
|
+
for (let i = 0;i < 256; i++)
|
|
1100
|
+
x[outPos + i] ^= A2_BUF[i];
|
|
1104
1101
|
clean(A2_BUF);
|
|
1105
1102
|
}
|
|
1106
1103
|
function Hp(A, dkLen) {
|
|
@@ -1139,19 +1136,28 @@ function indexAlpha(r, s, laneLen, segmentLen, index, randL, sameLane = false) {
|
|
|
1139
1136
|
else
|
|
1140
1137
|
area = laneLen - segmentLen + (index == 0 ? -1 : 0);
|
|
1141
1138
|
const startPos = r !== 0 && s !== ARGON2_SYNC_POINTS - 1 ? (s + 1) * segmentLen : 0;
|
|
1142
|
-
const
|
|
1139
|
+
const randLow = Math.imul(randL, randL);
|
|
1140
|
+
const randHigh = ((randL >>> 0) * (randL >>> 0) - (randLow >>> 0)) / 4294967296 + 0.5 | 0;
|
|
1141
|
+
const areaLow = Math.imul(area, randHigh);
|
|
1142
|
+
const areaHigh = ((area >>> 0) * (randHigh >>> 0) - (areaLow >>> 0)) / 4294967296 + 0.5 | 0;
|
|
1143
|
+
const rel = area - 1 - areaHigh;
|
|
1143
1144
|
return (startPos + rel) % laneLen;
|
|
1144
1145
|
}
|
|
1145
1146
|
var maxUint32 = Math.pow(2, 32);
|
|
1147
|
+
var ARGON2_DEFAULT_MEMORY = 1024 ** 2;
|
|
1148
|
+
var ARGON2_DEFAULT_MAXMEM = ARGON2_DEFAULT_MEMORY * 1024;
|
|
1146
1149
|
function isU32(num) {
|
|
1147
1150
|
return Number.isSafeInteger(num) && num >= 0 && num < maxUint32;
|
|
1148
1151
|
}
|
|
1149
|
-
function argon2Opts(opts) {
|
|
1152
|
+
function argon2Opts(opts = {}) {
|
|
1150
1153
|
opts = checkOpts({}, opts);
|
|
1151
1154
|
const merged = {
|
|
1155
|
+
t: 3,
|
|
1156
|
+
m: ARGON2_DEFAULT_MEMORY,
|
|
1157
|
+
p: 1,
|
|
1152
1158
|
version: 19,
|
|
1153
1159
|
dkLen: 32,
|
|
1154
|
-
maxmem:
|
|
1160
|
+
maxmem: ARGON2_DEFAULT_MAXMEM,
|
|
1155
1161
|
asyncTick: 10
|
|
1156
1162
|
};
|
|
1157
1163
|
for (let [k, v] of Object.entries(opts))
|
|
@@ -1175,63 +1181,89 @@ function argon2Opts(opts) {
|
|
|
1175
1181
|
throw new Error('"version" must be 0x10 or 0x13, got ' + version);
|
|
1176
1182
|
return merged;
|
|
1177
1183
|
}
|
|
1178
|
-
function
|
|
1179
|
-
|
|
1180
|
-
salt = kdfInputToBytes(salt, "salt");
|
|
1181
|
-
if (!isU32(password.length))
|
|
1182
|
-
throw new Error('"password" must be less of length 1..4Gb');
|
|
1183
|
-
if (!isU32(salt.length) || salt.length < 8)
|
|
1184
|
-
throw new Error('"salt" must be of length 8..4Gb');
|
|
1185
|
-
if (!Object.values(AT).includes(type))
|
|
1186
|
-
throw new Error('"type" was invalid');
|
|
1187
|
-
let { p, dkLen, m, t, version, key, personalization, maxmem, onProgress, asyncTick } = argon2Opts(opts);
|
|
1188
|
-
key = abytesOrZero(key, "key");
|
|
1189
|
-
personalization = abytesOrZero(personalization, "personalization");
|
|
1190
|
-
const h = blake2b.create();
|
|
1184
|
+
function argon2InitialHash(password, salt, type, opts) {
|
|
1185
|
+
const ownedInputs = [];
|
|
1191
1186
|
const BUF = new Uint32Array(1);
|
|
1192
1187
|
const BUF8 = u8(BUF);
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
}
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1188
|
+
let h;
|
|
1189
|
+
let H0;
|
|
1190
|
+
let succeeded = false;
|
|
1191
|
+
const rememberOwned = (input, bytes) => {
|
|
1192
|
+
if (typeof input === "string")
|
|
1193
|
+
ownedInputs.push(bytes);
|
|
1194
|
+
return bytes;
|
|
1195
|
+
};
|
|
1196
|
+
try {
|
|
1197
|
+
const passwordBytes = rememberOwned(password, kdfInputToBytes(password, "password"));
|
|
1198
|
+
const saltBytes = rememberOwned(salt, kdfInputToBytes(salt, "salt"));
|
|
1199
|
+
if (!isU32(passwordBytes.length))
|
|
1200
|
+
throw new Error('"password" must be less of length 1..4Gb');
|
|
1201
|
+
if (!isU32(saltBytes.length) || saltBytes.length < 8)
|
|
1202
|
+
throw new Error('"salt" must be of length 8..4Gb');
|
|
1203
|
+
if (!Object.values(AT).includes(type))
|
|
1204
|
+
throw new Error('"type" was invalid');
|
|
1205
|
+
let { p, dkLen, m, t, version, key, personalization, maxmem, onProgress, asyncTick } = argon2Opts(opts);
|
|
1206
|
+
const keyInput = key;
|
|
1207
|
+
key = rememberOwned(keyInput, abytesOrZero(keyInput, "key"));
|
|
1208
|
+
const personalizationInput = personalization;
|
|
1209
|
+
personalization = rememberOwned(personalizationInput, abytesOrZero(personalizationInput, "personalization"));
|
|
1210
|
+
h = blake2b.create();
|
|
1211
|
+
for (let item of [p, dkLen, m, t, version, type]) {
|
|
1212
|
+
BUF[0] = swap8IfBE(item);
|
|
1213
|
+
h.update(BUF8);
|
|
1214
|
+
}
|
|
1215
|
+
for (let i of [passwordBytes, saltBytes, key, personalization]) {
|
|
1216
|
+
BUF[0] = swap8IfBE(i.length);
|
|
1217
|
+
h.update(BUF8).update(i);
|
|
1218
|
+
}
|
|
1219
|
+
H0 = new Uint32Array(18);
|
|
1220
|
+
h.digestInto(u8(H0));
|
|
1221
|
+
succeeded = true;
|
|
1222
|
+
return { H0, p, dkLen, m, t, version, maxmem, onProgress, asyncTick };
|
|
1223
|
+
} finally {
|
|
1224
|
+
if (h)
|
|
1225
|
+
h.destroy();
|
|
1226
|
+
clean(BUF, ...ownedInputs);
|
|
1227
|
+
if (!succeeded && H0)
|
|
1228
|
+
clean(H0);
|
|
1221
1229
|
}
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1230
|
+
}
|
|
1231
|
+
function argon2Init(password, salt, type, opts) {
|
|
1232
|
+
const { H0, p, dkLen, m, t, version, maxmem, onProgress, asyncTick } = argon2InitialHash(password, salt, type, opts);
|
|
1233
|
+
try {
|
|
1234
|
+
const lanes = p;
|
|
1235
|
+
const mP = 4 * p * Math.floor(m / (ARGON2_SYNC_POINTS * p));
|
|
1236
|
+
const laneLen = Math.floor(mP / p);
|
|
1237
|
+
const segmentLen = Math.floor(laneLen / ARGON2_SYNC_POINTS);
|
|
1238
|
+
const memUsed = mP * 1024;
|
|
1239
|
+
if (!isU32(maxmem))
|
|
1240
|
+
throw new Error('"maxmem" expected <2**32, got ' + maxmem);
|
|
1241
|
+
if (memUsed > maxmem)
|
|
1242
|
+
throw new Error('"maxmem" limit was hit: memUsed(mP*1024)=' + memUsed + ", maxmem=" + maxmem);
|
|
1243
|
+
const B = new Uint32Array(memUsed / 4);
|
|
1244
|
+
for (let l = 0;l < p; l++) {
|
|
1245
|
+
const i = 256 * laneLen * l;
|
|
1246
|
+
H0[17] = swap8IfBE(l);
|
|
1247
|
+
H0[16] = swap8IfBE(0);
|
|
1248
|
+
B.set(swap32IfBE(u32(Hp(H0, 1024))), i);
|
|
1249
|
+
H0[16] = swap8IfBE(1);
|
|
1250
|
+
B.set(swap32IfBE(u32(Hp(H0, 1024))), i + 256);
|
|
1251
|
+
}
|
|
1252
|
+
let perBlock = () => {};
|
|
1253
|
+
if (onProgress) {
|
|
1254
|
+
const totalBlock = t * ARGON2_SYNC_POINTS * p * segmentLen - 2 * p;
|
|
1255
|
+
const callbackPer = Math.max(Math.floor(totalBlock / 1e4), 1);
|
|
1256
|
+
let blockCnt = 0;
|
|
1257
|
+
perBlock = () => {
|
|
1258
|
+
blockCnt++;
|
|
1259
|
+
if (onProgress && (!(blockCnt % callbackPer) || blockCnt === totalBlock))
|
|
1260
|
+
onProgress(blockCnt / totalBlock);
|
|
1261
|
+
};
|
|
1262
|
+
}
|
|
1263
|
+
return { type, mP, p, t, version, B, laneLen, lanes, segmentLen, dkLen, perBlock, asyncTick };
|
|
1264
|
+
} finally {
|
|
1265
|
+
clean(H0);
|
|
1232
1266
|
}
|
|
1233
|
-
clean(BUF, H0);
|
|
1234
|
-
return { type, mP, p, t, version, B, laneLen, lanes, segmentLen, dkLen, perBlock, asyncTick };
|
|
1235
1267
|
}
|
|
1236
1268
|
function argon2Output(B, p, laneLen, dkLen) {
|
|
1237
1269
|
const B_final = new Uint32Array(256);
|
|
@@ -1242,9 +1274,8 @@ function argon2Output(B, p, laneLen, dkLen) {
|
|
|
1242
1274
|
clean(B, B_final);
|
|
1243
1275
|
return res;
|
|
1244
1276
|
}
|
|
1245
|
-
function* argon2Blocks(ctx) {
|
|
1277
|
+
function* argon2Blocks(ctx, address) {
|
|
1246
1278
|
const { type, mP, p, t, version, B, laneLen, lanes, segmentLen, perBlock } = ctx;
|
|
1247
|
-
const address = new Uint32Array(3 * 256);
|
|
1248
1279
|
address[256 + 6] = mP;
|
|
1249
1280
|
address[256 + 8] = t;
|
|
1250
1281
|
address[256 + 10] = type;
|
|
@@ -1298,11 +1329,11 @@ function* argon2Blocks(ctx) {
|
|
|
1298
1329
|
}
|
|
1299
1330
|
function argon2(type, password, salt, opts) {
|
|
1300
1331
|
const ctx = argon2Init(password, salt, type, opts);
|
|
1301
|
-
const blocks = argon2Blocks(ctx);
|
|
1332
|
+
const blocks = argon2Blocks(ctx, new Uint32Array(3 * 256));
|
|
1302
1333
|
while (!blocks.next().done) {}
|
|
1303
1334
|
return argon2Output(ctx.B, ctx.p, ctx.laneLen, ctx.dkLen);
|
|
1304
1335
|
}
|
|
1305
|
-
var argon2id = (password, salt, opts) => argon2(AT.Argon2id, password, salt, opts);
|
|
1336
|
+
var argon2id = (password, salt, opts = {}) => argon2(AT.Argon2id, password, salt, opts);
|
|
1306
1337
|
|
|
1307
1338
|
// src/runtime/kdf-worker-thread.js
|
|
1308
1339
|
if (!parentPort)
|
package/docs/agents.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Use the JavaScript API for a long-running agent and the canonical CLI for one-off shell work. A local read-only MCP resource server can help an MCP-capable host discover the installed SDK documentation, but it cannot operate Veyl.
|
|
4
4
|
|
|
5
|
-
The SDK is not a privileged backend. It authenticates, decrypts the vault, signs wallet operations, encrypts/signs chat actions, and maintains encrypted local cache state exactly like web and iOS.
|
|
5
|
+
The SDK is not a privileged backend. It authenticates, decrypts the vault, signs wallet operations, encrypts/signs chat actions, and maintains encrypted local cache state exactly like web and iOS. A public profile is `sdk` while it is machine-only and becomes `app` if a passkey is linked. That describes its available client surface, not whether a person or agent operates it.
|
|
6
6
|
|
|
7
7
|
## Setup
|
|
8
8
|
|
|
@@ -101,7 +101,7 @@ Agents should correct normal validation errors from their messages. They should
|
|
|
101
101
|
- preserve `operationId`;
|
|
102
102
|
- do not blindly repeat a Spark send, request payment, external invoice payment, or withdrawal;
|
|
103
103
|
- reconcile public wallet history or application state first;
|
|
104
|
-
- retry Lightning only when `retryable === true`, using the exact same `
|
|
104
|
+
- retry Lightning only when `retryable === true`, using `operationId` as the exact same `transferId`.
|
|
105
105
|
|
|
106
106
|
This is intentionally a small contract for the one class of error where automatic self-correction can lose money. Veyl does not maintain a large error taxonomy for ordinary mistakes.
|
|
107
107
|
|
package/docs/api.md
CHANGED
|
@@ -25,6 +25,16 @@ The auth and account compositions consume explicit runtime ports and have no dir
|
|
|
25
25
|
|
|
26
26
|
Most product methods ensure login and vault unlock when saved account and vault keys are available. Long-running callers should explicitly login/unlock once and call `close()` when finished.
|
|
27
27
|
|
|
28
|
+
### Local access and connectivity
|
|
29
|
+
|
|
30
|
+
The shared account owner separates `localReady`, `online`, and `connection` in its snapshot. `localReady` means the exact locally signed-in account has enough encrypted bootstrap data for vault unlock; it is not server authorization. Unlock opens encrypted cached chats and wallet history without waiting for cloud services. Cached balance is display-only and must be labeled last known. `online` becomes true after cloud reads and online proof succeed; reconnect attaches services to the same unlocked session. Text sends wait up to 30 seconds for connectivity, then remain encrypted on-device as failed attempts for manual retry; reactions expire without a retry row. Avatar changes wait only for the current session, as described below. These are domain-owned pending operations, not a general cloud mutation queue. Live wallet readiness remains mandatory for payments.
|
|
31
|
+
|
|
32
|
+
Custom platform hosts may provide `bootstrapStorage.read(uid)`, `write(uid, snapshot)`, and `remove(uid)` to `openAccount`, and call `setInternetAvailable(false | true | null)` with platform reachability. Encrypt bootstrap data under the account/environment-bound install key; never put decrypted private content there. Standard web, iOS and Node adapters supply encrypted storage. Logout or observed revocation removes it.
|
|
33
|
+
|
|
34
|
+
Node authentication is currently process-local: a fresh SDK/CLI process still needs the network to authenticate, even with saved credentials. Cached access supports an already-authenticated long-running SDK process; saved username/profile metadata cannot establish an offline session. Web and iOS can restore their platform-persisted signed-in auth slots.
|
|
35
|
+
|
|
36
|
+
`connection.unavailable` is the shared offline-display signal, separate from account readiness in `connection.status`. Ordinary startup, local service initialization, and brief cache refreshes do not mean offline. Explicit device/cloud blocking and network errors report unavailability immediately; silent required server reads use the existing 15-second deadline. The cloud transport's `availability` port reports `false` when explicitly blocked and `null` when unknown, never treating an allowed test phase as proof of a server connection.
|
|
37
|
+
|
|
28
38
|
## Graphical auth owner
|
|
29
39
|
|
|
30
40
|
```js
|
|
@@ -158,7 +168,9 @@ await account.close();
|
|
|
158
168
|
|
|
159
169
|
`openAccount()` owns authenticated user observation, username and avatar publication, vault observation and creation, vault unlock/lock, encrypted settings/network selection, presence, late wallet readiness, public Bitcoin data, support/report commands, chat and peer/profile composition, account switching, and secret-bearing session teardown. Focused-chat presence is separately owned by the chat session's encrypted ephemeral live transport. The account snapshot exposes `user`, `vault`, `vaultReady`, `vaultError`, `session`, `wallet`, `walletError`, `network`, and `lockState`; `vaultReady` becomes true only after the backend authorizes and confirms the current vault snapshot, while a cached snapshot may warm `vault` without authorizing a guarded route. Stable domain owners such as `bitcoin` and `support` live directly on the returned account owner. Graphical password-change flows call `verifyVaultPasswordForChange(currentPassword)` before revealing the new-password step, then call the atomic `changeVaultPassword({ currentPassword, newPassword })` command. Both are account-bound local decryptions; the first immediately clears its temporary seed, while the second preserves and verifies the existing Vault Signature identity before replacing the authoritative ciphertext.
|
|
160
170
|
|
|
161
|
-
`account.profile` owns the server mutation after a platform has prepared avatar bytes or collected a username. Browser canvas work and native image manipulation remain platform-local; both then call the same `setAvatar`, `clearAvatar`, or `setUsername` command.
|
|
171
|
+
`account.profile` owns the server mutation after a platform has prepared avatar bytes or collected a username. Browser canvas work and native image manipulation remain platform-local; both then call the same `setAvatar`, `clearAvatar`, or `setUsername` command. Avatar selection/removal previews immediately through the shared user snapshot, waits while offline, and publishes once authenticated profile reads recover. Only the latest selection is retained, in memory for this session; lock/close discards unsent work and rejects its promise with `cancelled`. The promise resolves after server acknowledgment and the confirmed bytes/version enter the ordinary avatar cache. No pending avatar is persisted or compared through extra server reads. Username changes still require connectivity.
|
|
172
|
+
|
|
173
|
+
`account.bitcoin` restores the last observed public USD price from `bitcoinPriceStorage` (`read()` / `write({ price, updatedAt })`). The platform port is shared across accounts within the same installation and realm. The snapshot exposes `priceUpdatedAt` and `priceFromCache`; a null observation time means the configured $80,000 default, never a fetched rate. Cache hydration restores price only, not fee estimates or server/wallet readiness. The existing cloud listener refreshes the saved rate without additional requests. Confirmed self/peer avatar bytes similarly hydrate from their exact cached version independently of cloud readiness.
|
|
162
174
|
|
|
163
175
|
`account.peers` is the shared peer-directory owner used by Node, web, and iOS. `openAccount()` supplies its chat, wallet, blocked-user, and encrypted-cache sources directly, including missing-profile chat cleanup. Graphical adapters only subscribe to the same snapshot and profile selectors already defined by core. `openSearch('profiles')` creates profile-only search; web may also use `openSearch('mainmenu')` for its combined local-action and remote-profile menu. Active searches track peer and blocked-user changes and release those subscriptions when cleared or closed.
|
|
164
176
|
|
|
@@ -193,7 +205,7 @@ try {
|
|
|
193
205
|
}
|
|
194
206
|
```
|
|
195
207
|
|
|
196
|
-
An unknown Spark send, payment-request payment, invoice payment, or withdrawal outcome has `retryable: false`. Reconcile wallet transactions or the named operation before deciding what to do; blindly repeating it can spend twice. An unknown Lightning payment is retryable only when the same
|
|
208
|
+
An unknown Spark send, payment-request payment, invoice payment, or withdrawal outcome has `retryable: false`. Reconcile wallet transactions or the named operation before deciding what to do; blindly repeating it can spend twice. An unknown Lightning payment is retryable only when the same `transferId` will be reused. Veyl creates that UUID before the first attempt and returns it as `operationId` on an uncertain outcome. Direct CLI errors and persistent-session transport preserve these fields instead of reducing them to an error string.
|
|
197
209
|
|
|
198
210
|
## Account
|
|
199
211
|
|
|
@@ -214,7 +226,7 @@ await veyl.account.logoutAll();
|
|
|
214
226
|
await veyl.account.delete({ confirm: true });
|
|
215
227
|
```
|
|
216
228
|
|
|
217
|
-
- `create` makes an
|
|
229
|
+
- `create` makes an account authenticated by a local machine credential, publishes its account type as `sdk`, and returns its account key directly.
|
|
218
230
|
- `createPasskey({ username, webUrl, onUrl })` creates a normal passkey account through a browser-assisted WebAuthn flow, installs a local machine credential for future CLI sessions, and returns that account key directly.
|
|
219
231
|
- `login({ username?, key?, saveKey? })` authenticates with an account key. The key can instead come from `open({ accountKey })` or `VEYL_ACCOUNT_KEY`.
|
|
220
232
|
- `loginPasskey({ username?, webUrl?, onUrl? })` authenticates through the browser-assisted passkey flow.
|
|
@@ -225,7 +237,7 @@ await veyl.account.delete({ confirm: true });
|
|
|
225
237
|
- `logoutAll` revokes every product session generation, tears down this runtime locally, and stops a persistent CLI owner after its in-flight work drains.
|
|
226
238
|
- `delete({ confirm: true, key? })` drains decryptable inbox state, marks all discoverable chats deleted, destroys the complete account/network encrypted cache scope, proves vault possession inside the same destructive operation, deletes identifiable account data, removes the local profile, and stops a persistent CLI owner after its in-flight work drains. `key` is required only when the runtime has no saved vault key.
|
|
227
239
|
|
|
228
|
-
Account summaries report identity, network, local credential/vault availability, public wallet/chat keys, auth kind,
|
|
240
|
+
Account summaries report identity, network, local credential/vault availability, public wallet/chat keys, auth kind, public `app` or `sdk` account type, and current signed-in/unlocked state. Linking a passkey promotes the type to `app`; account and vault keys are never included in summaries.
|
|
229
241
|
|
|
230
242
|
## Vault
|
|
231
243
|
|
|
@@ -242,6 +254,9 @@ Vault creation returns the vault key directly. That key unlocks the vault and ev
|
|
|
242
254
|
|
|
243
255
|
```js
|
|
244
256
|
await veyl.profile.show();
|
|
257
|
+
await veyl.profile.getPresence({ timeoutMs: 15_000 });
|
|
258
|
+
await veyl.profile.setPresenceVisibility('private'); // appear offline on every account device
|
|
259
|
+
await veyl.profile.setPresenceVisibility('public'); // share online status and last active
|
|
245
260
|
await veyl.profile.uploadAvatar(webpBytes);
|
|
246
261
|
await veyl.profile.deleteAvatar();
|
|
247
262
|
await veyl.profile.setChatAdmission({
|
|
@@ -257,10 +272,12 @@ await veyl.cache.show();
|
|
|
257
272
|
await veyl.cache.clear();
|
|
258
273
|
```
|
|
259
274
|
|
|
260
|
-
`uploadAvatar` accepts prepared WebP bytes and uses the shared profile/avatar backend owner. `setChatAdmission` publishes a public `direct` mode (`open`, `requests`, or `closed`), a `groups` mode (`open` or `closed`), and a fixed-size padded set of private pair-capability commitments for up to eight allowed direct peers. Allowed peers may be usernames or public chat keys; their identities are resolved locally and are not published in the policy. Missing policies remain open for ordinary accounts, while malformed present policies fail closed. Existing chats
|
|
275
|
+
`uploadAvatar` accepts prepared WebP bytes and uses the shared profile/avatar backend owner. `setChatAdmission` publishes a public `direct` mode (`open`, `requests`, or `closed`), a `groups` mode (`open` or `closed`), and a fixed-size padded set of private pair-capability commitments for up to eight allowed direct peers. Allowed peers may be usernames or public chat keys; their identities are resolved locally and are not published in the policy. Missing policies remain open for ordinary accounts, while malformed present policies fail closed. Existing membership does not bypass a closed policy: disallowed chats are hidden and unavailable for admission-controlled actions, but policy changes never delete a direct or leave a group. `groups: closed` also prevents new group membership.
|
|
261
276
|
|
|
262
277
|
Settings use the shared normalization and encrypted settings document. Changing `walletNetwork` locks the current vault so the next unlock boots the selected network. Cache methods operate on the same vault-encrypted display and media cache as the other clients.
|
|
263
278
|
|
|
279
|
+
Presence visibility is an independent account-wide relay policy, not an encrypted settings field. `getPresence` waits for the acknowledged policy and returns `{ visibility, pending, error, availability, status, lastActiveAt }`. `setPresenceVisibility` accepts only `public` or `private` and resolves after the shared presence owner confirms the revisioned change; connection, conflict, and timeout errors reject explicitly. An unloaded policy never implies public visibility. The matching CLI commands are `veyl profile presence` and `veyl profile presence-set <public|private>`.
|
|
280
|
+
|
|
264
281
|
## Peers
|
|
265
282
|
|
|
266
283
|
```js
|
|
@@ -272,7 +289,9 @@ await veyl.peers.block('@alice');
|
|
|
272
289
|
await veyl.peers.unblock('@alice');
|
|
273
290
|
```
|
|
274
291
|
|
|
275
|
-
Peer resolution accepts `@username`, username, chat public key, or wallet public key when the operation supports it. Blocking self is rejected. Peer/profile results are public projections and do not expose local cache internals. `peers.show` authoritatively refreshes a cached identity; a confirmed missing profile evicts it and deletes loaded chats through the shared missing-peer owner. Normal chat/wallet actions keep the shared cached fast path, while their server-side operations still validate the authoritative route they mutate.
|
|
292
|
+
Peer resolution accepts `@username`, username, chat public key, or wallet public key when the operation supports it. Blocking self is rejected. A block independently submits a narrow user report, retires every private chat route containing that peer, and returns `reported` separately from `blocked`; report failure never prevents the block. Peer/profile results are public projections and do not expose local cache internals. `peers.show` authoritatively refreshes a cached identity; a confirmed missing profile evicts it and deletes loaded chats through the shared missing-peer owner. Normal chat/wallet actions keep the shared cached fast path, while their server-side operations still validate the authoritative route they mutate.
|
|
293
|
+
|
|
294
|
+
Profile and peer results include `presence: { availability, status, lastActiveAt }`; `active` is derived only from `availability === 'online'`, never from a stored profile flag. Availability is `unknown`, `online`, or `offline`; unknown/private/unobserved peers must not be presented as confirmed offline. Last-active timestamps are coarse buckets, not exact interaction times. Presence reflects the current bounded observation set; `@active` / `@online` search filters observed local peers rather than querying a global directory of online users.
|
|
276
295
|
|
|
277
296
|
## Chat
|
|
278
297
|
|
|
@@ -326,7 +345,7 @@ await veyl.chat.react('@alice', sent.message.id, '+1');
|
|
|
326
345
|
await veyl.chat.unreact('@alice', sent.message.id);
|
|
327
346
|
await veyl.chat.save('@alice', sent.message.id);
|
|
328
347
|
await veyl.chat.unsave('@alice', sent.message.id);
|
|
329
|
-
await veyl.chat.update('@alice', sent.message.id, 'edited');
|
|
348
|
+
await veyl.chat.update('@alice', sent.message.id, 'edited'); // own text, strictly within 10 minutes
|
|
330
349
|
await veyl.chat.delete('@alice', sent.message.id);
|
|
331
350
|
await veyl.chat.retention('@alice', '24h');
|
|
332
351
|
await veyl.chat.deleteChat('@alice', { cleanup: true });
|
|
@@ -419,7 +438,7 @@ await veyl.lightning.quote(invoice.encodedInvoice, { amountSats: 10 });
|
|
|
419
438
|
await veyl.lightning.pay(invoice.encodedInvoice, {
|
|
420
439
|
amountSats: 10,
|
|
421
440
|
maxFeeSats: 5,
|
|
422
|
-
|
|
441
|
+
transferId: '019c0000-0000-7000-8000-000000000001',
|
|
423
442
|
});
|
|
424
443
|
await veyl.lightning.receive(receiveId);
|
|
425
444
|
await veyl.lightning.send(sendId);
|
|
@@ -552,7 +571,7 @@ Losing the root loses every derived account. Back it up as carefully as a wallet
|
|
|
552
571
|
|
|
553
572
|
An existing account cannot retroactively acquire a derived master seed. Adopting one requires a one-time authenticated handoff that installs its root-derived account key and encrypts the existing master seed under its root-derived vault key without changing wallet/chat material.
|
|
554
573
|
|
|
555
|
-
The
|
|
574
|
+
The Veyl namespace seed is separate from a fleet root. `veyl namespace init` creates that owner-only local key once. When its default file exists under the fleet `homeDir`, provisioning automatically signs a short-lived claim bound to the exact derived machine credential so a reserved canonical username can use the normal public account-creation transaction. The seed is never stored in the manifest or an account profile. Other fleet operators do not have this key and cannot claim the reserved namespace.
|
|
556
575
|
|
|
557
576
|
The owner opens one ordinary public client per enabled ready profile, runs account boots with bounded concurrency, tags events with their manifest account, preserves per-account policy order, fails visibly on backlog overflow, and closes every client on stop. An owner-only PID lock prevents two local processes from operating the fleet. It reclaims a dead same-host PID after a crash but never signals or replaces a healthy owner. Shared owners still control chat ordering, wallet serialization, encryption, cache, and account revocation.
|
|
558
577
|
|