@opendatalabs/personal-server-ts-lite 1.33.8 → 1.34.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.
Files changed (51) hide show
  1. package/dist/additions-crypto.d.ts +3 -0
  2. package/dist/additions-crypto.d.ts.map +1 -0
  3. package/dist/additions-crypto.js +32 -0
  4. package/dist/additions-crypto.js.map +1 -0
  5. package/dist/additions-protocol.d.ts +48 -0
  6. package/dist/additions-protocol.d.ts.map +1 -0
  7. package/dist/additions-protocol.js +17 -0
  8. package/dist/additions-protocol.js.map +1 -0
  9. package/dist/additions-session.d.ts +18 -0
  10. package/dist/additions-session.d.ts.map +1 -0
  11. package/dist/additions-session.js +190 -0
  12. package/dist/additions-session.js.map +1 -0
  13. package/dist/additions-transport.d.ts +64 -0
  14. package/dist/additions-transport.d.ts.map +1 -0
  15. package/dist/additions-transport.js +333 -0
  16. package/dist/additions-transport.js.map +1 -0
  17. package/dist/additions-worker.bundle.js +30615 -0
  18. package/dist/additions-worker.d.ts +2 -0
  19. package/dist/additions-worker.d.ts.map +1 -0
  20. package/dist/additions-worker.js +259 -0
  21. package/dist/additions-worker.js.map +1 -0
  22. package/dist/browser-runtime.d.ts +2 -1
  23. package/dist/browser-runtime.d.ts.map +1 -1
  24. package/dist/browser-runtime.js +5 -1
  25. package/dist/browser-runtime.js.map +1 -1
  26. package/dist/index.d.ts +1 -1
  27. package/dist/index.d.ts.map +1 -1
  28. package/dist/index.js.map +1 -1
  29. package/dist/relay-tls.d.ts.map +1 -1
  30. package/dist/relay-tls.js +10 -0
  31. package/dist/relay-tls.js.map +1 -1
  32. package/dist/relay.d.ts +2 -2
  33. package/dist/relay.d.ts.map +1 -1
  34. package/dist/relay.js +114 -54
  35. package/dist/relay.js.map +1 -1
  36. package/dist/runtime.d.ts +2 -0
  37. package/dist/runtime.d.ts.map +1 -1
  38. package/dist/runtime.js +1 -0
  39. package/dist/runtime.js.map +1 -1
  40. package/dist/state.d.ts +8 -1
  41. package/dist/state.d.ts.map +1 -1
  42. package/dist/state.js +84 -20
  43. package/dist/state.js.map +1 -1
  44. package/dist/storage-utils.d.ts.map +1 -1
  45. package/dist/storage-utils.js +10 -2
  46. package/dist/storage-utils.js.map +1 -1
  47. package/dist/sync.d.ts +8 -1
  48. package/dist/sync.d.ts.map +1 -1
  49. package/dist/sync.js +53 -3
  50. package/dist/sync.js.map +1 -1
  51. package/package.json +8 -5
@@ -0,0 +1,3 @@
1
+ import type { ByteBudget } from "@opendatalabs/personal-server-ts-core/additions";
2
+ export declare function decryptBoundedAdditions(encrypted: Uint8Array, password: string, budget: ByteBudget): Promise<Uint8Array>;
3
+ //# sourceMappingURL=additions-crypto.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"additions-crypto.d.ts","sourceRoot":"","sources":["../src/additions-crypto.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iDAAiD,CAAC;AAalF,wBAAsB,uBAAuB,CAC3C,SAAS,EAAE,UAAU,EACrB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,UAAU,GACjB,OAAO,CAAC,UAAU,CAAC,CAqBrB"}
@@ -0,0 +1,32 @@
1
+ import { CompressedDataPacket, decrypt, readMessage } from "openpgp";
2
+ /** OpenPGP 6.3 constructs this replacement for tag 8 before calling read.
3
+ * Reject here: maxDecompressedMessageSize alone runs after decompression starts.
4
+ */
5
+ class RejectedCompressedPacket extends CompressedDataPacket {
6
+ async read() {
7
+ throw new Error("Compressed OpenPGP packets are unsupported in bounded recovery");
8
+ }
9
+ }
10
+ export async function decryptBoundedAdditions(encrypted, password, budget) {
11
+ budget.charge(encrypted.byteLength * 4);
12
+ const config = {
13
+ additionalAllowedPackets: [RejectedCompressedPacket],
14
+ maxDecompressedMessageSize: 0,
15
+ ignoreUnsupportedPackets: false,
16
+ ignoreMalformedPackets: false,
17
+ };
18
+ const message = await readMessage({ binaryMessage: encrypted, config });
19
+ const result = await decrypt({
20
+ message,
21
+ passwords: [password],
22
+ format: "binary",
23
+ config,
24
+ });
25
+ budget.charge();
26
+ if (!(result.data instanceof Uint8Array))
27
+ throw new Error("Unexpected OpenPGP stream");
28
+ if (result.data.byteLength > budget.remaining)
29
+ budget.charge(budget.remaining + 1);
30
+ return result.data;
31
+ }
32
+ //# sourceMappingURL=additions-crypto.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"additions-crypto.js","sourceRoot":"","sources":["../src/additions-crypto.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAGrE;;GAEG;AACH,MAAM,wBAAyB,SAAQ,oBAAoB;IAChD,KAAK,CAAC,IAAI;QACjB,MAAM,IAAI,KAAK,CACb,gEAAgE,CACjE,CAAC;IACJ,CAAC;CACF;AAED,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,SAAqB,EACrB,QAAgB,EAChB,MAAkB;IAElB,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC;IACxC,MAAM,MAAM,GAAG;QACb,wBAAwB,EAAE,CAAC,wBAAwB,CAAC;QACpD,0BAA0B,EAAE,CAAC;QAC7B,wBAAwB,EAAE,KAAK;QAC/B,sBAAsB,EAAE,KAAK;KAC9B,CAAC;IACF,MAAM,OAAO,GAAG,MAAM,WAAW,CAAC,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC,CAAC;IACxE,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC;QAC3B,OAAO;QACP,SAAS,EAAE,CAAC,QAAQ,CAAC;QACrB,MAAM,EAAE,QAAQ;QAChB,MAAM;KACP,CAAC,CAAC;IACH,MAAM,CAAC,MAAM,EAAE,CAAC;IAChB,IAAI,CAAC,CAAC,MAAM,CAAC,IAAI,YAAY,UAAU,CAAC;QACtC,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;IAC/C,IAAI,MAAM,CAAC,IAAI,CAAC,UAAU,GAAG,MAAM,CAAC,SAAS;QAC3C,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC;IACtC,OAAO,MAAM,CAAC,IAAI,CAAC;AACrB,CAAC"}
@@ -0,0 +1,48 @@
1
+ import type { DurableAdditionsService } from "@opendatalabs/personal-server-ts-core/additions";
2
+ import type { PsLiteAdditionsTransport } from "./additions-transport.js";
3
+ export interface AdditionsWorkerInit {
4
+ ownerAddress: string;
5
+ network: string;
6
+ gatewayUrl: string;
7
+ storageEndpoint: string;
8
+ masterKey: Uint8Array;
9
+ byteBudget: number;
10
+ timeBudgetMs: number;
11
+ }
12
+ export type AdditionsOperation = {
13
+ method: "summarize";
14
+ args: Parameters<DurableAdditionsService["summarize"]>;
15
+ } | {
16
+ method: "recordUpload";
17
+ scope: string;
18
+ };
19
+ export type HostMethod = Exclude<keyof PsLiteAdditionsTransport, "openSession">;
20
+ export type WorkerMessage = {
21
+ kind: "run";
22
+ init: AdditionsWorkerInit;
23
+ operation: AdditionsOperation;
24
+ } | {
25
+ kind: "response";
26
+ id: number;
27
+ result?: unknown;
28
+ error?: string;
29
+ spent: number;
30
+ budgetExceeded?: boolean;
31
+ };
32
+ export type HostMessage = {
33
+ kind: "request";
34
+ id: number;
35
+ method: HostMethod;
36
+ args: unknown[];
37
+ remaining: number;
38
+ remainingMilliseconds?: number;
39
+ } | {
40
+ kind: "result";
41
+ result: unknown;
42
+ } | {
43
+ kind: "error";
44
+ error: string;
45
+ };
46
+ /** Transfer binary payloads across the dedicated worker channel without cloning. */
47
+ export declare function additionsTransfers(value: unknown): Transferable[];
48
+ //# sourceMappingURL=additions-protocol.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"additions-protocol.d.ts","sourceRoot":"","sources":["../src/additions-protocol.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,iDAAiD,CAAC;AAC/F,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,0BAA0B,CAAC;AAEzE,MAAM,WAAW,mBAAmB;IAClC,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;IACxB,SAAS,EAAE,UAAU,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;CACtB;AACD,MAAM,MAAM,kBAAkB,GAC1B;IACE,MAAM,EAAE,WAAW,CAAC;IACpB,IAAI,EAAE,UAAU,CAAC,uBAAuB,CAAC,WAAW,CAAC,CAAC,CAAC;CACxD,GACD;IAAE,MAAM,EAAE,cAAc,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAC9C,MAAM,MAAM,UAAU,GAAG,OAAO,CAAC,MAAM,wBAAwB,EAAE,aAAa,CAAC,CAAC;AAChF,MAAM,MAAM,aAAa,GACrB;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,IAAI,EAAE,mBAAmB,CAAC;IAAC,SAAS,EAAE,kBAAkB,CAAA;CAAE,GACzE;IACE,IAAI,EAAE,UAAU,CAAC;IACjB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B,CAAC;AACN,MAAM,MAAM,WAAW,GACnB;IACE,IAAI,EAAE,SAAS,CAAC;IAChB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,UAAU,CAAC;IACnB,IAAI,EAAE,OAAO,EAAE,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,qBAAqB,CAAC,EAAE,MAAM,CAAC;CAChC,GACD;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,MAAM,EAAE,OAAO,CAAA;CAAE,GACnC;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAErC,oFAAoF;AACpF,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,YAAY,EAAE,CAYjE"}
@@ -0,0 +1,17 @@
1
+ /** Transfer binary payloads across the dedicated worker channel without cloning. */
2
+ export function additionsTransfers(value) {
3
+ const buffers = new Set();
4
+ function visit(item) {
5
+ if (item instanceof Uint8Array && item.buffer instanceof ArrayBuffer)
6
+ buffers.add(item.buffer);
7
+ else if (item instanceof ArrayBuffer)
8
+ buffers.add(item);
9
+ else if (Array.isArray(item))
10
+ item.forEach(visit);
11
+ else if (item && typeof item === "object")
12
+ Object.values(item).forEach(visit);
13
+ }
14
+ visit(value);
15
+ return [...buffers];
16
+ }
17
+ //# sourceMappingURL=additions-protocol.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"additions-protocol.js","sourceRoot":"","sources":["../src/additions-protocol.ts"],"names":[],"mappings":"AAyCA,oFAAoF;AACpF,MAAM,UAAU,kBAAkB,CAAC,KAAc;IAC/C,MAAM,OAAO,GAAG,IAAI,GAAG,EAAe,CAAC;IACvC,SAAS,KAAK,CAAC,IAAa;QAC1B,IAAI,IAAI,YAAY,UAAU,IAAI,IAAI,CAAC,MAAM,YAAY,WAAW;YAClE,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;aACtB,IAAI,IAAI,YAAY,WAAW;YAAE,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;aACnD,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC;YAAE,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;aAC7C,IAAI,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ;YACvC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IACvC,CAAC;IACD,KAAK,CAAC,KAAK,CAAC,CAAC;IACb,OAAO,CAAC,GAAG,OAAO,CAAC,CAAC;AACtB,CAAC"}
@@ -0,0 +1,18 @@
1
+ import { type DurableAdditionsService } from "@opendatalabs/personal-server-ts-core/additions";
2
+ import type { AdditionsWorkerInit, HostMessage, WorkerMessage } from "./additions-protocol.js";
3
+ import type { PsLiteAdditionsTransport } from "./additions-transport.js";
4
+ export interface AdditionsWorkerPort {
5
+ postMessage(message: WorkerMessage, transfer?: Transferable[]): void;
6
+ terminate(): void;
7
+ onmessage: ((event: MessageEvent<HostMessage>) => void) | null;
8
+ onerror: ((event: ErrorEvent) => void) | null;
9
+ }
10
+ export interface PsLiteAdditionsSessionOptions {
11
+ init: AdditionsWorkerInit;
12
+ transport: PsLiteAdditionsTransport;
13
+ deleteSystemScope(scope: string): Promise<void>;
14
+ /** Bundlers may supply their own URL/factory; no synchronous fallback exists. */
15
+ workerFactory?: () => AdditionsWorkerPort;
16
+ }
17
+ export declare function createPsLiteAdditionsSession(options: PsLiteAdditionsSessionOptions): DurableAdditionsService;
18
+ //# sourceMappingURL=additions-session.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"additions-session.d.ts","sourceRoot":"","sources":["../src/additions-session.ts"],"names":[],"mappings":"AAAA,OAAO,EAML,KAAK,uBAAuB,EAC7B,MAAM,iDAAiD,CAAC;AAEzD,OAAO,KAAK,EAEV,mBAAmB,EACnB,WAAW,EACX,aAAa,EACd,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,0BAA0B,CAAC;AAEzE,MAAM,WAAW,mBAAmB;IAClC,WAAW,CAAC,OAAO,EAAE,aAAa,EAAE,QAAQ,CAAC,EAAE,YAAY,EAAE,GAAG,IAAI,CAAC;IACrE,SAAS,IAAI,IAAI,CAAC;IAClB,SAAS,EAAE,CAAC,CAAC,KAAK,EAAE,YAAY,CAAC,WAAW,CAAC,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC;IAC/D,OAAO,EAAE,CAAC,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC;CAC/C;AACD,MAAM,WAAW,6BAA6B;IAC5C,IAAI,EAAE,mBAAmB,CAAC;IAC1B,SAAS,EAAE,wBAAwB,CAAC;IACpC,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAChD,iFAAiF;IACjF,aAAa,CAAC,EAAE,MAAM,mBAAmB,CAAC;CAC3C;AAED,wBAAgB,4BAA4B,CAC1C,OAAO,EAAE,6BAA6B,GACrC,uBAAuB,CAwOzB"}
@@ -0,0 +1,190 @@
1
+ import { AdditionsBudget, AdditionsBudgetExceeded, additionsLedgerScope, ADDITIONS_SUMMARY_SCOPE, summarizeAdditions, } from "@opendatalabs/personal-server-ts-core/additions";
2
+ import { additionsTransfers } from "./additions-protocol.js";
3
+ export function createPsLiteAdditionsSession(options) {
4
+ async function run(operation) {
5
+ const started = performance.now();
6
+ if (typeof navigator === "undefined" || !navigator.locks)
7
+ throw new Error("Bounded additions requires browser locks for persisted publication");
8
+ const signal = AbortSignal.timeout(options.init.timeBudgetMs);
9
+ // Web Locks span tabs and survive worker restarts without a stale lease.
10
+ return navigator.locks.request(JSON.stringify([
11
+ "ps-lite.additions.v1",
12
+ options.init.ownerAddress.toLowerCase(),
13
+ options.init.network,
14
+ ]), { mode: "exclusive", signal }, async () => {
15
+ signal.throwIfAborted();
16
+ const remainingMs = Math.max(1, Math.floor(options.init.timeBudgetMs - (performance.now() - started)));
17
+ return runLocked(operation, remainingMs);
18
+ });
19
+ }
20
+ async function runLocked(operation, remainingMs) {
21
+ const controller = new AbortController();
22
+ const transport = options.transport.openSession();
23
+ const worker = options.workerFactory?.() ??
24
+ new Worker(new URL("./additions-worker.bundle.js", import.meta.url), {
25
+ type: "module",
26
+ });
27
+ const active = new Set();
28
+ let timer;
29
+ try {
30
+ return await new Promise((resolve, reject) => {
31
+ let finished = false;
32
+ const finish = (error, value) => {
33
+ if (finished)
34
+ return;
35
+ finished = true;
36
+ controller.abort(error ?? new Error("Additions session complete"));
37
+ worker.terminate();
38
+ void Promise.allSettled([...active]).then(() => error ? reject(error) : resolve(value));
39
+ };
40
+ timer = setTimeout(() => finish(new Error("Additions worker deadline exceeded")), remainingMs);
41
+ worker.onerror = (event) => finish(new Error(event.message || "Additions worker failed"));
42
+ worker.onmessage = (event) => {
43
+ if (finished)
44
+ return;
45
+ const message = event.data;
46
+ if (message.kind === "result") {
47
+ finish(undefined, message.result);
48
+ return;
49
+ }
50
+ if (message.kind === "error") {
51
+ finish(new Error(message.error));
52
+ return;
53
+ }
54
+ const task = (async () => {
55
+ const budget = new AdditionsBudget(message.remaining, message.remainingMilliseconds === undefined ||
56
+ !Number.isFinite(message.remainingMilliseconds)
57
+ ? undefined
58
+ : Math.max(0, Math.floor(message.remainingMilliseconds)), controller.signal);
59
+ try {
60
+ const hostBudget = {
61
+ signal: budget.signal,
62
+ get remaining() {
63
+ return budget.remaining;
64
+ },
65
+ recordSpent(bytes) {
66
+ budget.recordSpent(bytes);
67
+ },
68
+ charge(bytes = 0) {
69
+ budget.signal?.throwIfAborted();
70
+ budget.charge(bytes);
71
+ },
72
+ };
73
+ // This channel is private to the worker created above. Network
74
+ // responses are validated in that worker, never trusted as JSON.
75
+ const args = message.args;
76
+ let result;
77
+ switch (message.method) {
78
+ case "fetch":
79
+ result = await transport.fetch(args[0], hostBudget);
80
+ break;
81
+ case "download":
82
+ result = await transport.download(args[0], hostBudget);
83
+ break;
84
+ case "signRequest":
85
+ result = await transport.signRequest(args[0], budget.signal);
86
+ break;
87
+ case "publish":
88
+ result = await transport.publish(args[0], hostBudget);
89
+ break;
90
+ case "readPending":
91
+ result = await transport.readPending(args[0], hostBudget);
92
+ break;
93
+ case "clearPending":
94
+ result = await transport.clearPending(args[0], hostBudget);
95
+ break;
96
+ }
97
+ if (!finished)
98
+ worker.postMessage({
99
+ kind: "response",
100
+ id: message.id,
101
+ result,
102
+ spent: message.remaining - budget.remaining,
103
+ }, additionsTransfers(result));
104
+ }
105
+ catch (error) {
106
+ if (!finished)
107
+ worker.postMessage({
108
+ kind: "response",
109
+ id: message.id,
110
+ error: error instanceof Error ? error.message : String(error),
111
+ budgetExceeded: error instanceof AdditionsBudgetExceeded ||
112
+ budget.signal?.aborted,
113
+ spent: message.remaining - budget.remaining,
114
+ });
115
+ }
116
+ })();
117
+ active.add(task);
118
+ void task.finally(() => active.delete(task));
119
+ };
120
+ worker.postMessage({
121
+ kind: "run",
122
+ init: { ...options.init, timeBudgetMs: remainingMs },
123
+ operation,
124
+ });
125
+ });
126
+ }
127
+ finally {
128
+ if (timer !== undefined)
129
+ clearTimeout(timer);
130
+ controller.abort();
131
+ worker.terminate();
132
+ await Promise.allSettled([...active]);
133
+ }
134
+ }
135
+ return {
136
+ async summarize(input) {
137
+ try {
138
+ return (await run({ method: "summarize", args: [input] }));
139
+ }
140
+ catch {
141
+ return summarizeAdditions({
142
+ ...input,
143
+ ledgers: [],
144
+ coverage: "behind",
145
+ });
146
+ }
147
+ },
148
+ async recordUpload(version) {
149
+ if (version.scope.startsWith("vana.system."))
150
+ return;
151
+ // Upload bodies already belong to sync. Recovery reads bounded committed
152
+ // blobs instead of cloning an arbitrarily large upload into the worker.
153
+ try {
154
+ await run({ method: "recordUpload", scope: version.scope });
155
+ }
156
+ catch {
157
+ /* The next read retries authoritative recovery. */
158
+ }
159
+ },
160
+ async deleteScope(scope, deletion) {
161
+ if (scope.startsWith("vana.system."))
162
+ return;
163
+ if (typeof navigator === "undefined" || !navigator.locks)
164
+ throw new Error("Durable additions deletion requires browser locks");
165
+ // Explicit durable deletion belongs to the ordinary sync pipeline and
166
+ // has no bounded-recovery deadline or noncancelable worker RPC.
167
+ const budget = deletion?.durableOnly
168
+ ? new AdditionsBudget(options.init.byteBudget, options.init.timeBudgetMs, deletion.signal)
169
+ : undefined;
170
+ await navigator.locks.request(JSON.stringify([
171
+ "ps-lite.additions.v1",
172
+ options.init.ownerAddress.toLowerCase(),
173
+ options.init.network,
174
+ ]), { mode: "exclusive", signal: budget?.signal }, async () => {
175
+ if (budget) {
176
+ await options.transport.deleteScope(scope, budget);
177
+ return;
178
+ }
179
+ for (const target of [
180
+ additionsLedgerScope(scope),
181
+ ADDITIONS_SUMMARY_SCOPE,
182
+ ]) {
183
+ await options.deleteSystemScope(target);
184
+ await options.transport.clearPending(target, new AdditionsBudget());
185
+ }
186
+ });
187
+ },
188
+ };
189
+ }
190
+ //# sourceMappingURL=additions-session.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"additions-session.js","sourceRoot":"","sources":["../src/additions-session.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,uBAAuB,EACvB,oBAAoB,EACpB,uBAAuB,EACvB,kBAAkB,GAEnB,MAAM,iDAAiD,CAAC;AACzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAuB7D,MAAM,UAAU,4BAA4B,CAC1C,OAAsC;IAEtC,KAAK,UAAU,GAAG,CAAC,SAA6B;QAC9C,MAAM,OAAO,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;QAClC,IAAI,OAAO,SAAS,KAAK,WAAW,IAAI,CAAC,SAAS,CAAC,KAAK;YACtD,MAAM,IAAI,KAAK,CACb,oEAAoE,CACrE,CAAC;QACJ,MAAM,MAAM,GAAG,WAAW,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAC9D,yEAAyE;QACzE,OAAO,SAAS,CAAC,KAAK,CAAC,OAAO,CAC5B,IAAI,CAAC,SAAS,CAAC;YACb,sBAAsB;YACtB,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,WAAW,EAAE;YACvC,OAAO,CAAC,IAAI,CAAC,OAAO;SACrB,CAAC,EACF,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,EAC7B,KAAK,IAAI,EAAE;YACT,MAAM,CAAC,cAAc,EAAE,CAAC;YACxB,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,CAC1B,CAAC,EACD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,YAAY,GAAG,CAAC,WAAW,CAAC,GAAG,EAAE,GAAG,OAAO,CAAC,CAAC,CACtE,CAAC;YACF,OAAO,SAAS,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;QAC3C,CAAC,CACF,CAAC;IACJ,CAAC;IACD,KAAK,UAAU,SAAS,CACtB,SAA6B,EAC7B,WAAmB;QAEnB,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;QACzC,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC,WAAW,EAAE,CAAC;QAClD,MAAM,MAAM,GACV,OAAO,CAAC,aAAa,EAAE,EAAE;YACzB,IAAI,MAAM,CAAC,IAAI,GAAG,CAAC,8BAA8B,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE;gBACnE,IAAI,EAAE,QAAQ;aACf,CAAC,CAAC;QACL,MAAM,MAAM,GAAG,IAAI,GAAG,EAAiB,CAAC;QACxC,IAAI,KAAgD,CAAC;QACrD,IAAI,CAAC;YACH,OAAO,MAAM,IAAI,OAAO,CAAU,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;gBACpD,IAAI,QAAQ,GAAG,KAAK,CAAC;gBACrB,MAAM,MAAM,GAAG,CAAC,KAAa,EAAE,KAAe,EAAE,EAAE;oBAChD,IAAI,QAAQ;wBAAE,OAAO;oBACrB,QAAQ,GAAG,IAAI,CAAC;oBAChB,UAAU,CAAC,KAAK,CAAC,KAAK,IAAI,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC,CAAC;oBACnE,MAAM,CAAC,SAAS,EAAE,CAAC;oBACnB,KAAK,OAAO,CAAC,UAAU,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAC7C,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CACvC,CAAC;gBACJ,CAAC,CAAC;gBACF,KAAK,GAAG,UAAU,CAChB,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC,EAC7D,WAAW,CACZ,CAAC;gBACF,MAAM,CAAC,OAAO,GAAG,CAAC,KAAK,EAAE,EAAE,CACzB,MAAM,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,OAAO,IAAI,yBAAyB,CAAC,CAAC,CAAC;gBAChE,MAAM,CAAC,SAAS,GAAG,CAAC,KAAK,EAAE,EAAE;oBAC3B,IAAI,QAAQ;wBAAE,OAAO;oBACrB,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC;oBAC3B,IAAI,OAAO,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;wBAC9B,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;wBAClC,OAAO;oBACT,CAAC;oBACD,IAAI,OAAO,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;wBAC7B,MAAM,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;wBACjC,OAAO;oBACT,CAAC;oBACD,MAAM,IAAI,GAAG,CAAC,KAAK,IAAI,EAAE;wBACvB,MAAM,MAAM,GAAG,IAAI,eAAe,CAChC,OAAO,CAAC,SAAS,EACjB,OAAO,CAAC,qBAAqB,KAAK,SAAS;4BACzC,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,qBAAqB,CAAC;4BAC/C,CAAC,CAAC,SAAS;4BACX,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,qBAAqB,CAAC,CAAC,EAC1D,UAAU,CAAC,MAAM,CAClB,CAAC;wBACF,IAAI,CAAC;4BACH,MAAM,UAAU,GAAG;gCACjB,MAAM,EAAE,MAAM,CAAC,MAAM;gCACrB,IAAI,SAAS;oCACX,OAAO,MAAM,CAAC,SAAS,CAAC;gCAC1B,CAAC;gCACD,WAAW,CAAC,KAAa;oCACvB,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;gCAC5B,CAAC;gCACD,MAAM,CAAC,KAAK,GAAG,CAAC;oCACd,MAAM,CAAC,MAAM,EAAE,cAAc,EAAE,CAAC;oCAChC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;gCACvB,CAAC;6BACF,CAAC;4BACF,+DAA+D;4BAC/D,iEAAiE;4BACjE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;4BAC1B,IAAI,MAAe,CAAC;4BACpB,QAAQ,OAAO,CAAC,MAAM,EAAE,CAAC;gCACvB,KAAK,OAAO;oCACV,MAAM,GAAG,MAAM,SAAS,CAAC,KAAK,CAC5B,IAAI,CAAC,CAAC,CAA0C,EAChD,UAAU,CACX,CAAC;oCACF,MAAM;gCACR,KAAK,UAAU;oCACb,MAAM,GAAG,MAAM,SAAS,CAAC,QAAQ,CAC/B,IAAI,CAAC,CAAC,CAAW,EACjB,UAAU,CACX,CAAC;oCACF,MAAM;gCACR,KAAK,aAAa;oCAChB,MAAM,GAAG,MAAM,SAAS,CAAC,WAAW,CAClC,IAAI,CAAC,CAAC,CAAgD,EACtD,MAAM,CAAC,MAAM,CACd,CAAC;oCACF,MAAM;gCACR,KAAK,SAAS;oCACZ,MAAM,GAAG,MAAM,SAAS,CAAC,OAAO,CAC9B,IAAI,CAAC,CAAC,CAA4C,EAClD,UAAU,CACX,CAAC;oCACF,MAAM;gCACR,KAAK,aAAa;oCAChB,MAAM,GAAG,MAAM,SAAS,CAAC,WAAW,CAClC,IAAI,CAAC,CAAC,CAAW,EACjB,UAAU,CACX,CAAC;oCACF,MAAM;gCACR,KAAK,cAAc;oCACjB,MAAM,GAAG,MAAM,SAAS,CAAC,YAAY,CACnC,IAAI,CAAC,CAAC,CAAW,EACjB,UAAU,CACX,CAAC;oCACF,MAAM;4BACV,CAAC;4BACD,IAAI,CAAC,QAAQ;gCACX,MAAM,CAAC,WAAW,CAChB;oCACE,IAAI,EAAE,UAAU;oCAChB,EAAE,EAAE,OAAO,CAAC,EAAE;oCACd,MAAM;oCACN,KAAK,EAAE,OAAO,CAAC,SAAS,GAAG,MAAM,CAAC,SAAS;iCAC5C,EACD,kBAAkB,CAAC,MAAM,CAAC,CAC3B,CAAC;wBACN,CAAC;wBAAC,OAAO,KAAK,EAAE,CAAC;4BACf,IAAI,CAAC,QAAQ;gCACX,MAAM,CAAC,WAAW,CAAC;oCACjB,IAAI,EAAE,UAAU;oCAChB,EAAE,EAAE,OAAO,CAAC,EAAE;oCACd,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;oCAC7D,cAAc,EACZ,KAAK,YAAY,uBAAuB;wCACxC,MAAM,CAAC,MAAM,EAAE,OAAO;oCACxB,KAAK,EAAE,OAAO,CAAC,SAAS,GAAG,MAAM,CAAC,SAAS;iCAC5C,CAAC,CAAC;wBACP,CAAC;oBACH,CAAC,CAAC,EAAE,CAAC;oBACL,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;oBACjB,KAAK,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;gBAC/C,CAAC,CAAC;gBACF,MAAM,CAAC,WAAW,CAAC;oBACjB,IAAI,EAAE,KAAK;oBACX,IAAI,EAAE,EAAE,GAAG,OAAO,CAAC,IAAI,EAAE,YAAY,EAAE,WAAW,EAAE;oBACpD,SAAS;iBACV,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;QACL,CAAC;gBAAS,CAAC;YACT,IAAI,KAAK,KAAK,SAAS;gBAAE,YAAY,CAAC,KAAK,CAAC,CAAC;YAC7C,UAAU,CAAC,KAAK,EAAE,CAAC;YACnB,MAAM,CAAC,SAAS,EAAE,CAAC;YACnB,MAAM,OAAO,CAAC,UAAU,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC;QACxC,CAAC;IACH,CAAC;IACD,OAAO;QACL,KAAK,CAAC,SAAS,CAAC,KAAK;YACnB,IAAI,CAAC;gBACH,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAExD,CAAC;YACJ,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,kBAAkB,CAAC;oBACxB,GAAG,KAAK;oBACR,OAAO,EAAE,EAAE;oBACX,QAAQ,EAAE,QAAQ;iBACnB,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QACD,KAAK,CAAC,YAAY,CAAC,OAAO;YACxB,IAAI,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,cAAc,CAAC;gBAAE,OAAO;YACrD,yEAAyE;YACzE,wEAAwE;YACxE,IAAI,CAAC;gBACH,MAAM,GAAG,CAAC,EAAE,MAAM,EAAE,cAAc,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC;YAC9D,CAAC;YAAC,MAAM,CAAC;gBACP,mDAAmD;YACrD,CAAC;QACH,CAAC;QACD,KAAK,CAAC,WAAW,CAAC,KAAK,EAAE,QAAQ;YAC/B,IAAI,KAAK,CAAC,UAAU,CAAC,cAAc,CAAC;gBAAE,OAAO;YAC7C,IAAI,OAAO,SAAS,KAAK,WAAW,IAAI,CAAC,SAAS,CAAC,KAAK;gBACtD,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAC;YACvE,sEAAsE;YACtE,gEAAgE;YAChE,MAAM,MAAM,GAAG,QAAQ,EAAE,WAAW;gBAClC,CAAC,CAAC,IAAI,eAAe,CACjB,OAAO,CAAC,IAAI,CAAC,UAAU,EACvB,OAAO,CAAC,IAAI,CAAC,YAAY,EACzB,QAAQ,CAAC,MAAM,CAChB;gBACH,CAAC,CAAC,SAAS,CAAC;YACd,MAAM,SAAS,CAAC,KAAK,CAAC,OAAO,CAC3B,IAAI,CAAC,SAAS,CAAC;gBACb,sBAAsB;gBACtB,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,WAAW,EAAE;gBACvC,OAAO,CAAC,IAAI,CAAC,OAAO;aACrB,CAAC,EACF,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,EAC7C,KAAK,IAAI,EAAE;gBACT,IAAI,MAAM,EAAE,CAAC;oBACX,MAAM,OAAO,CAAC,SAAS,CAAC,WAAW,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;oBACnD,OAAO;gBACT,CAAC;gBACD,KAAK,MAAM,MAAM,IAAI;oBACnB,oBAAoB,CAAC,KAAK,CAAC;oBAC3B,uBAAuB;iBACxB,EAAE,CAAC;oBACF,MAAM,OAAO,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC;oBACxC,MAAM,OAAO,CAAC,SAAS,CAAC,YAAY,CAAC,MAAM,EAAE,IAAI,eAAe,EAAE,CAAC,CAAC;gBACtE,CAAC;YACH,CAAC,CACF,CAAC;QACJ,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,64 @@
1
+ import { type ByteBudget } from "@opendatalabs/personal-server-ts-core/additions";
2
+ import type { ServerConfig } from "@opendatalabs/personal-server-ts-core/schemas";
3
+ import type { RequestSigner } from "@opendatalabs/personal-server-ts-core/signing";
4
+ import type { ServerSigner } from "@opendatalabs/personal-server-ts-core/signing";
5
+ import type { PsLiteStateStore } from "./state.js";
6
+ /** Hosts may expose these only when cancelling actually settles their wallet request. */
7
+ export interface PsLiteBoundedOwnerSigner {
8
+ signMessageBounded(message: string, signal?: AbortSignal): Promise<`0x${string}`>;
9
+ signAddDataBounded(message: Parameters<ServerSigner["signAddData"]>[0], signal?: AbortSignal): Promise<`0x${string}`>;
10
+ }
11
+ export interface PsLitePreparedPublication {
12
+ scope: string;
13
+ expectedVersion: string;
14
+ dataHash: `0x${string}`;
15
+ metadataHash: `0x${string}`;
16
+ encrypted: Uint8Array;
17
+ }
18
+ export declare function createPsLiteAdditionsTransport(options: {
19
+ config: ServerConfig;
20
+ ownerAddress: string;
21
+ stateStore: PsLiteStateStore;
22
+ masterKey: Uint8Array;
23
+ ownerSigner: PsLiteBoundedOwnerSigner;
24
+ /** Authentication origin may differ from a preview Storage endpoint. */
25
+ storageAudience?: string;
26
+ fetch?: typeof globalThis.fetch;
27
+ }): {
28
+ openSession: () => {
29
+ fetch: (input: {
30
+ url: string;
31
+ method?: string;
32
+ headers?: [string, string][];
33
+ body?: Uint8Array;
34
+ }, budget: ByteBudget) => Promise<{
35
+ status: number;
36
+ headers: [string, string][];
37
+ body: Uint8Array<ArrayBufferLike>;
38
+ }>;
39
+ signRequest: (params: Parameters<RequestSigner["signRequest"]>[0], signal?: AbortSignal) => Promise<string>;
40
+ publish: (prepared: PsLitePreparedPublication, budget: ByteBudget) => Promise<void>;
41
+ readPending: (scope: string, budget: ByteBudget) => Promise<PsLitePreparedPublication | null>;
42
+ clearPending: (scope: string, budget: ByteBudget) => Promise<void>;
43
+ download: (key: string, budget: ByteBudget) => Promise<Uint8Array<ArrayBufferLike>>;
44
+ };
45
+ tombstone: (scope: string, budget: ByteBudget) => Promise<import("@opendatalabs/personal-server-ts-core/ports").TombstoneOutcome>;
46
+ deleteScope: (scope: string, budget: ByteBudget) => Promise<void>;
47
+ fetch: (input: {
48
+ url: string;
49
+ method?: string;
50
+ headers?: [string, string][];
51
+ body?: Uint8Array;
52
+ }, budget: ByteBudget) => Promise<{
53
+ status: number;
54
+ headers: [string, string][];
55
+ body: Uint8Array<ArrayBufferLike>;
56
+ }>;
57
+ signRequest: (params: Parameters<RequestSigner["signRequest"]>[0], signal?: AbortSignal) => Promise<string>;
58
+ publish: (prepared: PsLitePreparedPublication, budget: ByteBudget) => Promise<void>;
59
+ readPending: (scope: string, budget: ByteBudget) => Promise<PsLitePreparedPublication | null>;
60
+ clearPending: (scope: string, budget: ByteBudget) => Promise<void>;
61
+ download: (key: string, budget: ByteBudget) => Promise<Uint8Array<ArrayBufferLike>>;
62
+ };
63
+ export type PsLiteAdditionsTransport = ReturnType<typeof createPsLiteAdditionsTransport>;
64
+ //# sourceMappingURL=additions-transport.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"additions-transport.d.ts","sourceRoot":"","sources":["../src/additions-transport.ts"],"names":[],"mappings":"AAMA,OAAO,EAKL,KAAK,UAAU,EAChB,MAAM,iDAAiD,CAAC;AAGzD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,+CAA+C,CAAC;AAClF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,+CAA+C,CAAC;AACnF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,+CAA+C,CAAC;AAClF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAEnD,yFAAyF;AACzF,MAAM,WAAW,wBAAwB;IACvC,kBAAkB,CAChB,OAAO,EAAE,MAAM,EACf,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,KAAK,MAAM,EAAE,CAAC,CAAC;IAC1B,kBAAkB,CAChB,OAAO,EAAE,UAAU,CAAC,YAAY,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,EACnD,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,KAAK,MAAM,EAAE,CAAC,CAAC;CAC3B;AAYD,MAAM,WAAW,yBAAyB;IACxC,KAAK,EAAE,MAAM,CAAC;IACd,eAAe,EAAE,MAAM,CAAC;IACxB,QAAQ,EAAE,KAAK,MAAM,EAAE,CAAC;IACxB,YAAY,EAAE,KAAK,MAAM,EAAE,CAAC;IAC5B,SAAS,EAAE,UAAU,CAAC;CACvB;AAYD,wBAAgB,8BAA8B,CAAC,OAAO,EAAE;IACtD,MAAM,EAAE,YAAY,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,gBAAgB,CAAC;IAC7B,SAAS,EAAE,UAAU,CAAC;IACtB,WAAW,EAAE,wBAAwB,CAAC;IACtC,wEAAwE;IACxE,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,KAAK,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK,CAAC;CACjC;;uBA0BU;YACL,GAAG,EAAE,MAAM,CAAC;YACZ,MAAM,CAAC,EAAE,MAAM,CAAC;YAChB,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC;YAC7B,IAAI,CAAC,EAAE,UAAU,CAAC;SACnB,UACO,UAAU;;;;;8BAqBV,UAAU,CAAC,aAAa,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,WAC1C,WAAW;4BAiJR,yBAAyB,UAC3B,UAAU;6BAvFX,MAAM,UACL,UAAU,KACjB,OAAO,CAAC,yBAAyB,GAAG,IAAI,CAAC;8BA4ET,MAAM,UAAU,UAAU;wBAgGlC,MAAM,UAAU,UAAU;;uBAcvB,MAAM,UAAU,UAAU;yBA4ExB,MAAM,UAAU,UAAU;mBA/VnD;QACL,GAAG,EAAE,MAAM,CAAC;QACZ,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC;QAC7B,IAAI,CAAC,EAAE,UAAU,CAAC;KACnB,UACO,UAAU;;;;;0BAqBV,UAAU,CAAC,aAAa,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,WAC1C,WAAW;wBAiJR,yBAAyB,UAC3B,UAAU;yBAvFX,MAAM,UACL,UAAU,KACjB,OAAO,CAAC,yBAAyB,GAAG,IAAI,CAAC;0BA4ET,MAAM,UAAU,UAAU;oBAgGlC,MAAM,UAAU,UAAU;EA8GxD;AAED,MAAM,MAAM,wBAAwB,GAAG,UAAU,CAC/C,OAAO,8BAA8B,CACtC,CAAC"}