@engramx/client 0.15.0-rc.3 → 0.16.0-rc.2
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 +255 -26
- package/dist/EngramClient.d.ts +235 -229
- package/dist/EngramClient.js +446 -1247
- package/dist/EngramClient.js.map +1 -1
- package/dist/MarketClient.d.ts +137 -0
- package/dist/MarketClient.js +228 -0
- package/dist/MarketClient.js.map +1 -0
- package/dist/ProfileManager.d.ts +4 -4
- package/dist/SessionManager.d.ts +3 -3
- package/dist/SessionManager.js +1 -1
- package/dist/SessionManager.js.map +1 -1
- package/dist/actionReceipt.d.ts +59 -0
- package/dist/actionReceipt.js +68 -2
- package/dist/actionReceipt.js.map +1 -1
- package/dist/auth.d.ts +16 -0
- package/dist/auth.js +38 -5
- package/dist/auth.js.map +1 -1
- package/dist/certifiedAudit.d.ts +32 -6
- package/dist/certifiedAudit.js +75 -14
- package/dist/certifiedAudit.js.map +1 -1
- package/dist/cli.js +95 -26
- package/dist/cli.js.map +1 -1
- package/dist/encryption.d.ts +26 -12
- package/dist/encryption.js +13 -15
- package/dist/encryption.js.map +1 -1
- package/dist/generated/engram.idl.d.ts +6 -0
- package/dist/generated/engram.idl.js +1366 -0
- package/dist/generated/engram.idl.js.map +1 -0
- package/dist/generated/market.idl.d.ts +6 -0
- package/dist/generated/market.idl.js +557 -0
- package/dist/generated/market.idl.js.map +1 -0
- package/dist/generated/registry.idl.d.ts +6 -0
- package/dist/generated/registry.idl.js +510 -0
- package/dist/generated/registry.idl.js.map +1 -0
- package/dist/idl.d.ts +66 -0
- package/dist/idl.js +227 -0
- package/dist/idl.js.map +1 -0
- package/dist/index.d.ts +12 -18
- package/dist/index.js +54 -9
- package/dist/index.js.map +1 -1
- package/dist/ledgerfsHash.js +1 -1
- package/dist/ledgerfsHash.js.map +1 -1
- package/dist/lineage.js +8 -5
- package/dist/lineage.js.map +1 -1
- package/dist/memoryArchive.d.ts +384 -0
- package/dist/memoryArchive.js +477 -0
- package/dist/memoryArchive.js.map +1 -0
- package/dist/migrate.js +31 -4
- package/dist/migrate.js.map +1 -1
- package/dist/openEngram.d.ts +48 -0
- package/dist/openEngram.js +161 -0
- package/dist/openEngram.js.map +1 -0
- package/dist/pair.d.ts +33 -2
- package/dist/pair.js +56 -9
- package/dist/pair.js.map +1 -1
- package/dist/types.d.ts +244 -307
- package/dist/version.d.ts +8 -0
- package/dist/version.js +45 -0
- package/dist/version.js.map +1 -0
- package/dist/wire.d.ts +76 -0
- package/dist/wire.js +79 -0
- package/dist/wire.js.map +1 -0
- package/package.json +3 -13
- package/dist/bootstrap.d.ts +0 -21
- package/dist/bootstrap.js +0 -71
- package/dist/bootstrap.js.map +0 -1
package/dist/EngramClient.d.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { type CertifiedAuditHead, type VerifiedAuditHead } from './certifiedAudit.js';
|
|
2
|
+
import { Ed25519KeyIdentity } from '@icp-sdk/core/identity';
|
|
2
3
|
import { Principal } from '@icp-sdk/core/principal';
|
|
3
|
-
import {
|
|
4
|
-
import type {
|
|
4
|
+
import { idlFactory } from './idl.js';
|
|
5
|
+
import type { MemoryHistory, MemoryRangePage, MemoryFile, MemoryFileInfo, SessionContext, Pairing, AuditPage, AgentRecord, ChildAllowanceRow, EngramStatus, OwnerConsole, GuardianRecord, BackupMetadata, BackupType, ApprovalRequest } from './types.js';
|
|
5
6
|
/**
|
|
6
7
|
* Source class declared on an append — recorded permanently in the engram's audit chain beside
|
|
7
|
-
* this
|
|
8
|
+
* this agent's principal. Declared by the caller, NOT verified by the canister; a false
|
|
8
9
|
* declaration is itself attributable. Omit (undefined) when none applies: untagged is honest,
|
|
9
10
|
* a guessed tag is not.
|
|
10
11
|
*/
|
|
@@ -20,29 +21,22 @@ export type MemorySource = 'human' | 'agentDerived' | 'sessionTranscript' | 'fil
|
|
|
20
21
|
* first four unchanged.
|
|
21
22
|
*/
|
|
22
23
|
| 'deterministic';
|
|
23
|
-
/**
|
|
24
|
-
|
|
25
|
-
|
|
24
|
+
/**
|
|
25
|
+
* The evidence a write actually landed.
|
|
26
|
+
*
|
|
27
|
+
* Returned by every write method as of the 2026-08-16 canister release. Previously these returned
|
|
28
|
+
* a bare version number and the receipt — which the canister had already computed — was discarded,
|
|
29
|
+
* so a writer could learn THAT their write succeeded but not be handed the proof. `head` is the
|
|
30
|
+
* audit-chain head after this write, hex-encoded; it transitively commits to the content root, so a
|
|
31
|
+
* third party can verify the write against the chain and its anchor without trusting the writer.
|
|
32
|
+
*/
|
|
33
|
+
export interface MemoryReceipt {
|
|
34
|
+
/** Version of this path after the write. */
|
|
26
35
|
version: bigint;
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
/** One reviewed-surface row: machine fields parsed canister-side from its own audit format. */
|
|
32
|
-
export interface OperatorWriteRow {
|
|
33
|
-
entry: AuditEntry;
|
|
34
|
-
path: [] | [string];
|
|
35
|
-
version: [] | [bigint];
|
|
36
|
-
source: [] | [string];
|
|
37
|
-
connector: [] | [string];
|
|
38
|
-
}
|
|
39
|
-
export interface OperatorWriteReview {
|
|
40
|
-
cursor: bigint;
|
|
41
|
-
head: bigint;
|
|
42
|
-
earliest: bigint;
|
|
43
|
-
/** true ⇒ exactly 200 rows returned AND more unreviewed writes exist — page via markOperatorWritesReviewed(lastShownId); never present 200 as a total. */
|
|
44
|
-
capped: boolean;
|
|
45
|
-
rows: OperatorWriteRow[];
|
|
36
|
+
/** Position in the engram's event sequence. */
|
|
37
|
+
seq: bigint;
|
|
38
|
+
/** Chain head after this write, hex. The thing to hand a verifier. */
|
|
39
|
+
head: string;
|
|
46
40
|
}
|
|
47
41
|
export interface EngramClientConfig {
|
|
48
42
|
/** The engram canister ID */
|
|
@@ -64,14 +58,15 @@ export interface EngramClientConfig {
|
|
|
64
58
|
* legacy plaintext keep working regardless. */
|
|
65
59
|
encryptMemory?: boolean;
|
|
66
60
|
/** Opt-in persistent key cache path (Node only; or set ENGRAMX_KEY_CACHE). The cache file is
|
|
67
|
-
* plaintext-equivalent key material: a
|
|
68
|
-
* Destroy the file when
|
|
61
|
+
* plaintext-equivalent key material: a machine that persisted the key keeps it after revocation.
|
|
62
|
+
* Destroy the file when retiring the machine the agent runs on. */
|
|
69
63
|
keyCachePath?: string;
|
|
70
64
|
/** Label identifying this host in the engram's distinct-reader set (drives cross-model reuse
|
|
71
65
|
* metrics). Sent by `startSession()`. Default: 'sdk'. Use your product name, e.g. 'openclaw'. */
|
|
72
66
|
clientLabel?: string;
|
|
73
67
|
}
|
|
74
|
-
export
|
|
68
|
+
export { idlFactory };
|
|
69
|
+
export declare const icrc2LedgerIdlFactory: ({ IDL }: {
|
|
75
70
|
IDL: any;
|
|
76
71
|
}) => any;
|
|
77
72
|
export declare class EngramClient {
|
|
@@ -84,31 +79,66 @@ export declare class EngramClient {
|
|
|
84
79
|
private encryption;
|
|
85
80
|
private encryptionModeSynced;
|
|
86
81
|
private clientLabel;
|
|
82
|
+
/**
|
|
83
|
+
* ⟨0.16.0⟩ Delegates to the shared unwrap, because `Err` is a VARIANT now, not a string.
|
|
84
|
+
*
|
|
85
|
+
* The old body was `throw new Error(result.Err)`, which under the new envelope stringifies a
|
|
86
|
+
* six-armed object to **"[object Object]"** — it compiles, it runs, and it destroys the message.
|
|
87
|
+
* On this codebase that is the product: the refusals exist to tell a caller what to do next, and
|
|
88
|
+
* this line decides whether they ever read one. See wire.ts.
|
|
89
|
+
*/
|
|
87
90
|
private unwrap;
|
|
88
91
|
constructor(config: EngramClientConfig);
|
|
89
92
|
readMemory(path: string): Promise<MemoryFile>;
|
|
93
|
+
/**
|
|
94
|
+
* Does this path hold content already?
|
|
95
|
+
*
|
|
96
|
+
* A whole-file read is the obvious way to answer this and the wrong one. The engram refuses a
|
|
97
|
+
* whole-file read above 512 KiB, and files above that ceiling exist: the write cap sat at
|
|
98
|
+
* 1.5 MB until it was lowered to the same 512 KiB on 2026-08-15, so anything grown past the
|
|
99
|
+
* read ceiling under the old cap is still stored, still appendable, and still unreadable
|
|
100
|
+
* whole. Treating that refusal as absence is not a missing newline — it silently concatenates
|
|
101
|
+
* onto the previous line, and in encrypted mode it skips the framing check that exists to stop
|
|
102
|
+
* an unparseable mixed blob.
|
|
103
|
+
*
|
|
104
|
+
* So ask for a byte instead. A one-byte ranged read answers the question without ever hitting
|
|
105
|
+
* the whole-file ceiling, and it is the cheaper question at ANY size — there is no reason to
|
|
106
|
+
* pull a whole file to learn whether it is empty. That reason outlives the legacy files.
|
|
107
|
+
*/
|
|
108
|
+
private hasContent;
|
|
90
109
|
/**
|
|
91
110
|
* Append `content` to a memory file (append-only; the canister concatenates the delta).
|
|
92
111
|
*
|
|
93
|
-
* @returns the
|
|
94
|
-
* network call fails with a transport error, the encoded delta is queued for a later
|
|
95
|
-
* `syncOfflineQueue()` and this returns `
|
|
96
|
-
*
|
|
112
|
+
* @returns the write {@link MemoryReceipt}. **Special case:** if an `offlineQueue` is configured
|
|
113
|
+
* and the network call fails with a transport error, the encoded delta is queued for a later
|
|
114
|
+
* `syncOfflineQueue()` and this returns `null` — there is no receipt for a write that has not
|
|
115
|
+
* happened, and a caller that surfaces one must say "queued", not report a version. Deterministic
|
|
97
116
|
* errors (validation, permission, writes-paused, non-framed base in encrypted mode) always throw.
|
|
98
117
|
*/
|
|
118
|
+
appendMemory(path: string, content: string, source?: MemorySource): Promise<MemoryReceipt | null>;
|
|
99
119
|
/**
|
|
100
|
-
*
|
|
120
|
+
* The engram's file listing.
|
|
101
121
|
*
|
|
102
|
-
*
|
|
103
|
-
*
|
|
104
|
-
*
|
|
105
|
-
*
|
|
106
|
-
*
|
|
107
|
-
* answers the question without ever hitting the whole-file ceiling.
|
|
122
|
+
* ⟨0.16.0, L1 + L3⟩ Paged and enveloped. Two things this signature deliberately does NOT hide:
|
|
123
|
+
* a refusal throws rather than returning [], and `withheld` — the rows policy removed from the
|
|
124
|
+
* page — is surfaced on the thrown/returned shape's sibling accessor rather than silently
|
|
125
|
+
* dropped. `listMemoryFilesPage` is there for callers that must render "N hidden"; this one
|
|
126
|
+
* returns the rows because most callers render a list.
|
|
108
127
|
*/
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
128
|
+
listMemoryFiles(opts?: {
|
|
129
|
+
start?: number;
|
|
130
|
+
limit?: number;
|
|
131
|
+
}): Promise<MemoryFileInfo[]>;
|
|
132
|
+
/** The same read, keeping `total` and `withheld` — a filtered listing that looks complete is
|
|
133
|
+
* the defect the page shape exists to fix, and only the caller can decide whether to say so. */
|
|
134
|
+
listMemoryFilesPage(opts?: {
|
|
135
|
+
start?: number;
|
|
136
|
+
limit?: number;
|
|
137
|
+
}): Promise<{
|
|
138
|
+
items: MemoryFileInfo[];
|
|
139
|
+
total: bigint;
|
|
140
|
+
withheld: bigint;
|
|
141
|
+
}>;
|
|
112
142
|
readMemoryBatch(paths: string[]): Promise<[string, MemoryFile | Error][]>;
|
|
113
143
|
/**
|
|
114
144
|
* Load the engram's memory for injection at the START of an agent session — the automatic
|
|
@@ -138,7 +168,7 @@ export declare class EngramClient {
|
|
|
138
168
|
* `startSession()` yourself if you need the structured files instead. Accepts the same `onError`
|
|
139
169
|
* option as `startSession`.
|
|
140
170
|
*
|
|
141
|
-
* SECURITY: memory content is written by
|
|
171
|
+
* SECURITY: memory content is written by agents and is UNTRUSTED input, not system
|
|
142
172
|
* instructions. Each file is wrapped in a delimited `<engram-memory>` block and the header tells the
|
|
143
173
|
* model to treat the blocks as data — so appended memory cannot masquerade as system-level directives
|
|
144
174
|
* (prompt-injection boundary). Do not strip the fences when embedding this in your own prompt.
|
|
@@ -187,34 +217,55 @@ export declare class EngramClient {
|
|
|
187
217
|
/**
|
|
188
218
|
* Replace the whole content of an EXISTING file.
|
|
189
219
|
*
|
|
190
|
-
*
|
|
220
|
+
* Agents may call this only on paths the owner listed in `agentRevisablePaths`, and
|
|
191
221
|
* never on a path classed `#vault` — those stay append-only for anyone but the owner. It never
|
|
192
222
|
* creates a path: a revise grant is permission to change what is there.
|
|
193
223
|
*
|
|
194
224
|
* The prior version is superseded, not overwritten: it stays readable via
|
|
195
225
|
* {@link readMemoryAt} and its hash stays committed.
|
|
196
226
|
*/
|
|
197
|
-
reviseMemory(path: string, content: string | Uint8Array): Promise<
|
|
227
|
+
reviseMemory(path: string, content: string | Uint8Array): Promise<MemoryReceipt>;
|
|
228
|
+
/** ⟨0.16.0, L2.1⟩ `getWalletBalances` answers `Result<WalletBalances>` — a RECORD
|
|
229
|
+
* {icpE8s; ckusdcE6s; ckusdtE6s; cycles}, not a Nat. `unwrap<bigint>` is an unchecked
|
|
230
|
+
* assertion over `ActorSubclass<any>`, so the record flowed straight through while the
|
|
231
|
+
* signature still said bigint: the stdio MCP tool emitted
|
|
232
|
+
* {"cyclesBalance":{"icpE8s":"0",...,"cycles":"40717306348548"}} against a catalog that
|
|
233
|
+
* promises "no ckUSDC/ICP amounts", and OpenClaw printed "Cycles: [object Object]".
|
|
234
|
+
* Same class as the readAuditLog envelope defect corrected 2026-08-20 two methods below,
|
|
235
|
+
* and caught the same way: by a live call, because tsc has nothing to check here.
|
|
236
|
+
* This method is the CYCLES projection its name and both MCP catalogs promise.
|
|
237
|
+
* Corrected 2026-08-25. */
|
|
198
238
|
walletBalance(): Promise<bigint>;
|
|
199
|
-
/**
|
|
200
|
-
*
|
|
201
|
-
*
|
|
202
|
-
*
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
*
|
|
209
|
-
*
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
*
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
239
|
+
/** ⟨0.16.0, L1 + L3⟩ Paged and enveloped. The wire method moved to `listAuditEntries` and the
|
|
240
|
+
* CALL followed it, but the RESULT HANDLING did not: this returned the raw
|
|
241
|
+
* `{Ok:{items,total,withheld}} | {Err}` envelope while still declaring `AuditEntry[]`, so a
|
|
242
|
+
* caller's `.forEach` threw "not a function" and a REFUSAL arrived as a truthy object instead
|
|
243
|
+
* of an exception — the failure mode L1 exists to end, reintroduced by a half-finished rename.
|
|
244
|
+
* `this.actor` is `ActorSubclass<any>`, so the declared type is an unchecked assertion and tsc
|
|
245
|
+
* had nothing to catch it with: the rename compiled and looked done.
|
|
246
|
+
* Corrected 2026-08-20 to the idiom every sibling here already uses.
|
|
247
|
+
*
|
|
248
|
+
* ⟨CORRECTED 2026-09-29, owner ruling follow-up 16 (B)⟩ Returns the PAGE, not `.items`. An agent
|
|
249
|
+
* now reads only the entries it caused, so a window of the record comes back with `withheld`
|
|
250
|
+
* counting what it was not shown; handing back the bare array would let an agent mistake its part
|
|
251
|
+
* of the record for the whole. `limit` is the window's span, not a row count. */
|
|
252
|
+
readAuditLog(fromIndex?: number, limit?: number): Promise<AuditPage>;
|
|
253
|
+
/** How many entries the chained audit log currently holds — the page bound for
|
|
254
|
+
* {@link readAuditLog}.
|
|
255
|
+
*
|
|
256
|
+
* SERVES `status().auditLogSize`. The canister's own `auditLogSize()` was removed by the surface
|
|
257
|
+
* diet (R3, 2026-08-17): it was `auditLogger.size()` behind an #anyRole gate, while `status()`
|
|
258
|
+
* and `getCertifiedAuditHead()` both publish the identical Nat from the identical accessor to an
|
|
259
|
+
* anonymous caller. This wrapper keeps its name and its `bigint`, and only changes which door it
|
|
260
|
+
* knocks on.
|
|
261
|
+
*
|
|
262
|
+
* WHY status() AND NOT getCertifiedAuditHead(). Two reasons, both about this method's one job.
|
|
263
|
+
* The head surface additionally returns the CBOR IC certificate and a `total` — bytes every
|
|
264
|
+
* caller of a bare count discards, and a second, differently-meaning number (cumulative across
|
|
265
|
+
* ring trims) sitting next to the one that is right. Paging `readAuditLog` off `.total` reads
|
|
266
|
+
* past the ring; `status().auditLogSize` offers no such wrong field to pick. Callers who want
|
|
267
|
+
* the head — and its certificate — already have {@link getCertifiedAuditHead} and
|
|
268
|
+
* {@link getVerifiedAuditHead}, which is the other half of why this one does not duplicate it. */
|
|
218
269
|
auditLogSize(): Promise<bigint>;
|
|
219
270
|
/** The chained audit-log head plus the IC certificate over it (raw, unverified). Use
|
|
220
271
|
* getVerifiedAuditHead() to verify it against the IC root key. */
|
|
@@ -223,77 +274,89 @@ export declare class EngramClient {
|
|
|
223
274
|
* head bytes and whether the replica's claim agrees, WITHOUT trusting this replica. */
|
|
224
275
|
getVerifiedAuditHead(): Promise<VerifiedAuditHead>;
|
|
225
276
|
status(): Promise<EngramStatus>;
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
getWorldIdProof(): Promise<WorldIdProof | null>;
|
|
229
|
-
/** The verified IDKitResult, verbatim, as World's /api/v4/verify accepted it (null if unverified). */
|
|
230
|
-
getWorldIdVerification(): Promise<string | null>;
|
|
231
|
-
getPaymentRequirements(amount: bigint): Promise<PaymentRequirement[]>;
|
|
232
|
-
requestSession(): Promise<SessionIntent>;
|
|
233
|
-
openSession(config: SessionConfig, sig: PaymentSignature, rationale?: string, approvalId?: string): Promise<SessionState | {
|
|
234
|
-
approvalPending: {
|
|
235
|
-
requestId: string;
|
|
236
|
-
reason: string;
|
|
237
|
-
};
|
|
238
|
-
}>;
|
|
239
|
-
sessionReadMemory(voucher: Voucher, path: string): Promise<RawMemoryFile>;
|
|
240
|
-
sessionAppendMemory(voucher: Voucher, path: string, content: Uint8Array): Promise<bigint>;
|
|
241
|
-
endSession(sessionId: string): Promise<PaymentResult>;
|
|
242
|
-
forceCloseSession(sessionId: string): Promise<PaymentResult>;
|
|
243
|
-
private ownerAuthFor;
|
|
244
|
-
/**
|
|
245
|
-
* Withdraw a token balance to the owner's own principal (owner-only, destination-locked).
|
|
246
|
-
* Pass `{ receipt: true }` to attach an exportable owner-signed authorization (D1).
|
|
247
|
-
*/
|
|
248
|
-
ownerWithdraw(token: string, amount: bigint, options?: {
|
|
249
|
-
receipt?: boolean;
|
|
250
|
-
nonce?: bigint;
|
|
251
|
-
}): Promise<{
|
|
252
|
-
Ok: bigint;
|
|
253
|
-
} | {
|
|
254
|
-
Err: string;
|
|
255
|
-
}>;
|
|
256
|
-
uploadContent(id: string, mimeType: string, data: Uint8Array): Promise<void>;
|
|
257
|
-
/**
|
|
258
|
-
* E8: upload content larger than the ~2 MB single-shot ingress limit by streaming it through the
|
|
259
|
-
* canister's chunked path (uploadContentInit + uploadContentChunk). Chunk size is 1.5 MB — the
|
|
260
|
-
* ContentStore MAX_CHUNK_SIZE, enforced as a hard cap and safely under ICP's 2 MB ingress limit once
|
|
261
|
-
* Candid framing is added.
|
|
277
|
+
/** ⟨0.16.0, L2.2⟩ The GATED half of the `status()` split, and the only "does this engram
|
|
278
|
+
* recognise me" question left after `about()` shed the `authorized` discriminator.
|
|
262
279
|
*
|
|
263
|
-
*
|
|
264
|
-
*
|
|
265
|
-
*
|
|
266
|
-
*
|
|
267
|
-
*
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
}>;
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
280
|
+
* DESPITE THE NAME THE GATE IS #anyRole, not owner-only — main.mo reads
|
|
281
|
+
* `Gated.gatedResult<Types.OwnerConsole>(gateCtx(msg.caller), #anyRole, "getOwnerConsole", …)`,
|
|
282
|
+
* and Gated.mo spells #anyRole as "owner | active agent | active guardian". An agent SDK
|
|
283
|
+
* is entitled to it, which is why migrate.ts's pairing probe may call it.
|
|
284
|
+
*
|
|
285
|
+
* THROWS on refusal, like every other gated wrapper here. That is the whole point: REACHING the
|
|
286
|
+
* record is the authorization, so `Ok` is the recognition and `#Err(#Refused …)` is the denial.
|
|
287
|
+
* There is no sibling flag left for a consumer to forget to check — which is exactly the defect
|
|
288
|
+
* that made `status().authorized` answer `undefined` to everyone. */
|
|
289
|
+
getOwnerConsole(): Promise<OwnerConsole>;
|
|
290
|
+
/** ⟨0.16.0, L1 + L3⟩ Paged and enveloped. A refusal here used to arrive as [], which reads as
|
|
291
|
+
* "this engram has nobody who can freeze payments or pause writes" — a claim about who can STOP
|
|
292
|
+
* it, handed to a caller who merely lacks a grant. It throws now. */
|
|
293
|
+
listGuardians(opts?: {
|
|
294
|
+
start?: number;
|
|
295
|
+
limit?: number;
|
|
296
|
+
}): Promise<GuardianRecord[]>;
|
|
297
|
+
rotateAgentKeyHash(newPublicKeyHash: string): Promise<void>;
|
|
298
|
+
/** ⟨2026-09-28⟩ End THIS agent's own engagement with the engram — a resignation, recorded by
|
|
299
|
+
* the registry under its own reason so an agent's track record tells a clean exit from a firing.
|
|
300
|
+
* Terminal for this principal on this engram: pairing is one-shot, so working for it again
|
|
301
|
+
* needs a new principal and a fresh invite. Throws on a refusal (not an agent, already ended). */
|
|
302
|
+
resignAgent(): Promise<void>;
|
|
303
|
+
/** ⟨2026-09-29, the owner's ruling of that date (follow-up 10, option A)⟩ Step one of replacing
|
|
304
|
+
* THIS agent's key on the engram: the key this client signs with nominates `newKey`. Nothing
|
|
305
|
+
* moves until the new key accepts (`acceptAgentKeyNomination`, called by a client that signs with
|
|
306
|
+
* the new key) within 24 hours. The engagement stays open, the track record does not move, and
|
|
307
|
+
* the agent's limits carry over. A new nomination replaces an earlier one. Throws on a refusal. */
|
|
308
|
+
nominateAgentKey(newKey: Principal): Promise<void>;
|
|
309
|
+
/** ⟨2026-09-29, follow-up 10⟩ Step two: the key this client signs with accepts the nomination the
|
|
310
|
+
* agent's current key (`agentKey`) made of it, and takes over the agent's record on this engram.
|
|
311
|
+
* From then on `agentKey` is refused as an agent. Returns the record as the new key holds it.
|
|
312
|
+
* Throws on a refusal (no pending nomination of this key, expired, or an ended engagement). */
|
|
313
|
+
acceptAgentKeyNomination(agentKey: Principal): Promise<AgentRecord>;
|
|
314
|
+
/** ⟨2026-10-01, the owner's ruling 2 A⟩ How many engrams of its own the agent holding
|
|
315
|
+
* `agentKey` may still open through this engram, and its lasting key (`root`) — the key that
|
|
316
|
+
* would own what it opens. The engram answers the owner, or the agent asking about its own key
|
|
317
|
+
* (`agentKey` = the key this client signs with); anyone else is refused, never told 0.
|
|
318
|
+
* Named caller: the `open-engram` command (openEngram.ts), before it asks the engram to open. */
|
|
319
|
+
getChildAllowance(agentKey: Principal): Promise<ChildAllowanceRow>;
|
|
320
|
+
/** ⟨2026-10-01, the owner's ruling 2 A⟩ Ask this engram to open an engram of the agent's own.
|
|
321
|
+
* The engram attaches its own cycles to the registry's call and the agent's LASTING key owns
|
|
322
|
+
* what is opened — approving is giving: it is the agent's from the moment it exists. Answers the
|
|
323
|
+
* new engram's canister id. Throws a `CanisterRefusal` carrying the engram's sentence (no
|
|
324
|
+
* allowance, payments frozen, too little balance, or the registry refused) — each names what to
|
|
325
|
+
* do. Named caller: the `open-engram` command (openEngram.ts). */
|
|
326
|
+
openChildEngram(): Promise<Principal>;
|
|
327
|
+
/** ⟨2026-10-01⟩ The registry that opened this engram, or null when it records none — a public
|
|
328
|
+
* read. Named caller: the `open-engram` command, which prints the owner kit's command with
|
|
329
|
+
* `--registry` filled in, so whoever runs the agent never has to find the id. */
|
|
330
|
+
getSpawnedBy(): Promise<Principal | null>;
|
|
331
|
+
/** The verified IDKitResult, verbatim, as World's /api/v4/verify accepted it (null if
|
|
332
|
+
* unverified). `Result<opt Text>` is TWO WRAPPERS: an envelope around an option. Unwrap the
|
|
333
|
+
* envelope, THEN take the option — reading `result.length` on `{Ok:[…]}` gives `undefined`,
|
|
334
|
+
* which silently reads as "absent" for a verified engram and a refused caller alike. */
|
|
335
|
+
getWorldIdVerification(): Promise<string | null>;
|
|
289
336
|
initBackup(dbType: string, backupType: BackupType, parentBackupId: string | null, sha256: string, backupLabel: string | null): Promise<string>;
|
|
290
337
|
pushBackupChunk(backupId: string, chunkIndex: number, data: Uint8Array): Promise<void>;
|
|
291
338
|
finalizeBackup(backupId: string): Promise<void>;
|
|
292
339
|
abortBackup(backupId: string): Promise<void>;
|
|
340
|
+
/**
|
|
341
|
+
* Every backup this engram holds, newest-first as the store orders them.
|
|
342
|
+
*
|
|
343
|
+
* Throws on refusal rather than returning []. An empty backup list is a claim about the engram;
|
|
344
|
+
* "you may not read this" is a claim about the caller, and conflating them here is how a
|
|
345
|
+
* destructive restore gets invited.
|
|
346
|
+
*
|
|
347
|
+
* ⟨0.16.0, L3⟩ `dbTypeFilter` LEFT THE WIRE and stayed in this signature. The census retired the
|
|
348
|
+
* canister-side filter; keeping the parameter here means no caller loses the ability to ask
|
|
349
|
+
* "backups of this database", and the filtering happens over a page that already contains every
|
|
350
|
+
* backup — the store's own cap is far below one page, so a local filter cannot hide a row on a
|
|
351
|
+
* page nobody fetched. If that ever stops being true, this must page rather than filter.
|
|
352
|
+
*/
|
|
293
353
|
listBackups(dbTypeFilter?: string): Promise<BackupMetadata[]>;
|
|
294
354
|
pullBackupChunk(backupId: string, chunkIndex: number): Promise<Uint8Array>;
|
|
355
|
+
/** One backup's metadata by id. Kept alongside listBackups/pullBackupChunk because
|
|
356
|
+
* RECOVERY-RUNBOOK §"Restore" names exactly that chain: list or fetch the metadata, pull each
|
|
357
|
+
* chunk, then check the reassembled sha256 against it before applying anything. A restore that
|
|
358
|
+
* cannot state the hash it expected is not a restore. */
|
|
295
359
|
getBackupMetadata(backupId: string): Promise<BackupMetadata>;
|
|
296
|
-
deleteBackup(backupId: string): Promise<void>;
|
|
297
360
|
latestBackupMatchesHash(dbType: string, sha256: string): Promise<BackupMetadata | null>;
|
|
298
361
|
/** Encrypt a backup payload IFF this engram is in Private mode — the SAME toggle that governs
|
|
299
362
|
* memory files governs backups (encrypt files ⇒ encrypt backups). Produces a whole-blob
|
|
@@ -304,16 +367,30 @@ export declare class EngramClient {
|
|
|
304
367
|
* Content-driven (not flag-driven), so a plaintext / legacy backup passes through unchanged
|
|
305
368
|
* regardless of the current mode. Returns the original DB bytes, ready to write to disk. */
|
|
306
369
|
decryptBackupPayload(bytes: Uint8Array): Promise<Uint8Array>;
|
|
307
|
-
storageStats(): Promise<StorageStats>;
|
|
308
370
|
/** Warm the vetKeys memory-encryption key cache (one vetKD derivation). Optional —
|
|
309
371
|
* read/append derive lazily on first use. */
|
|
310
372
|
initEncryption(): Promise<void>;
|
|
311
373
|
/** Drops in-memory AND persisted key material (the "assume compromise" lever). */
|
|
312
374
|
clearEncryptionCache(): Promise<void>;
|
|
313
375
|
/** Sync the write-time encryption mode from the canister flag (once, cached),
|
|
314
|
-
* unless an explicit `encryptMemory` was given at construction.
|
|
376
|
+
* unless an explicit `encryptMemory` was given at construction.
|
|
377
|
+
*
|
|
378
|
+
* READS `status().encryptionEnabled`, not the former `isEncryptionEnabled()` — the surface diet
|
|
379
|
+
* (R3, 2026-08-17) removed that method because `status()` already returns the SAME
|
|
380
|
+
* `memoryEncryptionEnabled` variable, unconditionally, to the same anonymous audience: status()
|
|
381
|
+
* redacts only `owner` and `cyclesBalance` behind its `isAuthorized` check, and
|
|
382
|
+
* `encryptionEnabled` sits outside that branch.
|
|
383
|
+
*
|
|
384
|
+
* THE EXTRA BYTES ARE PAID ONCE PER CLIENT, NOT ONCE PER WRITE. This is the sync-ONCE path:
|
|
385
|
+
* `encryptionModeSynced` short-circuits every later call, and it is already true at
|
|
386
|
+
* construction when `encryptMemory` was passed — so a client that writes a thousand times
|
|
387
|
+
* fetches the status record at most once, where before it fetched a bool at most once. Caching
|
|
388
|
+
* the record itself would buy nothing here and would make every OTHER status field silently
|
|
389
|
+
* stale for the client's lifetime. */
|
|
315
390
|
private ensureEncryptionMode;
|
|
316
|
-
/** Whether this engram has memory encryption enabled (reads the canister flag).
|
|
391
|
+
/** Whether this engram has memory encryption enabled (reads the canister flag, uncached).
|
|
392
|
+
* Serves `status().encryptionEnabled` — see ensureEncryptionMode for why the singleton read is
|
|
393
|
+
* gone. Deliberately NOT cached: this method's whole job is to answer "what is it now". */
|
|
317
394
|
isMemoryEncryptionEnabled(): Promise<boolean>;
|
|
318
395
|
/** Owner-only: turn memory encryption on/off on the canister. Updates the local
|
|
319
396
|
* write mode immediately. Turning ON does not re-encrypt existing files — call
|
|
@@ -344,108 +421,37 @@ export declare class EngramClient {
|
|
|
344
421
|
synced: number;
|
|
345
422
|
failed: number;
|
|
346
423
|
}>;
|
|
347
|
-
registerOperator(inviteCode: string): Promise<OperatorRecord>;
|
|
348
|
-
getProtectedPaths(): Promise<string[]>;
|
|
349
|
-
/** The caller's OWN payment approval requests (not owner-only listApprovalRequests). Poll this after an
|
|
350
|
-
* over-limit payment returns approvalPending: when the owner raises the spending limit, the request
|
|
351
|
-
* flips to `Approved` and the operation can be retried. Operator-safe (returns only your own requests). */
|
|
352
|
-
getMyApprovalRequests(): Promise<ApprovalRequest[]>;
|
|
353
|
-
/**
|
|
354
|
-
* Create a pre-configured Ic402Client for auto-payment operations.
|
|
355
|
-
* The client handles 402 → ICRC-2 approve → retry automatically.
|
|
356
|
-
*/
|
|
357
|
-
createPaymentClient(options?: {
|
|
358
|
-
autoPayment?: boolean;
|
|
359
|
-
ledger?: string;
|
|
360
|
-
}): Ic402Client;
|
|
361
424
|
/**
|
|
362
|
-
*
|
|
363
|
-
* payment signature into the LAST argument, but the engramx canister appends
|
|
364
|
-
* `rationale` + `approvalId` AFTER `paymentSig` (for the owner approval workflow), so the
|
|
365
|
-
* signature must land at a FIXED index, not last. Flow: call with no sig → on
|
|
366
|
-
* #paymentRequired, icrc2_approve the amount (+ fee buffer) → build the ICP payment
|
|
367
|
-
* signature (a nonce-carrier; the real authorization is the ICRC-2 allowance the canister
|
|
368
|
-
* spends via transfer_from) → retry with the sig at `sigIndex`. Returns the raw canister
|
|
369
|
-
* result; the caller unwraps ok/error/approvalPending.
|
|
370
|
-
*/
|
|
371
|
-
private payAndCall;
|
|
372
|
-
/**
|
|
373
|
-
* Get paid content with auto-payment. Handles #paymentRequired → approve → retry.
|
|
374
|
-
* @param contentId Content identifier
|
|
375
|
-
* @param options Optional ledger override
|
|
376
|
-
*/
|
|
377
|
-
getContentWithPayment(contentId: string, options?: {
|
|
378
|
-
ledger?: string;
|
|
379
|
-
}): Promise<ContentDelivery>;
|
|
380
|
-
/**
|
|
381
|
-
* Open a streaming payment session with auto-escrow and voucher signing.
|
|
382
|
-
* Returns a SessionHandle that auto-signs vouchers on each call.
|
|
425
|
+
* Redeem an invite as the key for this engram, enrolled under the agent's lasting key (`root`).
|
|
383
426
|
*
|
|
384
|
-
*
|
|
385
|
-
*
|
|
386
|
-
*
|
|
387
|
-
*
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
}, pricing: {
|
|
399
|
-
Exact: bigint;
|
|
400
|
-
} | {
|
|
401
|
-
Upto: bigint;
|
|
402
|
-
} | {
|
|
403
|
-
Session: null;
|
|
404
|
-
}, verificationMethod: string, delivery: {
|
|
405
|
-
Poll: null;
|
|
406
|
-
} | {
|
|
407
|
-
Callback: null;
|
|
408
|
-
} | {
|
|
409
|
-
Both: null;
|
|
410
|
-
}, timeout: bigint, verifierCanisterId?: string, verificationKey?: Uint8Array, bindResult?: boolean): Promise<string>;
|
|
411
|
-
listServices(): Promise<unknown[]>;
|
|
412
|
-
/** Owner/operator view — includes disabled service drafts (others get enabled-only). */
|
|
413
|
-
listAllServices(): Promise<unknown[]>;
|
|
414
|
-
submitServiceRequest(serviceId: string, params: Uint8Array, paymentSig?: unknown, rationale?: string, approvalId?: string): Promise<{
|
|
415
|
-
jobId: string;
|
|
416
|
-
} | {
|
|
417
|
-
approvalPending: unknown;
|
|
418
|
-
}>;
|
|
419
|
-
/**
|
|
420
|
-
* Submit a paid service request with auto-payment (the marketplace counterpart of
|
|
421
|
-
* getContentWithPayment). Handles #paymentRequired → approve → retry, injecting the
|
|
422
|
-
* signature at the correct index for the engramx submitServiceRequest signature
|
|
423
|
-
* (serviceId, params, paymentSig, rationale, approvalId). Returns the jobId, or an
|
|
424
|
-
* approval-pending handle when the charge exceeds policy and the owner must approve.
|
|
425
|
-
*/
|
|
426
|
-
submitServiceRequestWithPayment(serviceId: string, params: Uint8Array, options?: {
|
|
427
|
-
ledger?: string;
|
|
428
|
-
rationale?: string;
|
|
429
|
-
}): Promise<{
|
|
430
|
-
jobId: string;
|
|
431
|
-
} | {
|
|
432
|
-
approvalPending: unknown;
|
|
433
|
-
}>;
|
|
434
|
-
claimJob(jobId: string): Promise<void>;
|
|
435
|
-
submitJobResult(jobId: string, result: Uint8Array, proof?: Uint8Array, actualCost?: bigint): Promise<void>;
|
|
436
|
-
confirmJob(jobId: string): Promise<void>;
|
|
437
|
-
disputeJob(jobId: string, reason: string): Promise<void>;
|
|
438
|
-
getJobStatus(jobId: string): Promise<unknown | null>;
|
|
439
|
-
getJob(jobId: string): Promise<unknown | null>;
|
|
440
|
-
/**
|
|
441
|
-
* E1: enumerate a service's job summaries. Owner OR the service's own operator only — any other
|
|
442
|
-
* caller gets []. Summaries omit params/result/proof blobs (use getJob(jobId) for a full payload).
|
|
443
|
-
* Pass a statusFilter like `{ Pending: null }` to filter, or omit for all statuses.
|
|
427
|
+
* ⟨RESHAPED 2026-09-28, owner decision: one root key per agent, with an enrolled key per client⟩
|
|
428
|
+
* The root signs a statement naming this engram, this session key and this invite code
|
|
429
|
+
* (`signEnrolment`); the engram verifies it, stores the root on the agent record, and the
|
|
430
|
+
* registry keeps the agent's track record under the root — one record however many engrams.
|
|
431
|
+
* The root must NOT be this session key (the engram refuses a root enrolling itself): keep it off
|
|
432
|
+
* every engram and pair a fresh session key per engram.
|
|
433
|
+
*
|
|
434
|
+
* ⟨RESHAPED 2026-09-29⟩ Returns `{ agent, trackRecord }`. `trackRecord` is `{ NotRecorded }`
|
|
435
|
+
* with a plain sentence when the registry refused or could not be reached, so the engagement is
|
|
436
|
+
* not (yet) on the agent's track record; the pairing has succeeded either way.
|
|
437
|
+
*
|
|
438
|
+
* ⟨2026-09-29, ic402 2.16.1⟩ One statement, one call. The re-signing `pairEnrolled` this used
|
|
439
|
+
* went with the verifier fault it worked around: the engram's Ed25519 check no longer refuses
|
|
440
|
+
* valid signatures, so a refusal is final and is returned as it is.
|
|
444
441
|
*/
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
442
|
+
pairAgent(inviteCode: string, root: Ed25519KeyIdentity): Promise<Pairing>;
|
|
443
|
+
/** ⟨0.16.0, L1⟩ Enveloped, and the unwrap was missing — same defect as `readAuditLog` above,
|
|
444
|
+
* found by the same sweep. Returned `{Ok:{paths}} | {Err}` while declaring `string[]`, so a
|
|
445
|
+
* caller iterating the result got nothing iterable and a refusal read as a truthy value.
|
|
446
|
+
* The Ok arm is a RECORD (`{paths}`), not a bare vec, so the field is named here. */
|
|
447
|
+
getProtectedPaths(): Promise<string[]>;
|
|
448
|
+
/** The caller's OWN payment approval requests (not owner-only listApprovalRequests). Poll this after an
|
|
449
|
+
* over-limit payment returns approvalPending: when the owner raises the spending limit, the request
|
|
450
|
+
* flips to `Approved` and the operation can be retried. Agent-safe (returns only your own requests). */
|
|
451
|
+
getMyApprovalRequests(opts?: {
|
|
452
|
+
start?: number;
|
|
453
|
+
limit?: number;
|
|
454
|
+
}): Promise<ApprovalRequest[]>;
|
|
449
455
|
clearCache(): void;
|
|
450
456
|
getPrincipal(): Principal;
|
|
451
457
|
}
|