@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.
- package/LICENSE +21 -0
- package/README.md +26 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +7115 -0
- package/dist/types/api/app.d.ts +99 -0
- package/dist/types/api/auth-pure.d.ts +51 -0
- package/dist/types/api/auth.d.ts +17 -0
- package/dist/types/api/authorize.d.ts +24 -0
- package/dist/types/api/batch-deny.d.ts +22 -0
- package/dist/types/api/batch-routes.d.ts +69 -0
- package/dist/types/api/batch-store.d.ts +96 -0
- package/dist/types/api/batcher.d.ts +220 -0
- package/dist/types/api/browser.d.ts +14 -0
- package/dist/types/api/chain-budget.d.ts +61 -0
- package/dist/types/api/chain-views.d.ts +87 -0
- package/dist/types/api/client.d.ts +295 -0
- package/dist/types/api/deny-overlay.d.ts +81 -0
- package/dist/types/api/errors.d.ts +30 -0
- package/dist/types/api/file-stores.d.ts +7 -0
- package/dist/types/api/index.d.ts +17 -0
- package/dist/types/api/secure-fs.d.ts +12 -0
- package/dist/types/api/store.d.ts +51 -0
- package/dist/types/api/stores.d.ts +171 -0
- package/dist/types/api/verify-assertion.d.ts +22 -0
- package/dist/types/api/wire.d.ts +27 -0
- package/dist/types/chain/abis.d.ts +2125 -0
- package/dist/types/chain/browser.d.ts +20 -0
- package/dist/types/chain/deployment-fs.d.ts +15 -0
- package/dist/types/chain/deployment.d.ts +33 -0
- package/dist/types/chain/deployments.generated.d.ts +1 -0
- package/dist/types/chain/gas.d.ts +47 -0
- package/dist/types/chain/history.d.ts +52 -0
- package/dist/types/chain/index.d.ts +13 -0
- package/dist/types/chain/local.d.ts +34 -0
- package/dist/types/chain/logs.d.ts +62 -0
- package/dist/types/chain/placements.d.ts +92 -0
- package/dist/types/chain/read-scope.d.ts +66 -0
- package/dist/types/chain/registry.d.ts +16 -0
- package/dist/types/chain/sponsored.d.ts +93 -0
- package/dist/types/chain/transport.d.ts +53 -0
- package/dist/types/chain/writes.d.ts +165 -0
- package/dist/types/crypto/aead.d.ts +5 -0
- package/dist/types/crypto/bytes.d.ts +4 -0
- package/dist/types/crypto/derive.d.ts +20 -0
- package/dist/types/crypto/index.d.ts +6 -0
- package/dist/types/crypto/object.d.ts +42 -0
- package/dist/types/crypto/payload.d.ts +21 -0
- package/dist/types/crypto/wraps.d.ts +36 -0
- package/dist/types/grant-advisor/advise.d.ts +23 -0
- package/dist/types/grant-advisor/authority.d.ts +44 -0
- package/dist/types/grant-advisor/index.d.ts +5 -0
- package/dist/types/grant-advisor/manifest.d.ts +66 -0
- package/dist/types/grant-advisor/policy.d.ts +91 -0
- package/dist/types/grant-advisor/signatures.d.ts +10 -0
- package/dist/types/mida-context-sdk/daemon.d.ts +27 -0
- package/dist/types/mida-context-sdk/errors.d.ts +27 -0
- package/dist/types/mida-context-sdk/index.d.ts +5 -0
- package/dist/types/mida-context-sdk/local.d.ts +40 -0
- package/dist/types/mida-context-sdk/mida.d.ts +65 -0
- package/dist/types/mida-context-sdk/transport.d.ts +137 -0
- package/dist/types/protocol/batch.d.ts +161 -0
- package/dist/types/protocol/constants.d.ts +56 -0
- package/dist/types/protocol/errors.d.ts +15 -0
- package/dist/types/protocol/ids.d.ts +72 -0
- package/dist/types/protocol/index.d.ts +11 -0
- package/dist/types/protocol/namespaces.d.ts +15 -0
- package/dist/types/protocol/owner-link.d.ts +146 -0
- package/dist/types/protocol/typed-data.d.ts +365 -0
- package/dist/types/protocol/types.d.ts +215 -0
- package/dist/types/protocol/webauthn-assertion.d.ts +29 -0
- package/dist/types/protocol/wire.d.ts +8 -0
- package/dist/types/sdk/agent.d.ts +279 -0
- package/dist/types/sdk/batched.d.ts +68 -0
- package/dist/types/sdk/connect.d.ts +88 -0
- package/dist/types/sdk/index.d.ts +7 -0
- package/dist/types/sdk/request-store.d.ts +26 -0
- package/dist/types/storage/index.d.ts +23 -0
- package/package.json +50 -0
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import type { Address, Hex, ReaderEpochWrap } from "../protocol/index.js";
|
|
2
|
+
import type { ContextStorage } from "../storage/index.js";
|
|
3
|
+
import type { StoredObject } from "./store.js";
|
|
4
|
+
import type { RevocationIntent } from "./deny-overlay.js";
|
|
5
|
+
/** Key of a stored reader-epoch wrap (§12.4): one wrap per (owner, namespace, epoch, agent key version). */
|
|
6
|
+
export interface WrapKey {
|
|
7
|
+
owner: Address;
|
|
8
|
+
namespaceId: Hex;
|
|
9
|
+
readEpoch: string;
|
|
10
|
+
agentId: Hex;
|
|
11
|
+
agentKeyVersion: number;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* What the manifest index knows about one body hash: which envelope bytes it resolves to, when the row was
|
|
15
|
+
* first stored, and — once the envelope verified against the agent's chain record — when it last did so.
|
|
16
|
+
* `verifiedAt === null` means the agent has not registered on Monad yet (or the row was never re-checked):
|
|
17
|
+
* such rows are the sweep's job, because unverifiable staging bytes must not live forever.
|
|
18
|
+
*/
|
|
19
|
+
export interface ManifestIndexEntry {
|
|
20
|
+
envelopeHash: Hex;
|
|
21
|
+
/** ISO-8601 UTC; set once when the row is created and preserved on repointing writes. */
|
|
22
|
+
storedAt: string;
|
|
23
|
+
/** ISO-8601 UTC of the last successful verifySignedManifest, or null while unverified. */
|
|
24
|
+
verifiedAt: string | null;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Everything the Context API persists about objects, wraps and the manifest index, behind one async interface so the
|
|
28
|
+
* same app can run on the file-backed `ApiStore` or on D1 in the hosted worker. `blobs` is the §9.2 content-addressed
|
|
29
|
+
* byte store (`@mida/storage`); it still verifies content against its hash on every get.
|
|
30
|
+
*/
|
|
31
|
+
export interface ObjectStore {
|
|
32
|
+
readonly blobs: ContextStorage;
|
|
33
|
+
putObject(object: StoredObject): Promise<void>;
|
|
34
|
+
getObject(contextId: Hex): Promise<StoredObject | undefined>;
|
|
35
|
+
listObjects(owner: Address, namespaceId: Hex): Promise<StoredObject[]>;
|
|
36
|
+
/**
|
|
37
|
+
* This signer's objects that were never observed anchored on Monad (`anchoredAt` null), oldest
|
|
38
|
+
* first — the bounded set the pending-bytes quota re-checks. Rows marked anchored are excluded:
|
|
39
|
+
* anchoring cannot un-happen on this chain, so re-reading their records would be pure cost.
|
|
40
|
+
*/
|
|
41
|
+
pendingByUploader(uploader: Address): Promise<StoredObject[]>;
|
|
42
|
+
/**
|
|
43
|
+
* Records that this object was observed matching its Monad record at `anchoredAt`. First write
|
|
44
|
+
* wins: the mark is set once — it records a verified match, not merely that a record exists —
|
|
45
|
+
* and is never cleared, because a record cannot be un-registered on this chain design.
|
|
46
|
+
*/
|
|
47
|
+
markAnchored(contextId: Hex, anchoredAt: string): Promise<void>;
|
|
48
|
+
/**
|
|
49
|
+
* The quota-gated write for `PUT /objects`: the row lands only while the signer's unanchored bytes
|
|
50
|
+
* (`anchored_at IS NULL`) plus this object's ciphertext stay within `maxPendingBytes`, and the
|
|
51
|
+
* ciphertext `blob` is written with it — the pair is never split across two calls, so no sweep can
|
|
52
|
+
* land between them and take the blob of a row about to exist. "repeat" is a row with the same
|
|
53
|
+
* manifestHash already stored — a free no-op that still (re)writes the blob, healing a row whose
|
|
54
|
+
* first upload crashed between the writes; a different manifest for the same contextId throws
|
|
55
|
+
* COMMITMENT_MISMATCH, as `putObject` does, and a refused or mismatched PUT writes no blob at all.
|
|
56
|
+
* `blob` must hash to `object.manifest.ciphertextHash` — anything else is CONTENT_HASH_MISMATCH.
|
|
57
|
+
* `pendingSince` bounds which unmarked rows count toward the sum: only uploads at or after it.
|
|
58
|
+
* The app passes its quota-window cutoff so orphaned uploads past the window cannot block new
|
|
59
|
+
* writes at admission time; omitting it counts every unmarked row, the strictest reading.
|
|
60
|
+
* D1 evaluates the sum and the insert in a single statement inside one batch with the blob insert,
|
|
61
|
+
* so two Worker instances cannot both squeeze under the cap; the file-backed store performs the
|
|
62
|
+
* same check synchronously — atomic inside one Node process, but not across processes sharing a
|
|
63
|
+
* directory, which the README documents as single-process.
|
|
64
|
+
*/
|
|
65
|
+
putObjectWithinPending(object: StoredObject, maxPendingBytes: number, blob: Uint8Array, pendingSince?: Date): Promise<"stored" | "repeat" | "over-cap">;
|
|
66
|
+
putWrap(wrap: ReaderEpochWrap): Promise<void>;
|
|
67
|
+
getWrap(key: WrapKey): Promise<ReaderEpochWrap | undefined>;
|
|
68
|
+
/**
|
|
69
|
+
* Records or repoints bodyHash → envelopeHash. `storedAt` defaults to now and is only ever set on a new row;
|
|
70
|
+
* `verifiedAt` marks that the envelope just passed verifySignedManifest (omit for unverified staging bytes).
|
|
71
|
+
*/
|
|
72
|
+
setManifestIndex(bodyHash: Hex, envelopeHash: Hex, opts?: {
|
|
73
|
+
storedAt?: string;
|
|
74
|
+
verifiedAt?: string | null;
|
|
75
|
+
}): Promise<void>;
|
|
76
|
+
getManifestIndex(bodyHash: Hex): Promise<ManifestIndexEntry | undefined>;
|
|
77
|
+
/** Atomically counts one accepted PUT for this signer on this UTC day (`YYYY-MM-DD`) and returns the day's total. */
|
|
78
|
+
recordPut(signer: Address, day: string): Promise<number>;
|
|
79
|
+
/** Same atomic daily count as `recordPut`, on a separate counter for `PUT /agent-manifests`. */
|
|
80
|
+
recordManifestPut(signer: Address, day: string): Promise<number>;
|
|
81
|
+
/**
|
|
82
|
+
* Deletes objects uploaded before `olderThan` for which `stillPending` reports true — but only
|
|
83
|
+
* unmarked rows are even asked, and at most SWEEP_MAX_OBJECTS_PER_RUN of the oldest per call, so
|
|
84
|
+
* one invocation can never spend more chain reads than a request budget allows. A row
|
|
85
|
+
* `stillPending` reports false for was observed anchored: the implementation marks it once
|
|
86
|
+
* instead of deleting, so the next sweep skips it without a chain read. A `stillPending` call
|
|
87
|
+
* that throws skips that row entirely — it is neither deleted nor marked, and the run continues
|
|
88
|
+
* with the next row. Returns how many objects were removed.
|
|
89
|
+
*
|
|
90
|
+
* `blobGraceCutoff`, when given, additionally spares any blob written at or after it: a blob whose
|
|
91
|
+
* row has not landed yet (a PUT in flight) must survive the sweep — without it a sweep landing
|
|
92
|
+
* between the two writes could delete the blob of a row about to exist. `sweepStores` always passes
|
|
93
|
+
* it; a direct caller that omits it gets the bare reference check.
|
|
94
|
+
*/
|
|
95
|
+
sweepPending(olderThan: Date, stillPending: (object: StoredObject) => Promise<boolean>, blobGraceCutoff?: Date): Promise<number>;
|
|
96
|
+
/**
|
|
97
|
+
* Deletes every manifest index row still unverified (`verifiedAt` null) whose `storedAt` is before
|
|
98
|
+
* `olderThan` — the agent never registered, so the staged bytes can never serve. Each removed row's blob is
|
|
99
|
+
* deleted only when no other row references that hash (another index row, or an object's ciphertextHash),
|
|
100
|
+
* and — when `blobGraceCutoff` is given — only when the blob itself predates the cutoff.
|
|
101
|
+
*/
|
|
102
|
+
sweepManifests(olderThan: Date, blobGraceCutoff?: Date): Promise<number>;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* The §12.1 replay record. `consume` is the check-and-record of a (signer, nonce) pair as ONE atomic operation:
|
|
106
|
+
* an implementation backed by a single-writer file serializes it, a database-backed one uses a uniqueness
|
|
107
|
+
* constraint — an in-memory Map is never acceptable because the hosted worker runs many copies at once.
|
|
108
|
+
*/
|
|
109
|
+
export interface NonceStore {
|
|
110
|
+
consume(signer: Address, nonce: Hex, signedAt: bigint, now: bigint): Promise<void>;
|
|
111
|
+
/** Drops records whose signed timestamp is older than `now - REQUEST_WINDOW_SECONDS`. Returns how many went. */
|
|
112
|
+
sweep(now: bigint): Promise<number>;
|
|
113
|
+
}
|
|
114
|
+
/** What `deny-overlay.ts` persists: the revocation-intent rows the overlay's three transitions mutate. */
|
|
115
|
+
export interface DenyStore {
|
|
116
|
+
list(): Promise<RevocationIntent[]>;
|
|
117
|
+
get(id: Hex): Promise<RevocationIntent | undefined>;
|
|
118
|
+
insert(intent: RevocationIntent): Promise<void>;
|
|
119
|
+
update(intent: RevocationIntent): Promise<void>;
|
|
120
|
+
}
|
|
121
|
+
/** The three stores the app needs, bundled so `createContextApi` can take them in one option. */
|
|
122
|
+
export interface ContextStores {
|
|
123
|
+
objects: ObjectStore;
|
|
124
|
+
nonces: NonceStore;
|
|
125
|
+
denies: DenyStore;
|
|
126
|
+
}
|
|
127
|
+
/** Upload-abuse limits, applied by the shared app so self-hosters get them too. */
|
|
128
|
+
export interface StoreLimits {
|
|
129
|
+
/** Decoded ciphertext bytes accepted per object (a checkpoint is a few KB). */
|
|
130
|
+
maxCiphertextBytes: number;
|
|
131
|
+
/** Accepted PUT /objects per signer per UTC day. */
|
|
132
|
+
maxPutsPerSignerPerDay: number;
|
|
133
|
+
/** Total ciphertext bytes a signer may hold in objects that are not anchored on chain yet. */
|
|
134
|
+
maxPendingBytesPerSigner: number;
|
|
135
|
+
/** Raw body bytes for the agent-manifest PUT (a manifest is a few KB). */
|
|
136
|
+
maxManifestBodyBytes: number;
|
|
137
|
+
/** Accepted PUT /agent-manifests per signer per UTC day — the quota a request signature buys. */
|
|
138
|
+
maxManifestPutsPerSignerPerDay: number;
|
|
139
|
+
/** Raw body bytes for any authenticated route. */
|
|
140
|
+
maxRequestBodyBytes: number;
|
|
141
|
+
}
|
|
142
|
+
export declare const DEFAULT_STORE_LIMITS: StoreLimits;
|
|
143
|
+
/** Pending uploads older than this are swept: they were never anchored, so they only cost storage. */
|
|
144
|
+
export declare const PENDING_OBJECT_MAX_AGE_MS: number;
|
|
145
|
+
/**
|
|
146
|
+
* A blob younger than this is never deleted by the sweep, whatever the reference check says: a
|
|
147
|
+
* PUT writes its blob and its object row together, and a blob that fresh belongs to a row that is
|
|
148
|
+
* landing right now — the ten minutes cover clock skew and a slow request, not a guess.
|
|
149
|
+
*/
|
|
150
|
+
export declare const BLOB_SWEEP_GRACE_MS: number;
|
|
151
|
+
/**
|
|
152
|
+
* The most object rows one sweep invocation may ask `stillPending` about — each ask is a chain read,
|
|
153
|
+
* and one scheduled run must fit the same platform subrequest ceiling a request fits. Runs oldest-first
|
|
154
|
+
* and the cron repeats every 15 minutes, so a backlog drains in bounded tranches.
|
|
155
|
+
*/
|
|
156
|
+
export declare const SWEEP_MAX_OBJECTS_PER_RUN = 25;
|
|
157
|
+
/**
|
|
158
|
+
* The worker's scheduled job and any self-hoster's cron call: drop pending objects older than the window,
|
|
159
|
+
* unverified manifests past the same window, and nonces outside the freshness window. `isAnchored` checks
|
|
160
|
+
* Monad, so an anchored object is never swept.
|
|
161
|
+
*/
|
|
162
|
+
export declare function sweepStores(input: {
|
|
163
|
+
stores: ContextStores;
|
|
164
|
+
isAnchored: (object: StoredObject) => Promise<boolean>;
|
|
165
|
+
now?: Date;
|
|
166
|
+
pendingMaxAgeMs?: number;
|
|
167
|
+
}): Promise<{
|
|
168
|
+
objectsRemoved: number;
|
|
169
|
+
noncesRemoved: number;
|
|
170
|
+
manifestsRemoved: number;
|
|
171
|
+
}>;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { Hex } from "../protocol/index.js";
|
|
2
|
+
export interface WebAuthnAssertionInput {
|
|
3
|
+
authenticatorData: Hex;
|
|
4
|
+
clientDataJSON: string;
|
|
5
|
+
challengeIndex: string;
|
|
6
|
+
typeIndex: string;
|
|
7
|
+
r: Hex;
|
|
8
|
+
s: Hex;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Off-chain mirror of MidaWebAuthn plus webauthn-sol v1.0.0 (§10.4), used to accept a deny cancellation (§12.5):
|
|
12
|
+
* RP-ID hash, UP and UV flags, `"type":"webauthn.get"` and the base64url challenge at their declared indexes,
|
|
13
|
+
* low-s, then P256 over SHA-256(authenticatorData ‖ SHA-256(clientDataJSON)). Like the contract, it does not check
|
|
14
|
+
* `clientDataJSON.origin`; the browser enforces the origin for the Vault RP ID.
|
|
15
|
+
*/
|
|
16
|
+
export declare function verifyVaultAssertion(input: {
|
|
17
|
+
challenge: Hex;
|
|
18
|
+
assertion: WebAuthnAssertionInput;
|
|
19
|
+
qx: bigint;
|
|
20
|
+
qy: bigint;
|
|
21
|
+
rpIdHash: Hex;
|
|
22
|
+
}): boolean;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { Address, Hex, ObjectManifest, ReaderEpochWrap } from "../protocol/index.js";
|
|
2
|
+
/** PUT /objects body (§12.2). `capabilityId` names the agent's exact capability; owners omit it. */
|
|
3
|
+
export interface ObjectUploadBody {
|
|
4
|
+
owner: Address;
|
|
5
|
+
namespaceId: Hex;
|
|
6
|
+
objectNonce: Hex;
|
|
7
|
+
expectedParentId: Hex;
|
|
8
|
+
manifest: ObjectManifest;
|
|
9
|
+
ciphertext: Hex;
|
|
10
|
+
capabilityId?: Hex;
|
|
11
|
+
}
|
|
12
|
+
/** One element of GET /objects (§12.3). Clients re-check both commitments against Monad before decrypting. */
|
|
13
|
+
export interface AnchoredObject {
|
|
14
|
+
contextId: Hex;
|
|
15
|
+
owner: Address;
|
|
16
|
+
namespaceId: Hex;
|
|
17
|
+
authorId: Hex;
|
|
18
|
+
manifest: ObjectManifest;
|
|
19
|
+
manifestHash: Hex;
|
|
20
|
+
ciphertext: Hex;
|
|
21
|
+
}
|
|
22
|
+
export declare function hex(value: unknown, bytes: number, where: string): Hex;
|
|
23
|
+
export declare function address(value: unknown, where: string): Address;
|
|
24
|
+
export declare function parseObjectManifest(value: unknown): ObjectManifest;
|
|
25
|
+
export declare function parseObjectUpload(value: unknown): ObjectUploadBody;
|
|
26
|
+
/** §12.4 step 6: every wrap field present, correctly typed and of the exact byte length. */
|
|
27
|
+
export declare function parseReaderWrap(value: unknown): ReaderEpochWrap;
|