@oxyhq/contracts 0.2.1 → 0.3.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/dist/cjs/.tsbuildinfo +1 -1
- package/dist/cjs/identity.js +135 -0
- package/dist/cjs/index.js +14 -1
- package/dist/cjs/userResponse.js +18 -0
- package/dist/esm/.tsbuildinfo +1 -1
- package/dist/esm/identity.js +132 -0
- package/dist/esm/index.js +3 -0
- package/dist/esm/userResponse.js +18 -0
- package/dist/types/.tsbuildinfo +1 -1
- package/dist/types/identity.d.ts +244 -0
- package/dist/types/index.d.ts +2 -0
- package/dist/types/recommendations.d.ts +14 -14
- package/dist/types/userResponse.d.ts +365 -8
- package/package.json +1 -1
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Self-sovereign identity API contracts.
|
|
3
|
+
*
|
|
4
|
+
* SINGLE SOURCE OF TRUTH for the wire shape of Oxy's AtProto/Bluesky-flavoured
|
|
5
|
+
* identity & portability layer: the W3C DID document the API derives on demand,
|
|
6
|
+
* the signed-record envelope clients sign with their cryptographic key (and the
|
|
7
|
+
* server verifies), the verified-domain badge, the auth-method ↔ DID
|
|
8
|
+
* verification-method mapping, and the signed data-export ("credible exit")
|
|
9
|
+
* bundle. The API validates its OUTPUT against these schemas; every consumer
|
|
10
|
+
* (the Commons vault app, `@oxyhq/core`'s identity mixin) validates its INPUT
|
|
11
|
+
* against the same definitions, so producer and consumers cannot drift.
|
|
12
|
+
*
|
|
13
|
+
* Design anchors (from the identity-layer plan):
|
|
14
|
+
* - DID = `did:web:oxy.so:u:<userId>` — anchored on the stable account id, NOT
|
|
15
|
+
* the keypair. The keypair is a *verification method* that maps 1:1 to the
|
|
16
|
+
* existing `authMethods[]`. Custodial (password-only) users get a DID
|
|
17
|
+
* controlled solely by Oxy (`OXY_DID`); creating a Commons key upgrades them
|
|
18
|
+
* to self-sovereign (`controller = [userDid, OXY_DID]`); fully reversible.
|
|
19
|
+
* - Verification methods use the secp256k1 `EcdsaSecp256k1VerificationKey2019`
|
|
20
|
+
* type with `publicKeyHex` for now (a `Multikey`/`publicKeyMultibase` form may
|
|
21
|
+
* be added later — see the plan's open risks).
|
|
22
|
+
* - Signed records carry an envelope whose signing input is the canonical-JSON
|
|
23
|
+
* of every field EXCEPT `publicKey` and `signature`; `alg` is
|
|
24
|
+
* `ES256K-DER-SHA256` (secp256k1 over the SHA-256 of the canonical bytes,
|
|
25
|
+
* DER-encoded signature) — the same scheme `SignatureService` uses.
|
|
26
|
+
*
|
|
27
|
+
* Explicit-`interface` exports (DidDocument, SignedRecordEnvelope, ExportBundle,
|
|
28
|
+
* VerifiedDomain, AuthMethodsResponse and their sub-parts) follow the same
|
|
29
|
+
* rationale as `UserNameResponse` in `./userResponse`: a `z.infer<>` of a nested
|
|
30
|
+
* object schema can degrade under a consumer's `moduleResolution: "node"`
|
|
31
|
+
* (node10) resolution, so the load-bearing response shapes are declared as
|
|
32
|
+
* literal interfaces and the runtime schemas are annotated `z.ZodType<Interface>`
|
|
33
|
+
* — the emitted `.d.ts` then states the field types verbatim and survives BOTH
|
|
34
|
+
* `node` and `bundler` resolution. Request schemas (no nested-object hazard) are
|
|
35
|
+
* inferred via `z.infer<>`.
|
|
36
|
+
*
|
|
37
|
+
* Platform-agnostic — zod only, no react/react-native/expo. ESM-safe (no
|
|
38
|
+
* `require()`).
|
|
39
|
+
*/
|
|
40
|
+
import { z } from 'zod';
|
|
41
|
+
/**
|
|
42
|
+
* A single DID verification method. Mirrors the secp256k1 key entries the API
|
|
43
|
+
* derives from `User.publicKey` + each `authMethods[]` of type `identity`.
|
|
44
|
+
* `id` is a fragment reference within the DID document (e.g.
|
|
45
|
+
* `did:web:oxy.so:u:<id>#key-1`); `controller` is the controlling DID;
|
|
46
|
+
* `publicKeyHex` is the uncompressed/compressed secp256k1 public key in hex.
|
|
47
|
+
*/
|
|
48
|
+
export interface VerificationMethod {
|
|
49
|
+
id: string;
|
|
50
|
+
type: 'EcdsaSecp256k1VerificationKey2019';
|
|
51
|
+
controller: string;
|
|
52
|
+
publicKeyHex: string;
|
|
53
|
+
}
|
|
54
|
+
export declare const verificationMethodSchema: z.ZodType<VerificationMethod>;
|
|
55
|
+
/**
|
|
56
|
+
* A DID service entry (the `service[]` array). Oxy publishes its API root and
|
|
57
|
+
* profile endpoints here so a resolver can discover where to fetch the user's
|
|
58
|
+
* data. `serviceEndpoint` is a URL string.
|
|
59
|
+
*/
|
|
60
|
+
export interface DidService {
|
|
61
|
+
id: string;
|
|
62
|
+
type: string;
|
|
63
|
+
serviceEndpoint: string;
|
|
64
|
+
}
|
|
65
|
+
export declare const didServiceSchema: z.ZodType<DidService>;
|
|
66
|
+
/**
|
|
67
|
+
* A W3C DID document derived on demand by the API (no stored document).
|
|
68
|
+
*
|
|
69
|
+
* - `controller` is `[userDid, OXY_DID]` for a self-sovereign account (it holds
|
|
70
|
+
* at least one `identity` verification method) or `[OXY_DID]` for a custodial
|
|
71
|
+
* (password-only) account.
|
|
72
|
+
* - `verificationMethod[]` is composed from the account's secp256k1 keys.
|
|
73
|
+
* - `authentication` / `assertionMethod` reference verification-method ids.
|
|
74
|
+
* - `alsoKnownAs[]` carries the account's other identifiers (`acct:` handle,
|
|
75
|
+
* profile URL, any verified-domain URLs).
|
|
76
|
+
*/
|
|
77
|
+
export interface DidDocument {
|
|
78
|
+
'@context': string[];
|
|
79
|
+
id: string;
|
|
80
|
+
controller: string[];
|
|
81
|
+
verificationMethod: VerificationMethod[];
|
|
82
|
+
authentication: string[];
|
|
83
|
+
assertionMethod: string[];
|
|
84
|
+
alsoKnownAs: string[];
|
|
85
|
+
service: DidService[];
|
|
86
|
+
}
|
|
87
|
+
export declare const didDocumentSchema: z.ZodType<DidDocument>;
|
|
88
|
+
/**
|
|
89
|
+
* A signed record envelope. `record` is the arbitrary payload; the signing
|
|
90
|
+
* input is the canonical-JSON of every envelope field EXCEPT `publicKey` and
|
|
91
|
+
* `signature`. `subject` and `issuer` are DIDs (the subject the record is about
|
|
92
|
+
* and the signer's DID — equal for self-issued records, `OXY_DID` for a
|
|
93
|
+
* custodial provenance attestation). `issuedAt` is epoch milliseconds.
|
|
94
|
+
*/
|
|
95
|
+
export interface SignedRecordEnvelope {
|
|
96
|
+
version: 1;
|
|
97
|
+
type: 'identity' | 'profile';
|
|
98
|
+
subject: string;
|
|
99
|
+
issuer: string;
|
|
100
|
+
record: Record<string, unknown>;
|
|
101
|
+
issuedAt: number;
|
|
102
|
+
publicKey: string;
|
|
103
|
+
alg: 'ES256K-DER-SHA256';
|
|
104
|
+
signature: string;
|
|
105
|
+
}
|
|
106
|
+
export declare const signedRecordEnvelopeSchema: z.ZodType<SignedRecordEnvelope>;
|
|
107
|
+
/**
|
|
108
|
+
* A proven domain ownership badge. `method` records how ownership was proven —
|
|
109
|
+
* a DNS-TXT record (`_oxy-identity.<domain>`) or a `/.well-known/oxy-domain`
|
|
110
|
+
* HTTP file. `verifiedAt` is a string on the wire (ISO timestamp) but accepts a
|
|
111
|
+
* `Date` so the API can validate its own pre-serialization model objects.
|
|
112
|
+
*/
|
|
113
|
+
export interface VerifiedDomain {
|
|
114
|
+
domain: string;
|
|
115
|
+
verifiedAt: string | Date;
|
|
116
|
+
method: 'dns-txt' | 'well-known';
|
|
117
|
+
}
|
|
118
|
+
export declare const verifiedDomainSchema: z.ZodType<VerifiedDomain>;
|
|
119
|
+
/** Request body for `POST /identity/domains` — the domain to start verifying. */
|
|
120
|
+
export declare const domainVerificationRequestSchema: z.ZodObject<{
|
|
121
|
+
domain: z.ZodString;
|
|
122
|
+
}, "strip", z.ZodTypeAny, {
|
|
123
|
+
domain: string;
|
|
124
|
+
}, {
|
|
125
|
+
domain: string;
|
|
126
|
+
}>;
|
|
127
|
+
export type DomainVerificationRequest = z.infer<typeof domainVerificationRequestSchema>;
|
|
128
|
+
/**
|
|
129
|
+
* The instructions the API returns when a domain verification is requested. The
|
|
130
|
+
* caller may prove ownership EITHER by publishing the `dns` TXT record OR by
|
|
131
|
+
* serving the `wellKnown` file; either path then satisfies
|
|
132
|
+
* `POST /identity/domains/:domain/verify`.
|
|
133
|
+
*/
|
|
134
|
+
export declare const domainVerificationInstructionsSchema: z.ZodObject<{
|
|
135
|
+
domain: z.ZodString;
|
|
136
|
+
token: z.ZodString;
|
|
137
|
+
dns: z.ZodObject<{
|
|
138
|
+
name: z.ZodString;
|
|
139
|
+
value: z.ZodString;
|
|
140
|
+
}, "strip", z.ZodTypeAny, {
|
|
141
|
+
value: string;
|
|
142
|
+
name: string;
|
|
143
|
+
}, {
|
|
144
|
+
value: string;
|
|
145
|
+
name: string;
|
|
146
|
+
}>;
|
|
147
|
+
wellKnown: z.ZodObject<{
|
|
148
|
+
url: z.ZodString;
|
|
149
|
+
body: z.ZodString;
|
|
150
|
+
}, "strip", z.ZodTypeAny, {
|
|
151
|
+
url: string;
|
|
152
|
+
body: string;
|
|
153
|
+
}, {
|
|
154
|
+
url: string;
|
|
155
|
+
body: string;
|
|
156
|
+
}>;
|
|
157
|
+
}, "strip", z.ZodTypeAny, {
|
|
158
|
+
domain: string;
|
|
159
|
+
token: string;
|
|
160
|
+
dns: {
|
|
161
|
+
value: string;
|
|
162
|
+
name: string;
|
|
163
|
+
};
|
|
164
|
+
wellKnown: {
|
|
165
|
+
url: string;
|
|
166
|
+
body: string;
|
|
167
|
+
};
|
|
168
|
+
}, {
|
|
169
|
+
domain: string;
|
|
170
|
+
token: string;
|
|
171
|
+
dns: {
|
|
172
|
+
value: string;
|
|
173
|
+
name: string;
|
|
174
|
+
};
|
|
175
|
+
wellKnown: {
|
|
176
|
+
url: string;
|
|
177
|
+
body: string;
|
|
178
|
+
};
|
|
179
|
+
}>;
|
|
180
|
+
export type DomainVerificationInstructions = z.infer<typeof domainVerificationInstructionsSchema>;
|
|
181
|
+
/**
|
|
182
|
+
* One linked authentication method. Mirrors a `User.authMethods[]` entry.
|
|
183
|
+
* `verificationMethodId` is present for `identity` methods (a key) and absent
|
|
184
|
+
* for `password`/social methods, linking the auth method to its DID
|
|
185
|
+
* verification-method fragment.
|
|
186
|
+
*/
|
|
187
|
+
export interface AuthMethodEntry {
|
|
188
|
+
type: 'identity' | 'password' | 'google' | 'apple' | 'github';
|
|
189
|
+
linkedAt: string | Date;
|
|
190
|
+
verificationMethodId?: string;
|
|
191
|
+
}
|
|
192
|
+
export declare const authMethodEntrySchema: z.ZodType<AuthMethodEntry>;
|
|
193
|
+
/**
|
|
194
|
+
* Wire shape of `GET /auth/methods` — the account's DID plus every linked
|
|
195
|
+
* authentication method.
|
|
196
|
+
*/
|
|
197
|
+
export interface AuthMethodsResponse {
|
|
198
|
+
did: string;
|
|
199
|
+
methods: AuthMethodEntry[];
|
|
200
|
+
}
|
|
201
|
+
export declare const authMethodsResponseSchema: z.ZodType<AuthMethodsResponse>;
|
|
202
|
+
/**
|
|
203
|
+
* A cryptographic attestation over the canonical-JSON of an export bundle.
|
|
204
|
+
* Reused for both the mandatory Oxy provenance `attestation` (signed with the
|
|
205
|
+
* Oxy custodial key) and the optional client `proof` (signed with the user's
|
|
206
|
+
* own key when they hold one). `signedAt` is epoch milliseconds.
|
|
207
|
+
*/
|
|
208
|
+
export interface ExportAttestation {
|
|
209
|
+
issuer: string;
|
|
210
|
+
publicKey: string;
|
|
211
|
+
alg: 'ES256K-DER-SHA256';
|
|
212
|
+
signature: string;
|
|
213
|
+
signedAt: number;
|
|
214
|
+
}
|
|
215
|
+
export declare const exportAttestationSchema: z.ZodType<ExportAttestation>;
|
|
216
|
+
/**
|
|
217
|
+
* The signed, open-format data-export bundle from `GET /users/me/export`. A
|
|
218
|
+
* portable snapshot of the account: its DID document, profile, verified
|
|
219
|
+
* domains, auth methods (no secrets), published signed records, per-app data,
|
|
220
|
+
* and social graph.
|
|
221
|
+
*
|
|
222
|
+
* `attestation` is the Oxy custodial provenance signature. It is `null` only
|
|
223
|
+
* when the Oxy custodial signing key (`OXY_PRIVATE_KEY`) is unset (dev /
|
|
224
|
+
* pre-prod); in production it is always present. Carries an optional client
|
|
225
|
+
* `proof` when the user signed the bundle with their own key.
|
|
226
|
+
*/
|
|
227
|
+
export interface ExportBundle {
|
|
228
|
+
'$schema': string;
|
|
229
|
+
exportedAt: string;
|
|
230
|
+
did: string;
|
|
231
|
+
didDocument: DidDocument;
|
|
232
|
+
profile: Record<string, unknown>;
|
|
233
|
+
verifiedDomains: VerifiedDomain[];
|
|
234
|
+
authMethods: AuthMethodEntry[];
|
|
235
|
+
signedRecords: SignedRecordEnvelope[];
|
|
236
|
+
appData: Record<string, unknown>[];
|
|
237
|
+
social: {
|
|
238
|
+
following: string[];
|
|
239
|
+
followers: string[];
|
|
240
|
+
};
|
|
241
|
+
attestation: ExportAttestation | null;
|
|
242
|
+
proof?: ExportAttestation;
|
|
243
|
+
}
|
|
244
|
+
export declare const exportBundleSchema: z.ZodType<ExportBundle>;
|
package/dist/types/index.d.ts
CHANGED
|
@@ -17,3 +17,5 @@ export { fedcmTokenPayloadSchema, } from './fedcmToken';
|
|
|
17
17
|
export type { FedcmTokenPayload, } from './fedcmToken';
|
|
18
18
|
export { recommendationExcludeTypeSchema, recommendationBoostSchema, recommendationSignalWeightsSchema, recommendationRequestSchema, recommendationCountSchema, recommendationItemSchema, recommendationResponseSchema, appEndorsementInputSchema, appInterestInputSchema, appUserSignalIngestSchema, } from './recommendations';
|
|
19
19
|
export type { RecommendationExcludeType, RecommendationBoost, RecommendationSignalWeights, RecommendationRequest, RecommendationCount, RecommendationItem, RecommendationResponse, AppEndorsementInput, AppInterestInput, AppUserSignalIngest, } from './recommendations';
|
|
20
|
+
export { verificationMethodSchema, didServiceSchema, didDocumentSchema, signedRecordEnvelopeSchema, verifiedDomainSchema, domainVerificationRequestSchema, domainVerificationInstructionsSchema, authMethodEntrySchema, authMethodsResponseSchema, exportAttestationSchema, exportBundleSchema, } from './identity';
|
|
21
|
+
export type { VerificationMethod, DidService, DidDocument, SignedRecordEnvelope, VerifiedDomain, DomainVerificationRequest, DomainVerificationInstructions, AuthMethodEntry, AuthMethodsResponse, ExportAttestation, ExportBundle, } from './identity';
|
|
@@ -164,11 +164,11 @@ export declare const recommendationCountSchema: z.ZodObject<{
|
|
|
164
164
|
followers: z.ZodNumber;
|
|
165
165
|
following: z.ZodNumber;
|
|
166
166
|
}, "strip", z.ZodTypeAny, {
|
|
167
|
-
followers: number;
|
|
168
167
|
following: number;
|
|
169
|
-
}, {
|
|
170
168
|
followers: number;
|
|
169
|
+
}, {
|
|
171
170
|
following: number;
|
|
171
|
+
followers: number;
|
|
172
172
|
}>;
|
|
173
173
|
export type RecommendationCount = z.infer<typeof recommendationCountSchema>;
|
|
174
174
|
/**
|
|
@@ -197,11 +197,11 @@ export declare const recommendationItemSchema: z.ZodObject<{
|
|
|
197
197
|
followers: z.ZodNumber;
|
|
198
198
|
following: z.ZodNumber;
|
|
199
199
|
}, "strip", z.ZodTypeAny, {
|
|
200
|
-
followers: number;
|
|
201
200
|
following: number;
|
|
202
|
-
}, {
|
|
203
201
|
followers: number;
|
|
202
|
+
}, {
|
|
204
203
|
following: number;
|
|
204
|
+
followers: number;
|
|
205
205
|
}>;
|
|
206
206
|
}, "passthrough", z.ZodTypeAny, z.objectOutputType<{
|
|
207
207
|
id: z.ZodString;
|
|
@@ -222,11 +222,11 @@ export declare const recommendationItemSchema: z.ZodObject<{
|
|
|
222
222
|
followers: z.ZodNumber;
|
|
223
223
|
following: z.ZodNumber;
|
|
224
224
|
}, "strip", z.ZodTypeAny, {
|
|
225
|
-
followers: number;
|
|
226
225
|
following: number;
|
|
227
|
-
}, {
|
|
228
226
|
followers: number;
|
|
227
|
+
}, {
|
|
229
228
|
following: number;
|
|
229
|
+
followers: number;
|
|
230
230
|
}>;
|
|
231
231
|
}, z.ZodTypeAny, "passthrough">, z.objectInputType<{
|
|
232
232
|
id: z.ZodString;
|
|
@@ -247,11 +247,11 @@ export declare const recommendationItemSchema: z.ZodObject<{
|
|
|
247
247
|
followers: z.ZodNumber;
|
|
248
248
|
following: z.ZodNumber;
|
|
249
249
|
}, "strip", z.ZodTypeAny, {
|
|
250
|
-
followers: number;
|
|
251
250
|
following: number;
|
|
252
|
-
}, {
|
|
253
251
|
followers: number;
|
|
252
|
+
}, {
|
|
254
253
|
following: number;
|
|
254
|
+
followers: number;
|
|
255
255
|
}>;
|
|
256
256
|
}, z.ZodTypeAny, "passthrough">>;
|
|
257
257
|
export type RecommendationItem = z.infer<typeof recommendationItemSchema>;
|
|
@@ -275,11 +275,11 @@ export declare const recommendationResponseSchema: z.ZodArray<z.ZodObject<{
|
|
|
275
275
|
followers: z.ZodNumber;
|
|
276
276
|
following: z.ZodNumber;
|
|
277
277
|
}, "strip", z.ZodTypeAny, {
|
|
278
|
-
followers: number;
|
|
279
278
|
following: number;
|
|
280
|
-
}, {
|
|
281
279
|
followers: number;
|
|
280
|
+
}, {
|
|
282
281
|
following: number;
|
|
282
|
+
followers: number;
|
|
283
283
|
}>;
|
|
284
284
|
}, "passthrough", z.ZodTypeAny, z.objectOutputType<{
|
|
285
285
|
id: z.ZodString;
|
|
@@ -300,11 +300,11 @@ export declare const recommendationResponseSchema: z.ZodArray<z.ZodObject<{
|
|
|
300
300
|
followers: z.ZodNumber;
|
|
301
301
|
following: z.ZodNumber;
|
|
302
302
|
}, "strip", z.ZodTypeAny, {
|
|
303
|
-
followers: number;
|
|
304
303
|
following: number;
|
|
305
|
-
}, {
|
|
306
304
|
followers: number;
|
|
305
|
+
}, {
|
|
307
306
|
following: number;
|
|
307
|
+
followers: number;
|
|
308
308
|
}>;
|
|
309
309
|
}, z.ZodTypeAny, "passthrough">, z.objectInputType<{
|
|
310
310
|
id: z.ZodString;
|
|
@@ -325,11 +325,11 @@ export declare const recommendationResponseSchema: z.ZodArray<z.ZodObject<{
|
|
|
325
325
|
followers: z.ZodNumber;
|
|
326
326
|
following: z.ZodNumber;
|
|
327
327
|
}, "strip", z.ZodTypeAny, {
|
|
328
|
-
followers: number;
|
|
329
328
|
following: number;
|
|
330
|
-
}, {
|
|
331
329
|
followers: number;
|
|
330
|
+
}, {
|
|
332
331
|
following: number;
|
|
332
|
+
followers: number;
|
|
333
333
|
}>;
|
|
334
334
|
}, z.ZodTypeAny, "passthrough">>, "many">;
|
|
335
335
|
export type RecommendationResponse = z.infer<typeof recommendationResponseSchema>;
|