@mida-context/sdk 0.1.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 (78) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +26 -0
  3. package/dist/index.d.ts +1 -0
  4. package/dist/index.js +7115 -0
  5. package/dist/types/api/app.d.ts +99 -0
  6. package/dist/types/api/auth-pure.d.ts +51 -0
  7. package/dist/types/api/auth.d.ts +17 -0
  8. package/dist/types/api/authorize.d.ts +24 -0
  9. package/dist/types/api/batch-deny.d.ts +22 -0
  10. package/dist/types/api/batch-routes.d.ts +69 -0
  11. package/dist/types/api/batch-store.d.ts +96 -0
  12. package/dist/types/api/batcher.d.ts +220 -0
  13. package/dist/types/api/browser.d.ts +14 -0
  14. package/dist/types/api/chain-budget.d.ts +61 -0
  15. package/dist/types/api/chain-views.d.ts +87 -0
  16. package/dist/types/api/client.d.ts +295 -0
  17. package/dist/types/api/deny-overlay.d.ts +81 -0
  18. package/dist/types/api/errors.d.ts +30 -0
  19. package/dist/types/api/file-stores.d.ts +7 -0
  20. package/dist/types/api/index.d.ts +17 -0
  21. package/dist/types/api/secure-fs.d.ts +12 -0
  22. package/dist/types/api/store.d.ts +51 -0
  23. package/dist/types/api/stores.d.ts +171 -0
  24. package/dist/types/api/verify-assertion.d.ts +22 -0
  25. package/dist/types/api/wire.d.ts +27 -0
  26. package/dist/types/chain/abis.d.ts +2125 -0
  27. package/dist/types/chain/browser.d.ts +20 -0
  28. package/dist/types/chain/deployment-fs.d.ts +15 -0
  29. package/dist/types/chain/deployment.d.ts +33 -0
  30. package/dist/types/chain/deployments.generated.d.ts +1 -0
  31. package/dist/types/chain/gas.d.ts +47 -0
  32. package/dist/types/chain/history.d.ts +52 -0
  33. package/dist/types/chain/index.d.ts +13 -0
  34. package/dist/types/chain/local.d.ts +34 -0
  35. package/dist/types/chain/logs.d.ts +62 -0
  36. package/dist/types/chain/placements.d.ts +92 -0
  37. package/dist/types/chain/read-scope.d.ts +66 -0
  38. package/dist/types/chain/registry.d.ts +16 -0
  39. package/dist/types/chain/sponsored.d.ts +93 -0
  40. package/dist/types/chain/transport.d.ts +53 -0
  41. package/dist/types/chain/writes.d.ts +165 -0
  42. package/dist/types/crypto/aead.d.ts +5 -0
  43. package/dist/types/crypto/bytes.d.ts +4 -0
  44. package/dist/types/crypto/derive.d.ts +20 -0
  45. package/dist/types/crypto/index.d.ts +6 -0
  46. package/dist/types/crypto/object.d.ts +42 -0
  47. package/dist/types/crypto/payload.d.ts +21 -0
  48. package/dist/types/crypto/wraps.d.ts +36 -0
  49. package/dist/types/grant-advisor/advise.d.ts +23 -0
  50. package/dist/types/grant-advisor/authority.d.ts +44 -0
  51. package/dist/types/grant-advisor/index.d.ts +5 -0
  52. package/dist/types/grant-advisor/manifest.d.ts +66 -0
  53. package/dist/types/grant-advisor/policy.d.ts +91 -0
  54. package/dist/types/grant-advisor/signatures.d.ts +10 -0
  55. package/dist/types/mida-context-sdk/daemon.d.ts +27 -0
  56. package/dist/types/mida-context-sdk/errors.d.ts +27 -0
  57. package/dist/types/mida-context-sdk/index.d.ts +5 -0
  58. package/dist/types/mida-context-sdk/local.d.ts +40 -0
  59. package/dist/types/mida-context-sdk/mida.d.ts +65 -0
  60. package/dist/types/mida-context-sdk/transport.d.ts +137 -0
  61. package/dist/types/protocol/batch.d.ts +161 -0
  62. package/dist/types/protocol/constants.d.ts +56 -0
  63. package/dist/types/protocol/errors.d.ts +15 -0
  64. package/dist/types/protocol/ids.d.ts +72 -0
  65. package/dist/types/protocol/index.d.ts +11 -0
  66. package/dist/types/protocol/namespaces.d.ts +15 -0
  67. package/dist/types/protocol/owner-link.d.ts +146 -0
  68. package/dist/types/protocol/typed-data.d.ts +365 -0
  69. package/dist/types/protocol/types.d.ts +215 -0
  70. package/dist/types/protocol/webauthn-assertion.d.ts +29 -0
  71. package/dist/types/protocol/wire.d.ts +8 -0
  72. package/dist/types/sdk/agent.d.ts +279 -0
  73. package/dist/types/sdk/batched.d.ts +68 -0
  74. package/dist/types/sdk/connect.d.ts +88 -0
  75. package/dist/types/sdk/index.d.ts +7 -0
  76. package/dist/types/sdk/request-store.d.ts +26 -0
  77. package/dist/types/storage/index.d.ts +23 -0
  78. package/package.json +50 -0
@@ -0,0 +1,215 @@
1
+ import type { Address, Hex } from "viem";
2
+ import type { ContextKind, Permission, ProvenancePolicy, ProvenanceSource, RecordRelation } from "./constants.js";
3
+ export type { Address, Hex };
4
+ /** §4.3 */
5
+ export interface AgentRecord {
6
+ agentId: Hex;
7
+ operator: Address;
8
+ signer: Address;
9
+ encryptionPublicKey: Hex;
10
+ encryptionKeyVersion: number;
11
+ callbackOriginHash: Hex;
12
+ capabilityManifestHash: Hex;
13
+ capabilityManifestVersion: number;
14
+ active: boolean;
15
+ }
16
+ /** §7.2 */
17
+ export interface ReadEpochState {
18
+ readEpoch: bigint;
19
+ publicKey: Hex;
20
+ writeDeadline: bigint;
21
+ }
22
+ /** §8.2 */
23
+ export interface RecordReference {
24
+ relation: RecordRelation;
25
+ recordId: Hex;
26
+ }
27
+ /**
28
+ * Where a migrated record came from — sealed beside or inside the payload by `mida migrate`.
29
+ * Declared here because ContextPayload carries it; `@mida/checkpoint` holds an identical
30
+ * declaration beside StoredCheckpoint (that package stays dependency-free), and the two are
31
+ * structurally interchangeable.
32
+ */
33
+ export interface MigrationEnvelope {
34
+ version: 1;
35
+ /** The chain the record was copied from, as a decimal string. */
36
+ originalChainId: string;
37
+ /** The ContextRegistry the record lived on before the move. */
38
+ originalContract: Address;
39
+ originalRecordId: Hex;
40
+ /** The old record's on-chain manifestHash. */
41
+ originalCommitment: Hex;
42
+ /** The old record's on-chain author id. */
43
+ originalAuthor: Hex;
44
+ /** When the record was first written — ISO-8601. */
45
+ originalCreatedAt: string;
46
+ /** When the move happened — ISO-8601; its day is what "(moved on …)" renders. */
47
+ migratedAt: string;
48
+ }
49
+ export interface ContextPayload {
50
+ v: 1;
51
+ value: string | Record<string, unknown>;
52
+ kind: ContextKind;
53
+ provenance: {
54
+ source: ProvenanceSource;
55
+ extractionConfidence?: number;
56
+ references?: RecordReference[];
57
+ sourceHash?: Hex;
58
+ sourceUri?: string;
59
+ retrievedAt?: number;
60
+ note?: string;
61
+ };
62
+ tags?: string[];
63
+ /**
64
+ * The migration envelope of a moved record whose `value` is a string — a string cannot carry
65
+ * the envelope inside, so it sits here, a sibling of `value`. An object `value` carries it at
66
+ * `value.migration` instead, and an ordinary record carries no `migration` key at all.
67
+ */
68
+ migration?: MigrationEnvelope;
69
+ }
70
+ /** §8.3 */
71
+ export interface EpochDEKWrap {
72
+ v: 1;
73
+ contextId: Hex;
74
+ namespaceId: Hex;
75
+ readEpoch: string;
76
+ ephemeralPublicKey: Hex;
77
+ nonce: Hex;
78
+ wrappedDek: Hex;
79
+ }
80
+ /** §8.4 */
81
+ export interface ReaderEpochWrap {
82
+ v: 1;
83
+ owner: Address;
84
+ namespaceId: Hex;
85
+ readEpoch: string;
86
+ agentId: Hex;
87
+ agentKeyVersion: number;
88
+ ephemeralPublicKey: Hex;
89
+ nonce: Hex;
90
+ wrappedEpochPrivateKey: Hex;
91
+ createdAt: string;
92
+ }
93
+ /** §9.1 */
94
+ export interface ObjectManifest {
95
+ v: 1;
96
+ contextId: Hex;
97
+ ciphertextHash: Hex;
98
+ ciphertextSize: number;
99
+ payloadNonce: Hex;
100
+ cryptoVersion: "mida-crypto-v1";
101
+ readEpoch: string;
102
+ epochDekWrap: EpochDEKWrap;
103
+ }
104
+ /** §9.2 */
105
+ export interface StorageRef {
106
+ provider: "memory" | "fs" | "mida-api" | "s3" | "ipfs";
107
+ locator: string;
108
+ }
109
+ /** §13.2. GrantScope (§10.4) has the same three fields. */
110
+ export interface RequestedScope {
111
+ namespaceId: Hex;
112
+ permissions: number;
113
+ provenancePolicy: number;
114
+ }
115
+ export type GrantScope = RequestedScope;
116
+ export type PurposeId = "general_assistance" | "career_coaching" | "project_assistance" | "travel_planning";
117
+ export interface AccessRequest {
118
+ v: 1;
119
+ chainId: string;
120
+ capabilityRegistry: Address;
121
+ requestId: Hex;
122
+ nonce: Hex;
123
+ agentId: Hex;
124
+ purposeId: PurposeId;
125
+ callbackOrigin: string;
126
+ manifestHash: Hex;
127
+ manifestVersion: number;
128
+ policyVersion: "mida-grant-policy-v1";
129
+ namespaceTreeVersion: "mida-namespace-tree-v1";
130
+ scopes: RequestedScope[];
131
+ issuedAt: string;
132
+ requestExpiresAt: string;
133
+ capabilityExpiresAt: string;
134
+ agentSignature: Hex;
135
+ }
136
+ export interface GrantedCapability {
137
+ namespaceId: Hex;
138
+ permissions: number;
139
+ provenancePolicy: number;
140
+ expiresAt: string;
141
+ capabilityId: Hex;
142
+ transactionHash: Hex;
143
+ }
144
+ export interface AccessGrantResponse {
145
+ v: 1;
146
+ chainId: string;
147
+ capabilityRegistry: Address;
148
+ requestId: Hex;
149
+ nonce: Hex;
150
+ requestHash: Hex;
151
+ owner: Address;
152
+ agentId: Hex;
153
+ manifestHash: Hex;
154
+ manifestVersion: number;
155
+ policyVersion: "mida-grant-policy-v1";
156
+ namespaceTreeVersion: "mida-namespace-tree-v1";
157
+ capabilities: GrantedCapability[];
158
+ }
159
+ /** §14.1 */
160
+ export interface PurposeDeclaration {
161
+ id: PurposeId;
162
+ description: string;
163
+ }
164
+ export interface ScopeDeclaration {
165
+ purposeId: PurposeId;
166
+ namespace: string;
167
+ permissions: Permission[];
168
+ provenancePolicies?: ProvenancePolicy[];
169
+ reason: string;
170
+ }
171
+ export interface AgentCapabilityManifestBody {
172
+ v: 1;
173
+ agentId: Hex;
174
+ manifestVersion: number;
175
+ name: string;
176
+ purposes: PurposeDeclaration[];
177
+ scopeDeclarations: ScopeDeclaration[];
178
+ issuedAt: number;
179
+ }
180
+ export interface SignedAgentCapabilityManifest {
181
+ manifest: AgentCapabilityManifestBody;
182
+ operatorSignature: Hex;
183
+ }
184
+ /** §14.5 */
185
+ export interface EffectiveAuthority {
186
+ namespaceId: Hex;
187
+ permission: Permission;
188
+ provenancePolicy?: ProvenancePolicy;
189
+ }
190
+ export interface OwnerAgentHistory {
191
+ owner: Address;
192
+ agentId: Hex;
193
+ previouslyRevoked: boolean;
194
+ observedThroughBlock: bigint;
195
+ }
196
+ /** §14.6 */
197
+ export type ScopeWarningCode = "SCOPE_NOT_DECLARED" | "SCOPE_UNCLASSIFIED" | "SCOPE_ELEVATED" | "SCOPE_SUSPICIOUS" | "HIGH_SENSITIVITY" | "BROAD_PARENT_SCOPE" | "SUPERSEDE_ANY_EXPLICIT" | "PERMISSION_NARROWED" | "PROVENANCE_POLICY_NARROWED" | "DURATION_NARROWED" | "PREVIOUSLY_REVOKED";
198
+ export interface ScopeWarning {
199
+ code: ScopeWarningCode;
200
+ namespaceId?: Hex;
201
+ relatedNamespaceIds?: Hex[];
202
+ severity: "info" | "warning" | "critical";
203
+ messageKey: string;
204
+ }
205
+ export interface GrantAdvice {
206
+ policyVersion: "mida-grant-policy-v1";
207
+ namespaceTreeVersion: "mida-namespace-tree-v1";
208
+ requestHash: Hex;
209
+ manifestHash: Hex;
210
+ manifestVersion: number;
211
+ recommended: RequestedScope[];
212
+ recommendedExpiresAt: string;
213
+ warnings: ScopeWarning[];
214
+ risk: "low" | "medium" | "high";
215
+ }
@@ -0,0 +1,29 @@
1
+ import type { Hex } from "viem";
2
+ /** Order of the P256 (secp256r1) group. */
3
+ export declare const P256_N = 115792089210356248762697446949407573529996955224135760342422259061068512044369n;
4
+ /** Solidity `WebAuthn.WebAuthnAuth` from webauthn-sol v1.0.0, in field order. */
5
+ export interface WebAuthnAuthStruct {
6
+ authenticatorData: Hex;
7
+ clientDataJSON: string;
8
+ challengeIndex: bigint;
9
+ typeIndex: bigint;
10
+ r: bigint;
11
+ s: bigint;
12
+ }
13
+ /**
14
+ * EIP-7951 accepts any 0 < s < n, but webauthn-sol rejects s > n/2 (spec §10.4). A valid signature with high s has an
15
+ * equally valid twin at n - s, so every adapter maps to that low-s form before contract submission.
16
+ */
17
+ export declare function normalizeP256LowS(s: bigint): bigint;
18
+ /**
19
+ * The shared assertion adapter (spec §10.4, §15): builds the struct `grantBatch` and `rotateP256Key` consume, with s
20
+ * normalized. It has no FakeVault or browser dependency, so Project 2's real passkey adapter uses exactly this.
21
+ */
22
+ export declare function toWebAuthnAuthStruct(input: {
23
+ authenticatorData: Hex;
24
+ clientDataJSON: string;
25
+ challengeIndex: number | bigint;
26
+ typeIndex: number | bigint;
27
+ r: bigint;
28
+ s: bigint;
29
+ }): WebAuthnAuthStruct;
@@ -0,0 +1,8 @@
1
+ import type { Hex } from "viem";
2
+ export declare const MAX_UINT64: bigint;
3
+ export declare function encodeUint64(value: bigint): string;
4
+ export declare function decodeUint64(value: string): bigint;
5
+ export declare function assertHex(value: string, byteLength: number): Hex;
6
+ export declare function isZeroBytes(bytes: Uint8Array): boolean;
7
+ export declare function canonicalJson(value: unknown): string;
8
+ export declare function canonicalBytes(value: unknown): Uint8Array;
@@ -0,0 +1,279 @@
1
+ import type { AccessGrantResponse, AccessRequest, Address, ContextKind, ContextPayload, GrantedCapability, Hex, LineagePolicy, ObjectManifest, PurposeId, RecordReference } from "../protocol/index.js";
2
+ import type { LocalWriteContext } from "../chain/index.js";
3
+ import type { ScopeInput } from "../grant-advisor/index.js";
4
+ import type { BatchReceipt, ContextApiRoutes, ContextRecordView } from "../api/index.js";
5
+ import type { AccessRequestStore } from "./request-store.js";
6
+ /** §13.2 allows up to 600 seconds; the SDK uses 300 so a request stays valid through a normal consent screen. */
7
+ export declare const REQUEST_LIFETIME_SECONDS = 300n;
8
+ export interface AccessRequestInput {
9
+ purposeId: PurposeId;
10
+ /** Builder-supplied scopes; parents are expanded through the frozen tree before signing. */
11
+ scopes: readonly ScopeInput[];
12
+ /** Requested grant expiry in Unix seconds; omitted or 0n means no expiry is requested. */
13
+ capabilityExpiresAt?: bigint;
14
+ }
15
+ export interface Grant {
16
+ owner: Address;
17
+ agentId: Hex;
18
+ requestId: Hex;
19
+ capabilities: GrantedCapability[];
20
+ }
21
+ /** The only provenance an agent can write (§11.8). USER_ASSERTED and USER_CONFIRMED need the owner. */
22
+ export type AgentProvenanceSource = "AGENT_INFERRED" | "IMPORTED" | "EXTERNAL_ATTESTATION";
23
+ export interface CreateContextInput {
24
+ value: ContextPayload["value"];
25
+ kind: Exclude<ContextKind, "NONE">;
26
+ source: AgentProvenanceSource;
27
+ references?: RecordReference[];
28
+ tags?: string[];
29
+ note?: string;
30
+ extractionConfidence?: number;
31
+ expiresAt?: bigint;
32
+ }
33
+ export type SupersedeContextInput = CreateContextInput;
34
+ export interface ReadOptions {
35
+ /**
36
+ * `false` skips the same-second placement scan entirely — for a read that never orders its
37
+ * objects (the save duplicate-check). Default: records stamped in the same second get one
38
+ * bounded ±64-block log scan per disjoint window to recover (block, index).
39
+ */
40
+ placements?: boolean;
41
+ }
42
+ export interface ProposalInput {
43
+ value: ContextPayload["value"];
44
+ kind?: Exclude<ContextKind, "NONE">;
45
+ references?: RecordReference[];
46
+ tags?: string[];
47
+ note?: string;
48
+ extractionConfidence?: number;
49
+ }
50
+ /**
51
+ * One record written exactly as given (migrate B1): the payload is sealed verbatim — every
52
+ * provenance field `create` drops survives — and the record type, kind, lineage policy, expiry,
53
+ * parent and nonce are all the caller's. The caller predicts the id with `predictContextId`.
54
+ */
55
+ export interface ReplayInput {
56
+ namespaceId: Hex;
57
+ payload: ContextPayload;
58
+ recordType: "CONTEXT" | "EVIDENCE";
59
+ kind: ContextKind;
60
+ lineagePolicy: LineagePolicy;
61
+ expiresAt: bigint;
62
+ /** The parent record's contextId, or the zero hash for a root. */
63
+ expectedParentId: Hex;
64
+ /** Prepared by the caller; what makes a re-run land on the same id instead of duplicating. */
65
+ objectNonce: Hex;
66
+ }
67
+ export interface ContextObject {
68
+ contextId: Hex;
69
+ owner: Address;
70
+ namespace: string;
71
+ namespaceId: Hex;
72
+ authorId: Hex;
73
+ lineageId: Hex;
74
+ parentId: Hex;
75
+ version: number;
76
+ readEpoch: bigint;
77
+ recordType: "CONTEXT" | "EVIDENCE";
78
+ payload: ContextPayload;
79
+ transactionHash?: Hex;
80
+ /**
81
+ * The commitment the record's bytes were sealed under: the chain row's manifestHash for an
82
+ * anchored record, the signed batch message's for a pending one. A reader verifies the
83
+ * payload against it — it is never trusted on its own.
84
+ */
85
+ manifestHash?: Hex;
86
+ /**
87
+ * Monad's own placement of the save — set only on records the chain has actually recorded.
88
+ * `at` is the timestamp the chain stamped (the ContextRegistry row's createdAt for a direct
89
+ * save, the anchor block's time for a batched one); `block`, `transaction` and `index` are
90
+ * its position in the chain's order — the anchoring block, the anchoring transaction's index
91
+ * inside it, then the save's own position inside the transaction (the log index for a direct
92
+ * save, the batch's own position for a batched one). Absent entirely when no chain fact
93
+ * places the record — a pending batched save above all — and `block`/`transaction`/`index`
94
+ * are absent when only the stamp could be recovered. `batchId` names the one batch that
95
+ * anchored a batched-lane save: two rows sharing it share one transaction, so their `index`
96
+ * values are positions in the same ordering and comparable without asking the chain for the
97
+ * transaction index (in-14 F-1). Whatever an object claims inside its own payload never
98
+ * reaches this field.
99
+ */
100
+ chain?: {
101
+ at: bigint;
102
+ block?: bigint;
103
+ transaction?: number;
104
+ index?: number;
105
+ batchId?: Hex;
106
+ };
107
+ }
108
+ /**
109
+ * What `sealReplay` produces once and `sendSealed` may send any number of times (migrate B1b): the
110
+ * exact ciphertext and manifest the store's same-manifest repeat upload accepts, plus every field
111
+ * `register` needs. Ciphertext only — no plaintext — so a crash between upload and register
112
+ * resends identical bytes instead of re-sealing (a fresh seal draws a fresh key and a different
113
+ * manifestHash the store then refuses).
114
+ */
115
+ export interface SealedRecord {
116
+ contextId: Hex;
117
+ namespaceId: Hex;
118
+ readEpoch: bigint;
119
+ manifest: ObjectManifest;
120
+ manifestHash: Hex;
121
+ ciphertext: Uint8Array;
122
+ onChain: {
123
+ recordType: "CONTEXT" | "EVIDENCE";
124
+ kind: ContextKind;
125
+ lineagePolicy: LineagePolicy;
126
+ expiresAt: bigint;
127
+ expectedParentId: Hex;
128
+ evidenceCommitment: Hex;
129
+ objectNonce: Hex;
130
+ provenanceSource: number;
131
+ };
132
+ }
133
+ /**
134
+ * What `sendSealed` can attest: the anchored record's view plus its transaction — `ContextObject`
135
+ * minus `payload`, because a `SealedRecord` holds no plaintext to put in it (`replay` recomposes
136
+ * the full object from its own input). `transactionHash` is absent when the identical record was
137
+ * already anchored — a resend is done, not sent again.
138
+ */
139
+ export type SentRecord = Omit<ContextObject, "payload">;
140
+ export interface MidaAgentConfig {
141
+ agentId: Hex;
142
+ callbackOrigin: string;
143
+ encryptionPrivateKey: Uint8Array;
144
+ /** Write context whose account is the agent's current registered signer. */
145
+ chain: LocalWriteContext;
146
+ /** Context API client bound to the same signer. */
147
+ api: ContextApiRoutes & {
148
+ account: {
149
+ address: Address;
150
+ };
151
+ };
152
+ requests?: AccessRequestStore;
153
+ /**
154
+ * Grants this agent completed in an earlier process. They only tell the agent which capabilityId to present:
155
+ * every read is still authorised by the API against Monad and every write by the contract, so a stale or forged
156
+ * entry buys nothing.
157
+ */
158
+ grants?: readonly Grant[];
159
+ }
160
+ /** §13.1 agent/server SDK. Every authority it relies on is re-read from Monad; nothing the API returns is trusted alone. */
161
+ export declare class MidaAgent {
162
+ #private;
163
+ readonly agentId: Hex;
164
+ constructor(config: MidaAgentConfig);
165
+ get grants(): readonly Grant[];
166
+ /** The chain's own record for one contextId — null when the registry holds none. */
167
+ chainRecord(contextId: Hex): Promise<ContextRecordView | null>;
168
+ /**
169
+ * Whether Monad lists at least one currently-valid capability for this owner–agent pair —
170
+ * the contract's `isCapabilityValid` answer per id, not the local grant copy.
171
+ */
172
+ hasLiveCapability(owner: Address): Promise<boolean>;
173
+ /** §13.2: canonical, parent-expanded, sorted exact scopes, signed by the agent's current signer and persisted. */
174
+ createAccessRequest(input: AccessRequestInput): Promise<AccessRequest>;
175
+ /**
176
+ * §13.3: the response must match the stored original request, stay within its authority (Part C helper), and every
177
+ * capability must exist on Monad with identical fields, be currently valid, and be emitted by the named transaction.
178
+ * The chain proves a capability exists; the original request proves it is the one this agent asked for.
179
+ */
180
+ completeAccessRequest(request: AccessRequest, response: AccessGrantResponse): Promise<Grant>;
181
+ /**
182
+ * §12.3 read: API objects are re-checked against Monad commitments, then decrypted with this
183
+ * agent's own epoch wraps. A list the store could not fully verify is never returned as if it
184
+ * were complete — `read` refuses it outright; callers that can carry the flag use
185
+ * `readWithStatus` instead.
186
+ */
187
+ read(owner: Address, namespace: string, options?: ReadOptions): Promise<ContextObject[]>;
188
+ /**
189
+ * `read` plus the store's completeness flag, for callers that can surface it downstream (M3-D).
190
+ *
191
+ * Placement policy (in-9 R-1): `chain.at` is already chain truth on every record — the
192
+ * contract stores `block.timestamp` as createdAt — so no log scan runs for it. The event
193
+ * log's (block, index) is needed ONLY to order records stamped in the same second, and only
194
+ * then does the read scan: a bounded ±64-block window around the block that second implies,
195
+ * one getLogs per disjoint window. `{ placements: false }` skips even that (the save
196
+ * duplicate-check needs no ordering at all); a missed window falls back to the contextId
197
+ * tie-break, never to a whole-history scan.
198
+ */
199
+ readWithStatus(owner: Address, namespace: string, options?: ReadOptions): Promise<{
200
+ objects: ContextObject[];
201
+ partial: boolean;
202
+ }>;
203
+ /**
204
+ * The batched counterpart of `readWithStatus` (Task 4): lists the store's batch rows and verifies
205
+ * each one itself — an anchored row only survives if its proof reaches the on-chain batch root
206
+ * and it is the lineage's current head; a queued/submitted row is checked for everything except
207
+ * inclusion and comes back marked `PENDING_ANCHOR` with its author agentId. The store's word for
208
+ * a row's state is never trusted; every authority check reads the contracts.
209
+ */
210
+ readBatchedWithStatus(owner: Address, namespace: string): Promise<{
211
+ anchored: ContextObject[];
212
+ pending: (ContextObject & {
213
+ anchor: "PENDING_ANCHOR";
214
+ authorAgentId: Hex;
215
+ receivedAt: number;
216
+ })[];
217
+ skipped: {
218
+ contextId: Hex;
219
+ reason: string;
220
+ }[];
221
+ partial: boolean;
222
+ }>;
223
+ /**
224
+ * The duplicate check behind a save (in-12 N-6): whether this owner+namespace already holds a
225
+ * record whose decrypted payload satisfies `match`. Opening a row is local work — the epoch
226
+ * keys are fetched once per epoch and shared — so every listed row is opened and judged, and
227
+ * chain verification runs ONLY on the (normally zero or one) rows whose payload claims the
228
+ * match. That ordering is safe because a row the store invented cannot reach `match`: without
229
+ * the epoch key it cannot produce ciphertext that opens under the contextId binding, so a
230
+ * payload that opens was sealed honestly. A claimed match is then verified against Monad
231
+ * exactly as the full reads verify it — the store's word never decides "duplicate" — and a
232
+ * match whose record is not really there is skipped, not believed. A partial list still
233
+ * refuses outright: an incomplete view can never answer "not a duplicate" honestly. Returns
234
+ * the matching record's contextId, or undefined.
235
+ */
236
+ findDuplicate(owner: Address, namespace: string, match: (value: unknown) => boolean, options?: {
237
+ batched?: boolean;
238
+ }): Promise<Hex | undefined>;
239
+ create(owner: Address, namespace: string, input: CreateContextInput): Promise<ContextObject>;
240
+ /**
241
+ * The BatchAnchor write path (Task 4): seals the same checkpoint shape as `create` — a new
242
+ * STANDARD-lineage CONTEXT record, always AGENT_INFERRED — but signs it for the batch queue
243
+ * instead of calling `contexts.register`. The signature is the whole authorization; no
244
+ * transaction leaves this method.
245
+ */
246
+ createBatched(owner: Address, namespace: string, input: CreateContextInput): Promise<{
247
+ contextId: Hex;
248
+ state: "QUEUED";
249
+ receipt: BatchReceipt;
250
+ }>;
251
+ /** §11.6: SUPERSEDE_ANY on another author's STANDARD lineage, SUPERSEDE_OWN (or ANY) on this agent's own lineage. */
252
+ supersede(owner: Address, parentId: Hex, input: SupersedeContextInput): Promise<ContextObject>;
253
+ /** Always AGENT_INFERRED; the owner decides later whether to confirm it. */
254
+ propose(owner: Address, namespace: string, input: ProposalInput): Promise<ContextObject>;
255
+ /** The contextId a `replay` with this nonce will produce — computed before sending. */
256
+ predictContextId(owner: Address, namespaceId: Hex, objectNonce: Hex): Hex;
257
+ /**
258
+ * Writes one record exactly as given (migrate B1). Unlike `#write` it does not rebuild the
259
+ * payload — `sourceHash`, `sourceUri`, `retrievedAt`, `note`, `extractionConfidence`,
260
+ * `references` and `tags` all reach the seal — and it adds no provenance restriction of its
261
+ * own: the ordinary capability and epoch checks apply, and the contract stays the authority.
262
+ * Seal once, then send those bytes (migrate B1b).
263
+ */
264
+ replay(owner: Address, input: ReplayInput): Promise<ContextObject>;
265
+ /**
266
+ * Seals a replay exactly once and writes nothing (migrate B1b): the capability, epoch, id and
267
+ * every byte `sendSealed` needs, frozen so a retry — including after a crash between upload and
268
+ * register — resends identical bytes. The epoch is checked here and again at send: a seal that
269
+ * outlives its epoch is refused, never silently resealed under a different epoch.
270
+ */
271
+ sealReplay(owner: Address, input: ReplayInput): Promise<SealedRecord>;
272
+ /**
273
+ * Sends the bytes `sealReplay` produced — the same bytes on every call (migrate B1b). The store
274
+ * accepts a repeat upload only for an identical manifest, so a resend after an upload-only crash
275
+ * lands; a record already anchored with this exact manifestHash is done, not sent again; a stale
276
+ * epoch refuses `EPOCH_ROTATION_REQUIRED` before anything leaves this process.
277
+ */
278
+ sendSealed(owner: Address, sealed: SealedRecord): Promise<SentRecord>;
279
+ }
@@ -0,0 +1,68 @@
1
+ import type { Address, BatchSaveMessage, Hex } from "../protocol/index.js";
2
+ import type { Deployment } from "../chain/index.js";
3
+ import type { LocalAccount, PublicClient } from "viem";
4
+ import type { BatchedReadItem } from "../api/index.js";
5
+ export type { BatchedItemState, BatchedReadItem, BatchedSaveWire, BatchReceipt } from "../api/index.js";
6
+ /** Every way `verifyBatchedItem` can refuse, in the order the checks run. */
7
+ export type BatchedVerifyReason = "ciphertext" | "manifest" | "signature" | "author" | "not-anchored" | "unknown-batch" | "proof" | "stale";
8
+ /** Every way `verifyPendingItem` can refuse, in the order the checks run. */
9
+ export type PendingVerifyReason = "not-pending" | "ciphertext" | "manifest" | "signature" | "author" | "no-authority";
10
+ /**
11
+ * `anchorBlock` is the block `batchOf` reports for the save's batch — the block the anchor
12
+ * transaction mined in, read from the contract during verification, never the store's word.
13
+ */
14
+ export type BatchedVerdict = {
15
+ ok: true;
16
+ agentId: Hex;
17
+ anchorBlock: bigint;
18
+ } | {
19
+ ok: false;
20
+ reason: BatchedVerifyReason;
21
+ };
22
+ export type PendingVerdict = {
23
+ ok: true;
24
+ agentId: Hex;
25
+ anchorBlock?: never;
26
+ } | {
27
+ ok: false;
28
+ reason: PendingVerifyReason;
29
+ };
30
+ /**
31
+ * §BatchAnchor write path: the agent signs one `MidaBatchSaveV1` typed message per save under the
32
+ * BatchAnchor domain; the contract re-derives this digest, so the signature alone is the whole
33
+ * authorization — no transaction leaves this call.
34
+ */
35
+ export declare function signBatchSave(input: {
36
+ account: LocalAccount;
37
+ chainId: bigint;
38
+ batchAnchor: Address;
39
+ message: BatchSaveMessage;
40
+ }): Promise<Hex>;
41
+ /**
42
+ * The five-check anchored read. Chain state is the only authority: the signer→agent lookup, the
43
+ * batch root, and the lineage head all come from the contracts through `client`; the store supplies
44
+ * only the bytes being checked. A non-ANCHORED item can never pass — pending saves go through
45
+ * `verifyPendingItem` instead.
46
+ */
47
+ export declare function verifyBatchedItem(input: {
48
+ item: BatchedReadItem;
49
+ chainId: bigint;
50
+ deployment: Deployment;
51
+ client: PublicClient;
52
+ requireLatest: boolean;
53
+ }): Promise<BatchedVerdict>;
54
+ /**
55
+ * Amendment B.2 pending read: everything checkable without anchor inclusion — bytes, signature,
56
+ * registered author, contextId — plus the one live check that matters most for a not-yet-anchored
57
+ * save: the author's current authority, chosen exactly as `BatchAnchor._checkAndApply` chooses it.
58
+ * A new lineage needs CREATE+INFERENCE; a replacement needs SUPERSEDE_OWN when the signer authored
59
+ * the lineage root, SUPERSEDE_ANY otherwise — a save queued before a revocation must not survive
60
+ * this. Inclusion and freshness are deliberately unchecked: the contract will run them at anchor
61
+ * time.
62
+ */
63
+ export declare function verifyPendingItem(input: {
64
+ item: BatchedReadItem;
65
+ chainId: bigint;
66
+ deployment: Deployment;
67
+ client: PublicClient;
68
+ }): Promise<PendingVerdict>;