@metalabel/dfos-client 0.29.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 ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Metalabel
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,88 @@
1
+ # @metalabel/dfos-client
2
+
3
+ The high-level read client for the [DFOS protocol](https://protocol.dfos.com). The protocol library owns the crypto truth (CID re-derivation, signature verification, chain folding); this client owns the four things it deliberately refuses to do: **fetch, resolve, verify-orchestration, and cache** — over an untrusted set of relays. It holds no keys and never writes.
4
+
5
+ If verification logic appears in this package, that is the bug: every proof comes from `@metalabel/dfos-protocol`.
6
+
7
+ ## Install
8
+
9
+ > **Not yet published — pre-release.** This package is `private` until it ships with a stamped release; until then it is consumable only inside this workspace.
10
+
11
+ ```bash
12
+ npm install @metalabel/dfos-client @metalabel/dfos-protocol @metalabel/dfos-web-relay
13
+ ```
14
+
15
+ `@metalabel/dfos-protocol` and `@metalabel/dfos-web-relay` are peer dependencies — one source of truth for the crypto kernel and the relay transport, no double-ship. The client imports only the relay package's lightweight `./peer-client` subpath (fetch + paging + route constants), never the relay server graph.
16
+
17
+ ## The surface
18
+
19
+ ```typescript
20
+ import { createClient } from '@metalabel/dfos-client';
21
+
22
+ const client = createClient({ relays: ['https://relay.example'] });
23
+
24
+ // The product: bound protocol-lib callbacks — spread straight into any verifier.
25
+ const { resolveKey, resolveIdentity, isRevoked } = client.callbacks();
26
+
27
+ // Display verbs → Resolved<T>. Trust is DATA, not exceptions.
28
+ const id = await client.identity('did:dfos:…');
29
+ const content = await client.content('…'); // contentId
30
+ const cred = await client.credential('<jws>');
31
+ const doc = await client.document('…'); // contentId → current document blob
32
+
33
+ // Paste-a-string dispatcher (did / contentId / credential JWS).
34
+ const anything = await client.resolve(userInput);
35
+
36
+ // No-throw "is this legit" one-liner.
37
+ const verdict = await client.verify('<jws>'); // VerifyResult<unknown>
38
+ ```
39
+
40
+ Every resolution returns a `Resolved<T>`:
41
+
42
+ ```typescript
43
+ interface Resolved<T> {
44
+ value: T; // the protocol lib's proven type, untouched
45
+ trust: { ok: boolean; unverifiable?: ('revocation' | 'tip')[] };
46
+ provenance: { answeredBy; responses; agreed; fromCache };
47
+ }
48
+ ```
49
+
50
+ Trust degrades honestly: `revocation` when non-revocation cannot be proven, `tip` whenever an answer's freshness rests on the cache — either the cache alone (relays unreachable) or a fully drained relay log that exactly matches the cached log. **Tip freshness is never proven in v1**: a relay's complete answer can verify the known history but cannot prove that no newer operation exists, so the client refuses to launder that claim into proof (relay head-proofs / `tipProven` are v2). Nothing is ever claimed as proven that was not.
51
+
52
+ ### Quorum
53
+
54
+ ```typescript
55
+ createClient({ relays: [...], quorum: 2 }); // require 2 relays to return the same log (by digest)
56
+ ```
57
+
58
+ `quorum: 1` (default) is first-wins with failover. `provenance.agreed` reports whether the threshold was met.
59
+
60
+ ### The free floor
61
+
62
+ ```typescript
63
+ import { resolvers } from '@metalabel/dfos-client';
64
+
65
+ const { resolveKey } = resolvers(['https://relay.example']); // zero object graph, one-off verify
66
+ ```
67
+
68
+ ## Subpaths
69
+
70
+ ### `@metalabel/dfos-client/store`
71
+
72
+ ```typescript
73
+ import { indexedDbStore, memoryStore } from '@metalabel/dfos-client/store';
74
+ ```
75
+
76
+ `memoryStore()` (the isomorphic default) caches the **log**. Chain reads fully drain from zero, require the fetched JWS tokens to match the trusted cached prefix, and verify forward only the suffix, so a key rotation costs one verification op and the cache is never stale-wrong. `indexedDbStore()` is the browser-only durable adapter — the only heavy dependency, quarantined behind this subpath.
77
+
78
+ ### `@metalabel/dfos-client/siwd`
79
+
80
+ ```typescript
81
+ import { createSiwdChallenge, siwdSigningInput, verifySiwd } from '@metalabel/dfos-client/siwd';
82
+ ```
83
+
84
+ Sign In With DFOS. `siwdSigningInput(challenge)` is the pure byte contract both the signer and the verifier share (see [SIWD.md](../../specs/SIWD.md)); `verifySiwd` is a no-throw verifier that accepts only a current `authKeys` entry of a non-deleted identity.
85
+
86
+ ## License
87
+
88
+ MIT
@@ -0,0 +1,16 @@
1
+ // src/store/memory.ts
2
+ var memoryStore = () => {
3
+ const map = /* @__PURE__ */ new Map();
4
+ return {
5
+ async get(key) {
6
+ return map.get(key);
7
+ },
8
+ async set(key, value) {
9
+ map.set(key, value);
10
+ }
11
+ };
12
+ };
13
+
14
+ export {
15
+ memoryStore
16
+ };
@@ -0,0 +1,32 @@
1
+ import { C as ClientConfig, a as Client, b as Callbacks, R as RevChecker } from './types-ByxTj1u-.js';
2
+ export { c as CallOptions, D as DocumentBlob, G as GlobalLogOptions, d as GlobalLogPage, e as GlobalLogResult, I as IndexCapabilities, f as IndexContentPage, g as IndexContentRow, h as IndexCountersignatureRow, i as IndexCountersignaturesPage, j as IndexCredentialRow, k as IndexCredentialsPage, l as IndexIdentitiesPage, m as IndexIdentityProfile, n as IndexIdentityRow, o as IndexOrder, p as IndexRecencyOrder, L as LogOp, P as Provenance, q as RelayHealth, r as RelayResponse, s as Resolution, t as Resolved, u as ResolvedContent, v as ResolvedCredential, S as Store, T as Trust, U as UnverifiableAxis, V as VerifyResult } from './types-ByxTj1u-.js';
3
+ export { m as memoryStore } from './memory-CL1DM6Ud.js';
4
+ import '@metalabel/dfos-protocol/chain';
5
+ import '@metalabel/dfos-protocol/credentials';
6
+ import '@metalabel/dfos-web-relay/peer-client';
7
+
8
+ declare const createClient: (config: ClientConfig) => Client;
9
+ /**
10
+ * The true minimalist floor: the bound protocol-lib callbacks over a relay set,
11
+ * with no client object, no cache tuning, no verbs. For a one-off verify.
12
+ */
13
+ declare const resolvers: (relays: string[]) => Callbacks;
14
+
15
+ /**
16
+ * Build the default revocation checker over an ordered relay set.
17
+ *
18
+ * Returns true only for a revocation JWS that VERIFIES via the protocol
19
+ * (`verifyRevocation`: signature, CID integrity, issuer-only rule) and whose
20
+ * payload binds exactly the queried (issuerDID, credentialCID). Anything less —
21
+ * unreachable relay, negative answer, forged or mismatched proof — moves on to
22
+ * the next relay; false only after the full set has been consulted.
23
+ *
24
+ * When the caller supplies `asOfUnix` (the protocol does, on every cold fold, with
25
+ * each operation's own `createdAt`), a verified revocation only counts if its own
26
+ * signed `createdAt` is at or before that instant. This is what heals cold
27
+ * verification of history: without it, revoking a credential today would make
28
+ * every already-committed operation it ever authorized fail to verify tomorrow.
29
+ */
30
+ declare const createRevocationChecker: (relays: string[], fetchImpl: typeof fetch, resolveKey: (kid: string) => Promise<Uint8Array>) => RevChecker;
31
+
32
+ export { Callbacks, Client, ClientConfig, RevChecker, createClient, createRevocationChecker, resolvers };