@oxyhq/contracts 0.23.0 → 0.25.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 +202 -0
- package/NOTICE +15 -0
- package/dist/cjs/.tsbuildinfo +1 -1
- package/dist/cjs/followGraph.js +28 -0
- package/dist/cjs/oxyRecordTypes.js +44 -13
- package/dist/esm/.tsbuildinfo +1 -1
- package/dist/esm/followGraph.js +27 -0
- package/dist/esm/oxyRecordTypes.js +44 -13
- package/dist/types/.tsbuildinfo +1 -1
- package/dist/types/followGraph.d.ts +150 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/oxyRecordTypes.d.ts +42 -14
- package/package.json +3 -2
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* The follow graph wire contract (`/v2/follows`).
|
|
4
|
+
*
|
|
5
|
+
* These types are the boundary between the API that owns the graph and every
|
|
6
|
+
* application that reads it. They live here — not in the API and not in the
|
|
7
|
+
* SDK — because both ends have to agree, and a shape defined on one side is a
|
|
8
|
+
* shape the other side re-declares slightly differently within a release or two.
|
|
9
|
+
*
|
|
10
|
+
* ## Why the state is three fields and not a boolean
|
|
11
|
+
*
|
|
12
|
+
* A user can follow something globally and turn it off in ONE application. That
|
|
13
|
+
* is a state the user themselves created, so the client has to be able to see
|
|
14
|
+
* it and say so — "following, but not shown here" is a sentence a boolean
|
|
15
|
+
* cannot express. `globalState`, `applicationMode` and `effectiveState` are
|
|
16
|
+
* therefore reported separately, and only the last one answers "does this
|
|
17
|
+
* appear in my feed right now".
|
|
18
|
+
*
|
|
19
|
+
* ## Why kinds are strings
|
|
20
|
+
*
|
|
21
|
+
* `FollowTargetKind` is a plain `string`, not a union. Applications register
|
|
22
|
+
* their own kinds at runtime (`mercaria.store`, `syra.artist`), so a union here
|
|
23
|
+
* would mean every new application in the ecosystem needs a release of this
|
|
24
|
+
* package before it can follow anything. The namespace rule is enforced by the
|
|
25
|
+
* database, which is the one place that can enforce it for applications this
|
|
26
|
+
* package has never heard of.
|
|
27
|
+
*/
|
|
28
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
@@ -2,26 +2,54 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* Oxy-scoped signed-record types.
|
|
4
4
|
*
|
|
5
|
-
* The base `signedRecordEnvelopeSchema` (`./identity`)
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* it knows how to verify and materialize — this module is that closed set.
|
|
5
|
+
* The base `signedRecordEnvelopeSchema` (`./identity`) treats `type` as an OPEN,
|
|
6
|
+
* non-empty string so ANY Oxy app may sign on the shared envelope grammar. The
|
|
7
|
+
* Oxy STORE re-narrows it to the closed set in this module — a `type` outside it
|
|
8
|
+
* is rejected as `invalid_envelope`.
|
|
10
9
|
*
|
|
11
|
-
* `oxySignedRecordTypeSchema` is
|
|
12
|
-
*
|
|
13
|
-
* `
|
|
14
|
-
* the matching compile-time union the SDK
|
|
10
|
+
* `oxySignedRecordTypeSchema` is that runtime gate (the API's `verifyEnvelope`
|
|
11
|
+
* re-narrows with it; the Mongoose `SignedRecord.type` enum and the Postgres
|
|
12
|
+
* CHECK on `signed_records.type` are both derived from `.options`);
|
|
13
|
+
* `OxySignedRecordType` is the matching compile-time union the SDK
|
|
14
|
+
* identity/civic mixins type against.
|
|
15
15
|
*
|
|
16
16
|
* The signing input INCLUDES `type`, so this set is part of the signed bytes —
|
|
17
|
-
* a record cannot have its category swapped after signing
|
|
17
|
+
* a record cannot have its category swapped after signing, and a value once
|
|
18
|
+
* signed can never be renamed.
|
|
18
19
|
*
|
|
19
20
|
* v1 only ever carried `identity` / `profile` (already in production); v2 added
|
|
20
21
|
* the civic record types (reputation attestations, real-life / peer validations,
|
|
21
22
|
* personhood vouches, verifiable credentials) and the user-node registration
|
|
22
|
-
* record.
|
|
23
|
-
*
|
|
24
|
-
*
|
|
23
|
+
* record.
|
|
24
|
+
*
|
|
25
|
+
* ## Why `app_record` is here, when it deliberately was not
|
|
26
|
+
*
|
|
27
|
+
* This set used to hold Oxy's own categories only, and said so: an app's `type`
|
|
28
|
+
* was "intentionally NOT in this set". The reason given was that the store
|
|
29
|
+
* accepts only what it knows how to **verify and materialize**. Verification
|
|
30
|
+
* turned out not to argue for the exclusion — the engine verifies a signature
|
|
31
|
+
* against the subject's keys whatever the category says — and materialization
|
|
32
|
+
* is the app's job, not the store's: an app projects its own feed tables from
|
|
33
|
+
* records it reads back.
|
|
34
|
+
*
|
|
35
|
+
* What changed is the decision the exclusion blocked. One chain per PERSON, held
|
|
36
|
+
* by Oxy, is the ecosystem substrate: apps append their records to the subject's
|
|
37
|
+
* one chain instead of each keeping a private chain for the same person. A
|
|
38
|
+
* closed set that admits no app category makes that unrepresentable.
|
|
39
|
+
*
|
|
40
|
+
* `app_record` is ONE value rather than an open lane, and the lexicon lives in
|
|
41
|
+
* the envelope's `collection` (`app.mention.feed.post`, `app.syra.*`), which the
|
|
42
|
+
* store denormalizes to `signed_records.nsid` and indexes. So a new app needs no
|
|
43
|
+
* change here — it picks its own collection namespace and signs `app_record`,
|
|
44
|
+
* exactly as Mention already does in production. Keeping the set closed is what
|
|
45
|
+
* keeps the CHECK a real constraint.
|
|
46
|
+
*
|
|
47
|
+
* **Admitting the category is not the whole of that decision.** Two gates sit
|
|
48
|
+
* beside it and are unchanged: an app record must arrive as a v2 (chained)
|
|
49
|
+
* envelope, and `oxyVerificationResolver` accepts exactly one custodial issuer
|
|
50
|
+
* (`OXY_DID`). So a record a user signs themselves verifies here today, while
|
|
51
|
+
* one an app signs custodially under its OWN issuer DID does not — that needs a
|
|
52
|
+
* separate, deliberate answer about which issuers may write to a person's chain.
|
|
25
53
|
*
|
|
26
54
|
* Platform-agnostic — zod only, no react/react-native/expo, ESM-safe.
|
|
27
55
|
*/
|
|
@@ -37,4 +65,7 @@ exports.oxySignedRecordTypeSchema = zod_1.z.enum([
|
|
|
37
65
|
'personhood_vouch',
|
|
38
66
|
'credential',
|
|
39
67
|
'node',
|
|
68
|
+
// Any Oxy app's own record. The LEXICON is the envelope's `collection`, not
|
|
69
|
+
// this value — see the header.
|
|
70
|
+
'app_record',
|
|
40
71
|
]);
|