@oxyhq/contracts 0.3.0 → 0.4.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/civic.js +163 -0
- package/dist/cjs/identity.js +84 -3
- package/dist/cjs/index.js +23 -1
- package/dist/esm/.tsbuildinfo +1 -1
- package/dist/esm/civic.js +160 -0
- package/dist/esm/identity.js +84 -3
- package/dist/esm/index.js +5 -0
- package/dist/types/.tsbuildinfo +1 -1
- package/dist/types/civic.d.ts +338 -0
- package/dist/types/identity.d.ts +37 -2
- package/dist/types/index.d.ts +3 -1
- package/dist/types/sessionStatus.d.ts +2 -2
- package/dist/types/userResponse.d.ts +22 -22
- package/package.json +1 -1
|
@@ -0,0 +1,338 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Civic / Commons API contracts (Fase 1 — DNI + crypto-owned reputation).
|
|
3
|
+
*
|
|
4
|
+
* SINGLE SOURCE OF TRUTH for the wire shape of the public "DNI" card a Commons
|
|
5
|
+
* user shows (and others scan): the user's DID, display identity, trust tier,
|
|
6
|
+
* personhood status, verified domains, and credential badges — sealed with an
|
|
7
|
+
* Oxy custodial attestation so a scanner can verify it OFFLINE against the Oxy
|
|
8
|
+
* public key (the same `ES256K-DER-SHA256` scheme as the signed data export).
|
|
9
|
+
*
|
|
10
|
+
* The QR encodes ONLY the DID (`oxydni://card?did=…`) — never trust data — so a
|
|
11
|
+
* card cannot be spoofed by crafting a QR; the scanner resolves the signed card
|
|
12
|
+
* server-side and verifies the Oxy signature. The attestation is computed over
|
|
13
|
+
* the canonical-JSON of the `card` object, so a consumer re-canonicalizes the
|
|
14
|
+
* card it received and verifies `attestation.signature` against
|
|
15
|
+
* `attestation.publicKey` (which MUST be a current verification method of the
|
|
16
|
+
* Oxy DID).
|
|
17
|
+
*
|
|
18
|
+
* Explicit-`interface` exports (PublicCard, SignedPublicCard) follow the same
|
|
19
|
+
* node-resolution rationale as `UserNameResponse` / the identity contracts: a
|
|
20
|
+
* nested `z.infer<>` can degrade to `{}` under a consumer's
|
|
21
|
+
* `moduleResolution: "node"`, so the load-bearing shapes are declared as literal
|
|
22
|
+
* interfaces and the runtime schemas are annotated `z.ZodType<Interface>`.
|
|
23
|
+
*
|
|
24
|
+
* The `attestation` reuses the export-bundle `ExportAttestation` shape from
|
|
25
|
+
* `./identity` (mirrored, not duplicated): `{ issuer, publicKey, alg, signature,
|
|
26
|
+
* signedAt }`. It is `null` ONLY when the Oxy signing key is unconfigured (dev).
|
|
27
|
+
*
|
|
28
|
+
* Platform-agnostic — zod only, no react/react-native/expo, ESM-safe.
|
|
29
|
+
*/
|
|
30
|
+
import { z } from 'zod';
|
|
31
|
+
import { type ExportAttestation } from './identity';
|
|
32
|
+
/**
|
|
33
|
+
* The trust tier shown on the card. Mirrors the API's reputation `TRUST_TIERS`
|
|
34
|
+
* (lowest → highest, plus the punitive `restricted`). Declared as a literal
|
|
35
|
+
* union here (NOT imported from the API) so the contract package stays
|
|
36
|
+
* dependency-free while giving consumers an exhaustive type to render against.
|
|
37
|
+
*/
|
|
38
|
+
export type CardTrustTier = 'restricted' | 'new' | 'trusted' | 'high_trust' | 'verified';
|
|
39
|
+
/**
|
|
40
|
+
* Personhood verification status. `unverified` for everyone in Fase 1; the
|
|
41
|
+
* web-of-trust pipeline (Fase 3) graduates users to `pending` / `verified`.
|
|
42
|
+
*/
|
|
43
|
+
export type PersonhoodStatus = 'unverified' | 'pending' | 'verified';
|
|
44
|
+
/**
|
|
45
|
+
* The public, render-ready "DNI" card for a Commons user. Assembled server-side
|
|
46
|
+
* from the canonical account fields and signed by Oxy.
|
|
47
|
+
*
|
|
48
|
+
* - `name` is the canonical composed display name (`name.displayName`) — a
|
|
49
|
+
* consumer renders it directly and NEVER recomposes it from `name.first` etc.
|
|
50
|
+
* - `username` / `avatarUrl` are OPTIONAL (omitted entirely for accounts that
|
|
51
|
+
* have none) — `avatarUrl` is the public `cloud.oxy.so` URL when an avatar is
|
|
52
|
+
* set. The server emits ONLY present keys so a consumer re-canonicalizing the
|
|
53
|
+
* card it received derives byte-identical bytes for signature verification.
|
|
54
|
+
* - `trustTier` is the user's current reputation tier; `personhoodStatus` is
|
|
55
|
+
* `unverified` for everyone in Fase 1 (Fase 3 graduates users) and
|
|
56
|
+
* `credentialBadges` is `[]` until verifiable credentials land (Fase 4).
|
|
57
|
+
* - `issuedAt` is epoch milliseconds — part of the signed bytes (the attestation
|
|
58
|
+
* covers the canonical-JSON of the whole card), so a scanner can detect a
|
|
59
|
+
* stale/replayed card.
|
|
60
|
+
*/
|
|
61
|
+
export interface PublicCard {
|
|
62
|
+
did: string;
|
|
63
|
+
userId: string;
|
|
64
|
+
name: string;
|
|
65
|
+
username?: string;
|
|
66
|
+
avatarUrl?: string;
|
|
67
|
+
trustTier: CardTrustTier;
|
|
68
|
+
personhoodStatus: PersonhoodStatus;
|
|
69
|
+
verifiedDomains: string[];
|
|
70
|
+
credentialBadges: string[];
|
|
71
|
+
issuedAt: number;
|
|
72
|
+
}
|
|
73
|
+
export declare const publicCardSchema: z.ZodType<PublicCard>;
|
|
74
|
+
/**
|
|
75
|
+
* A {@link PublicCard} sealed with an Oxy custodial attestation. The attestation
|
|
76
|
+
* is an `ES256K-DER-SHA256` signature over the canonical-JSON of `card` (the
|
|
77
|
+
* exact `ExportAttestation` shape reused from the signed data export). It is
|
|
78
|
+
* `null` ONLY when the Oxy signing key (`OXY_PRIVATE_KEY`/`OXY_PUBLIC_KEY`) is
|
|
79
|
+
* unconfigured (dev / pre-prod) — in production it is always present. A consumer
|
|
80
|
+
* MUST check `attestation !== null` and that `attestation.publicKey` is the Oxy
|
|
81
|
+
* custodial key before trusting the card.
|
|
82
|
+
*/
|
|
83
|
+
export interface SignedPublicCard {
|
|
84
|
+
card: PublicCard;
|
|
85
|
+
attestation: ExportAttestation | null;
|
|
86
|
+
}
|
|
87
|
+
export declare const signedPublicCardSchema: z.ZodType<SignedPublicCard>;
|
|
88
|
+
/**
|
|
89
|
+
* The `record` payload of a `real_life_attestation` signed envelope. The
|
|
90
|
+
* COUNTERPARTY (B) signs this with their OWN key as a self-issued v2 record on
|
|
91
|
+
* THEIR chain (`subject === issuer === B.did`); the subject being attested (A)
|
|
92
|
+
* is referenced by `about` (A's DID). The server resolves `about` → A's account
|
|
93
|
+
* and awards A the HIGH-weight `real_life_attested` points, recording B as the
|
|
94
|
+
* attestor (so B can be slashed if A's action is later found fraudulent).
|
|
95
|
+
*
|
|
96
|
+
* - `context` is an opaque interaction id from the QR (`oxydni://attest?ctx=…`).
|
|
97
|
+
* - `nonce` is the single-use replay guard from the QR; `exp` is its expiry
|
|
98
|
+
* (epoch ms) — both are part of the signed bytes.
|
|
99
|
+
* - `geohash` (optional) is a coarse co-location proof; `biometricOk` (optional)
|
|
100
|
+
* signals B's device biometric gate fired before signing (a support signal,
|
|
101
|
+
* never sufficient alone).
|
|
102
|
+
*/
|
|
103
|
+
export interface RealLifeAttestationRecord {
|
|
104
|
+
about: string;
|
|
105
|
+
context: string;
|
|
106
|
+
nonce: string;
|
|
107
|
+
exp: number;
|
|
108
|
+
geohash?: string;
|
|
109
|
+
biometricOk?: boolean;
|
|
110
|
+
}
|
|
111
|
+
export declare const realLifeAttestationRecordSchema: z.ZodType<RealLifeAttestationRecord>;
|
|
112
|
+
/**
|
|
113
|
+
* The result of `POST /civic/attestations` on success: the stored attestation
|
|
114
|
+
* record id (B's envelope), the subject + attestor account ids, and the points
|
|
115
|
+
* awarded to the subject.
|
|
116
|
+
*/
|
|
117
|
+
export interface RealLifeAttestationResult {
|
|
118
|
+
accepted: true;
|
|
119
|
+
recordId: string;
|
|
120
|
+
subjectUserId: string;
|
|
121
|
+
attestorUserId: string;
|
|
122
|
+
points: number;
|
|
123
|
+
}
|
|
124
|
+
export declare const realLifeAttestationResultSchema: z.ZodType<RealLifeAttestationResult>;
|
|
125
|
+
/** A juror's verdict on a validation request. */
|
|
126
|
+
export type ValidationVerdict = 'valid' | 'invalid' | 'abstain';
|
|
127
|
+
/** The lifecycle status of a validation request. */
|
|
128
|
+
export type ValidationRequestStatus = 'pending' | 'quorum_met' | 'validated' | 'rejected' | 'expired';
|
|
129
|
+
/**
|
|
130
|
+
* The `record` payload of a `validation_verdict` signed envelope — a juror's
|
|
131
|
+
* SELF-ISSUED verdict, bound to the request id + the canonical payload hash (so
|
|
132
|
+
* a verdict cannot be replayed onto a different request or an altered payload).
|
|
133
|
+
*/
|
|
134
|
+
export interface ValidationVerdictRecord {
|
|
135
|
+
requestId: string;
|
|
136
|
+
payloadHash: string;
|
|
137
|
+
verdict: ValidationVerdict;
|
|
138
|
+
}
|
|
139
|
+
export declare const validationVerdictRecordSchema: z.ZodType<ValidationVerdictRecord>;
|
|
140
|
+
/** Request body for opening a validation request (`POST /civic/validations`). */
|
|
141
|
+
export declare const validationOpenRequestSchema: z.ZodObject<{
|
|
142
|
+
subjectUserId: z.ZodString;
|
|
143
|
+
actionType: z.ZodString;
|
|
144
|
+
sourceActionId: z.ZodString;
|
|
145
|
+
payload: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
146
|
+
highValue: z.ZodOptional<z.ZodBoolean>;
|
|
147
|
+
}, "strip", z.ZodTypeAny, {
|
|
148
|
+
subjectUserId: string;
|
|
149
|
+
actionType: string;
|
|
150
|
+
sourceActionId: string;
|
|
151
|
+
payload: Record<string, unknown>;
|
|
152
|
+
highValue?: boolean | undefined;
|
|
153
|
+
}, {
|
|
154
|
+
subjectUserId: string;
|
|
155
|
+
actionType: string;
|
|
156
|
+
sourceActionId: string;
|
|
157
|
+
payload: Record<string, unknown>;
|
|
158
|
+
highValue?: boolean | undefined;
|
|
159
|
+
}>;
|
|
160
|
+
export type ValidationOpenRequest = z.infer<typeof validationOpenRequestSchema>;
|
|
161
|
+
/** The result of opening a validation request (`POST /civic/validations`). */
|
|
162
|
+
export interface ValidationOpenResult {
|
|
163
|
+
requestId: string;
|
|
164
|
+
selectedValidatorCount: number;
|
|
165
|
+
expiresAt: string;
|
|
166
|
+
}
|
|
167
|
+
export declare const validationOpenResultSchema: z.ZodType<ValidationOpenResult>;
|
|
168
|
+
/**
|
|
169
|
+
* A pending validation request as shown in a juror's inbox. `payload` is the
|
|
170
|
+
* claim the juror inspects; `payloadHash` is what their verdict must bind to.
|
|
171
|
+
*/
|
|
172
|
+
export interface ValidationRequestSummary {
|
|
173
|
+
id: string;
|
|
174
|
+
subjectUserId: string;
|
|
175
|
+
actionType: string;
|
|
176
|
+
payload: Record<string, unknown>;
|
|
177
|
+
payloadHash: string;
|
|
178
|
+
status: ValidationRequestStatus;
|
|
179
|
+
highValue: boolean;
|
|
180
|
+
expiresAt: string;
|
|
181
|
+
}
|
|
182
|
+
export declare const validationRequestSummarySchema: z.ZodType<ValidationRequestSummary>;
|
|
183
|
+
/** The result of casting a vote (`POST /civic/validations/:id/vote`). */
|
|
184
|
+
export interface ValidationVoteResult {
|
|
185
|
+
recorded: true;
|
|
186
|
+
requestId: string;
|
|
187
|
+
verdict: ValidationVerdict;
|
|
188
|
+
status: ValidationRequestStatus;
|
|
189
|
+
}
|
|
190
|
+
export declare const validationVoteResultSchema: z.ZodType<ValidationVoteResult>;
|
|
191
|
+
/**
|
|
192
|
+
* The `record` payload of a `personhood_vouch` signed envelope. The VOUCHER (B)
|
|
193
|
+
* signs this with their OWN key as a self-issued v2 record on THEIR chain
|
|
194
|
+
* (`subject === issuer === B.did`); the person being vouched for (A) is
|
|
195
|
+
* referenced by `about` (A's DID). The server resolves `about` → A's account,
|
|
196
|
+
* stakes the voucher, awards A the `personhood_vouched` points, and recomputes
|
|
197
|
+
* A's personhood.
|
|
198
|
+
*
|
|
199
|
+
* - `about` is A's DID (`did:web:oxy.so:u:<userId>`).
|
|
200
|
+
* - `context` (optional) is an opaque note from the vouching UI.
|
|
201
|
+
* - `stake` (optional) is the voucher's chosen stake; the server clamps it into
|
|
202
|
+
* `[PERSONHOOD_VOUCH_MIN_STAKE, PERSONHOOD_VOUCH_MAX_STAKE]` and defaults it
|
|
203
|
+
* when omitted. (Note: the wire field is `stake`, NOT `stakeAmount` — the
|
|
204
|
+
* latter is the server's clamped, awarded value echoed in {@link VouchResult}.)
|
|
205
|
+
*/
|
|
206
|
+
export interface PersonhoodVouchRecord {
|
|
207
|
+
about: string;
|
|
208
|
+
context?: string;
|
|
209
|
+
stake?: number;
|
|
210
|
+
}
|
|
211
|
+
export declare const personhoodVouchRecordSchema: z.ZodType<PersonhoodVouchRecord>;
|
|
212
|
+
/**
|
|
213
|
+
* The signal sub-scores behind a personhood score (audit / UI breakdown),
|
|
214
|
+
* mirroring the API `PersonhoodStatus` model's embedded `breakdown`.
|
|
215
|
+
*/
|
|
216
|
+
export interface PersonhoodBreakdown {
|
|
217
|
+
/** Saturated [0,1] vouch signal from the weighted vouch sum. */
|
|
218
|
+
vouchSignal: number;
|
|
219
|
+
/** Saturated [0,1] real-life-attestation signal. */
|
|
220
|
+
realLifeSignal: number;
|
|
221
|
+
/** 1 when the account is biometric-bound, else 0. */
|
|
222
|
+
biometricSignal: number;
|
|
223
|
+
/** Weighted blend of the three signals before the sybil penalty. */
|
|
224
|
+
evidence: number;
|
|
225
|
+
/** The [0,1] sybil penalty subtracted from the evidence. */
|
|
226
|
+
sybilPenalty: number;
|
|
227
|
+
/** True when the score came from the seed-verifier genesis short-circuit. */
|
|
228
|
+
seed: boolean;
|
|
229
|
+
}
|
|
230
|
+
export declare const personhoodBreakdownSchema: z.ZodType<PersonhoodBreakdown>;
|
|
231
|
+
/**
|
|
232
|
+
* The public personhood status snapshot returned by
|
|
233
|
+
* `GET /civic/personhood/:userId` (and `POST /civic/personhood/:userId/recompute`).
|
|
234
|
+
* Mirrors the API `PersonhoodStatus` model's serialized response exactly — a
|
|
235
|
+
* cached, recomputable proof-of-personhood snapshot.
|
|
236
|
+
*
|
|
237
|
+
* - `score` is in `[0,1]`; `isRealPerson` is `score >= θ`.
|
|
238
|
+
* - `breakdown` is `null` ONLY on a public read of a user who has no status
|
|
239
|
+
* document yet (the zeroed `unverified` shape); otherwise it is the full
|
|
240
|
+
* {@link PersonhoodBreakdown}.
|
|
241
|
+
* - `updatedAt` is the ISO-8601 timestamp of the last recompute, or `null` when
|
|
242
|
+
* no status document exists yet. (Distinct from the card's coarse
|
|
243
|
+
* {@link PersonhoodStatus} enum, which is `'unverified' | 'pending' |
|
|
244
|
+
* 'verified'`.)
|
|
245
|
+
*/
|
|
246
|
+
export interface PersonhoodStatusResult {
|
|
247
|
+
userId: string;
|
|
248
|
+
score: number;
|
|
249
|
+
isRealPerson: boolean;
|
|
250
|
+
vouchCount: number;
|
|
251
|
+
realLifeCount: number;
|
|
252
|
+
biometricBound: boolean;
|
|
253
|
+
sybilPenalty: number;
|
|
254
|
+
breakdown: PersonhoodBreakdown | null;
|
|
255
|
+
updatedAt: string | null;
|
|
256
|
+
}
|
|
257
|
+
export declare const personhoodStatusResultSchema: z.ZodType<PersonhoodStatusResult>;
|
|
258
|
+
/**
|
|
259
|
+
* The result of `POST /civic/personhood/vouch` on success: the stored vouch
|
|
260
|
+
* record id (the voucher's envelope), the subject + voucher account ids, the
|
|
261
|
+
* clamped stake the server recorded, and the points awarded to the subject.
|
|
262
|
+
*/
|
|
263
|
+
export interface VouchResult {
|
|
264
|
+
accepted: true;
|
|
265
|
+
recordId: string;
|
|
266
|
+
subjectUserId: string;
|
|
267
|
+
voucherUserId: string;
|
|
268
|
+
stakeAmount: number;
|
|
269
|
+
points: number;
|
|
270
|
+
}
|
|
271
|
+
export declare const vouchResultSchema: z.ZodType<VouchResult>;
|
|
272
|
+
/** The lifecycle status of a stored verifiable credential. */
|
|
273
|
+
export type CredentialStatus = 'active' | 'revoked' | 'expired';
|
|
274
|
+
/**
|
|
275
|
+
* The `record` payload of a `credential` signed envelope — the W3C-VC-flavoured
|
|
276
|
+
* claim the issuer signs.
|
|
277
|
+
*
|
|
278
|
+
* - `about` is the HOLDER's DID (`did:web:oxy.so:u:<userId>`), i.e. the W3C
|
|
279
|
+
* `credentialSubject.id`. (Named `about` to match the sibling civic records
|
|
280
|
+
* and to avoid colliding with the envelope's own chain `subject` field.)
|
|
281
|
+
* - `types` are the VC type tags; `'VerifiableCredential'` MUST be present as the
|
|
282
|
+
* base type, with at least one specific type (e.g. `'EmploymentCredential'`).
|
|
283
|
+
* - `claims` is the arbitrary, issuer-asserted claim set about the holder.
|
|
284
|
+
* - `expiresAt` (optional) is epoch milliseconds; absent = non-expiring. It is
|
|
285
|
+
* part of the signed bytes, so a holder cannot extend a credential's validity.
|
|
286
|
+
*/
|
|
287
|
+
export interface CredentialRecord {
|
|
288
|
+
about: string;
|
|
289
|
+
types: string[];
|
|
290
|
+
claims: Record<string, unknown>;
|
|
291
|
+
expiresAt?: number;
|
|
292
|
+
}
|
|
293
|
+
export declare const credentialRecordSchema: z.ZodType<CredentialRecord>;
|
|
294
|
+
/**
|
|
295
|
+
* The serialized verifiable credential as returned by the list + verify routes.
|
|
296
|
+
* `issuerUserId` is present only for user-issued credentials (absent for
|
|
297
|
+
* app/org-issued credentials signed by the Oxy custodial key). All timestamps
|
|
298
|
+
* are epoch milliseconds.
|
|
299
|
+
*/
|
|
300
|
+
export interface VerifiableCredentialResponse {
|
|
301
|
+
id: string;
|
|
302
|
+
recordId: string;
|
|
303
|
+
holderUserId: string;
|
|
304
|
+
holderDid: string;
|
|
305
|
+
issuerUserId?: string;
|
|
306
|
+
issuerDid: string;
|
|
307
|
+
types: string[];
|
|
308
|
+
claims: Record<string, unknown>;
|
|
309
|
+
status: CredentialStatus;
|
|
310
|
+
issuedAt: number;
|
|
311
|
+
expiresAt?: number;
|
|
312
|
+
revokedAt?: number;
|
|
313
|
+
}
|
|
314
|
+
export declare const verifiableCredentialResponseSchema: z.ZodType<VerifiableCredentialResponse>;
|
|
315
|
+
/** The result of `POST /civic/credentials` on success. */
|
|
316
|
+
export interface CredentialIssueResult {
|
|
317
|
+
accepted: true;
|
|
318
|
+
credential: VerifiableCredentialResponse;
|
|
319
|
+
}
|
|
320
|
+
export declare const credentialIssueResultSchema: z.ZodType<CredentialIssueResult>;
|
|
321
|
+
/** The result of `GET /civic/credentials/:holderUserId` (list). */
|
|
322
|
+
export interface CredentialListResult {
|
|
323
|
+
credentials: VerifiableCredentialResponse[];
|
|
324
|
+
}
|
|
325
|
+
export declare const credentialListResultSchema: z.ZodType<CredentialListResult>;
|
|
326
|
+
/**
|
|
327
|
+
* The result of `GET /civic/credentials/by-record/:recordId/verify`. `valid` is
|
|
328
|
+
* `true` ONLY when the signature verifies against a CURRENT verification method
|
|
329
|
+
* of the issuer DID AND the credential is neither revoked nor expired. `reason`
|
|
330
|
+
* is a stable, machine-readable rejection code when `valid` is `false`.
|
|
331
|
+
* `credential` is `null` when no credential exists for the record id.
|
|
332
|
+
*/
|
|
333
|
+
export interface CredentialVerifyResult {
|
|
334
|
+
valid: boolean;
|
|
335
|
+
reason?: string;
|
|
336
|
+
credential: VerifiableCredentialResponse | null;
|
|
337
|
+
}
|
|
338
|
+
export declare const credentialVerifyResultSchema: z.ZodType<CredentialVerifyResult>;
|
package/dist/types/identity.d.ts
CHANGED
|
@@ -85,20 +85,55 @@ export interface DidDocument {
|
|
|
85
85
|
service: DidService[];
|
|
86
86
|
}
|
|
87
87
|
export declare const didDocumentSchema: z.ZodType<DidDocument>;
|
|
88
|
+
/**
|
|
89
|
+
* The category of a signed record. v1 only ever carried `identity` / `profile`
|
|
90
|
+
* (already in production); v2 widens the union with the civic record types
|
|
91
|
+
* (reputation attestations, real-life / peer validations, personhood vouches,
|
|
92
|
+
* verifiable credentials) and the user-node registration record. The signing
|
|
93
|
+
* input includes `type`, so this union is part of the signed bytes.
|
|
94
|
+
*/
|
|
95
|
+
export type SignedRecordType = 'identity' | 'profile' | 'reputation_attestation' | 'real_life_attestation' | 'validation_verdict' | 'personhood_vouch' | 'credential' | 'node';
|
|
88
96
|
/**
|
|
89
97
|
* A signed record envelope. `record` is the arbitrary payload; the signing
|
|
90
98
|
* input is the canonical-JSON of every envelope field EXCEPT `publicKey` and
|
|
91
99
|
* `signature`. `subject` and `issuer` are DIDs (the subject the record is about
|
|
92
100
|
* and the signer's DID — equal for self-issued records, `OXY_DID` for a
|
|
93
101
|
* custodial provenance attestation). `issuedAt` is epoch milliseconds.
|
|
102
|
+
*
|
|
103
|
+
* ## Versioning
|
|
104
|
+
*
|
|
105
|
+
* - **v1** is the original shape (`{version, type, subject, issuer, record,
|
|
106
|
+
* issuedAt}` + `publicKey/alg/signature`). It carries NONE of the v2 chain
|
|
107
|
+
* fields and remains accepted unchanged — every `identity`/`profile` record
|
|
108
|
+
* already in production verifies byte-identically.
|
|
109
|
+
* - **v2** adds a per-subject hash-chain (an append-only "personal blockchain"
|
|
110
|
+
* of a single signer, no consensus/mining). The four chain fields are part of
|
|
111
|
+
* the signed bytes (so the chain cannot be forged):
|
|
112
|
+
* - `seq` — strictly-increasing sequence number per subject.
|
|
113
|
+
* - `prev` — the `recordId` (content address) of the previous record in this
|
|
114
|
+
* subject's chain, or `null` at genesis.
|
|
115
|
+
* - `collection` + `rkey` — an AtProto-style record key (e.g.
|
|
116
|
+
* `collection: 'app.oxy.identity'`, `rkey: 'self'`) used for
|
|
117
|
+
* materialization and last-writer-wins reconciliation.
|
|
118
|
+
*
|
|
119
|
+
* The chain fields are OPTIONAL on the interface so v1 envelopes (which omit
|
|
120
|
+
* them) still type-check; the schema enforces "present iff version === 2".
|
|
94
121
|
*/
|
|
95
122
|
export interface SignedRecordEnvelope {
|
|
96
|
-
version: 1;
|
|
97
|
-
type:
|
|
123
|
+
version: 1 | 2;
|
|
124
|
+
type: SignedRecordType;
|
|
98
125
|
subject: string;
|
|
99
126
|
issuer: string;
|
|
100
127
|
record: Record<string, unknown>;
|
|
101
128
|
issuedAt: number;
|
|
129
|
+
/** v2 only: strictly-increasing sequence number for this subject's chain. */
|
|
130
|
+
seq?: number;
|
|
131
|
+
/** v2 only: `recordId` of the previous record in the chain, `null` at genesis. */
|
|
132
|
+
prev?: string | null;
|
|
133
|
+
/** v2 only: AtProto-style collection namespace (e.g. `app.oxy.identity`). */
|
|
134
|
+
collection?: string;
|
|
135
|
+
/** v2 only: AtProto-style record key within the collection (e.g. `self`). */
|
|
136
|
+
rkey?: string;
|
|
102
137
|
publicKey: string;
|
|
103
138
|
alg: 'ES256K-DER-SHA256';
|
|
104
139
|
signature: string;
|
package/dist/types/index.d.ts
CHANGED
|
@@ -18,4 +18,6 @@ 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
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';
|
|
21
|
+
export type { VerificationMethod, DidService, DidDocument, SignedRecordEnvelope, SignedRecordType, VerifiedDomain, DomainVerificationRequest, DomainVerificationInstructions, AuthMethodEntry, AuthMethodsResponse, ExportAttestation, ExportBundle, } from './identity';
|
|
22
|
+
export { publicCardSchema, signedPublicCardSchema, realLifeAttestationRecordSchema, realLifeAttestationResultSchema, validationVerdictRecordSchema, validationOpenRequestSchema, validationOpenResultSchema, validationRequestSummarySchema, validationVoteResultSchema, personhoodVouchRecordSchema, personhoodBreakdownSchema, personhoodStatusResultSchema, vouchResultSchema, credentialRecordSchema, verifiableCredentialResponseSchema, credentialIssueResultSchema, credentialListResultSchema, credentialVerifyResultSchema, } from './civic';
|
|
23
|
+
export type { CardTrustTier, PersonhoodStatus, PublicCard, SignedPublicCard, RealLifeAttestationRecord, RealLifeAttestationResult, ValidationVerdict, ValidationRequestStatus, ValidationVerdictRecord, ValidationOpenRequest, ValidationOpenResult, ValidationRequestSummary, ValidationVoteResult, PersonhoodVouchRecord, PersonhoodBreakdown, PersonhoodStatusResult, VouchResult, CredentialStatus, CredentialRecord, VerifiableCredentialResponse, CredentialIssueResult, CredentialListResult, CredentialVerifyResult, } from './civic';
|
|
@@ -151,6 +151,7 @@ export declare const sessionStatusSchema: z.ZodObject<{
|
|
|
151
151
|
}, "strip", z.ZodTypeAny, {
|
|
152
152
|
status: string;
|
|
153
153
|
publicKey?: string | null | undefined;
|
|
154
|
+
userId?: string | null | undefined;
|
|
154
155
|
expiresAt?: string | undefined;
|
|
155
156
|
sessionId?: string | null | undefined;
|
|
156
157
|
authorized?: boolean | undefined;
|
|
@@ -167,10 +168,10 @@ export declare const sessionStatusSchema: z.ZodObject<{
|
|
|
167
168
|
websiteUrl?: string | undefined;
|
|
168
169
|
developerName?: string | undefined;
|
|
169
170
|
} | null | undefined;
|
|
170
|
-
userId?: string | null | undefined;
|
|
171
171
|
}, {
|
|
172
172
|
status: string;
|
|
173
173
|
publicKey?: string | null | undefined;
|
|
174
|
+
userId?: string | null | undefined;
|
|
174
175
|
expiresAt?: string | undefined;
|
|
175
176
|
sessionId?: string | null | undefined;
|
|
176
177
|
authorized?: boolean | undefined;
|
|
@@ -187,6 +188,5 @@ export declare const sessionStatusSchema: z.ZodObject<{
|
|
|
187
188
|
websiteUrl?: string | undefined;
|
|
188
189
|
developerName?: string | undefined;
|
|
189
190
|
} | null | undefined;
|
|
190
|
-
userId?: string | null | undefined;
|
|
191
191
|
}>;
|
|
192
192
|
export type SessionStatusResponse = z.infer<typeof sessionStatusSchema>;
|
|
@@ -413,9 +413,9 @@ export declare const refreshAllAccountSchema: z.ZodObject<{
|
|
|
413
413
|
verifiedDomains: z.ZodOptional<z.ZodArray<z.ZodType<import("./identity").VerifiedDomain, z.ZodTypeDef, import("./identity").VerifiedDomain>, "many">>;
|
|
414
414
|
}, z.ZodTypeAny, "passthrough">>;
|
|
415
415
|
}, "strip", z.ZodTypeAny, {
|
|
416
|
+
expiresAt: string;
|
|
416
417
|
authuser: number;
|
|
417
418
|
accessToken: string;
|
|
418
|
-
expiresAt: string;
|
|
419
419
|
sessionId: string;
|
|
420
420
|
user: {
|
|
421
421
|
name: UserNameResponse;
|
|
@@ -423,23 +423,23 @@ export declare const refreshAllAccountSchema: z.ZodObject<{
|
|
|
423
423
|
publicKey?: string | undefined;
|
|
424
424
|
did?: string | undefined;
|
|
425
425
|
verifiedDomains?: import("./identity").VerifiedDomain[] | undefined;
|
|
426
|
-
|
|
426
|
+
verified?: boolean | undefined;
|
|
427
427
|
username?: string | undefined;
|
|
428
|
+
_id?: string | undefined;
|
|
428
429
|
email?: string | undefined;
|
|
429
430
|
phone?: string | undefined;
|
|
430
431
|
address?: string | undefined;
|
|
431
432
|
birthday?: string | undefined;
|
|
432
433
|
avatar?: string | null | undefined;
|
|
433
434
|
color?: string | null | undefined;
|
|
434
|
-
verified?: boolean | undefined;
|
|
435
435
|
language?: string | undefined;
|
|
436
436
|
} & {
|
|
437
437
|
[k: string]: unknown;
|
|
438
438
|
};
|
|
439
439
|
}, {
|
|
440
|
+
expiresAt: string;
|
|
440
441
|
authuser: number;
|
|
441
442
|
accessToken: string;
|
|
442
|
-
expiresAt: string;
|
|
443
443
|
sessionId: string;
|
|
444
444
|
user: {
|
|
445
445
|
name: UserNameResponse;
|
|
@@ -447,15 +447,15 @@ export declare const refreshAllAccountSchema: z.ZodObject<{
|
|
|
447
447
|
publicKey?: string | undefined;
|
|
448
448
|
did?: string | undefined;
|
|
449
449
|
verifiedDomains?: import("./identity").VerifiedDomain[] | undefined;
|
|
450
|
-
|
|
450
|
+
verified?: boolean | undefined;
|
|
451
451
|
username?: string | undefined;
|
|
452
|
+
_id?: string | undefined;
|
|
452
453
|
email?: string | undefined;
|
|
453
454
|
phone?: string | undefined;
|
|
454
455
|
address?: string | undefined;
|
|
455
456
|
birthday?: string | undefined;
|
|
456
457
|
avatar?: string | null | undefined;
|
|
457
458
|
color?: string | null | undefined;
|
|
458
|
-
verified?: boolean | undefined;
|
|
459
459
|
language?: string | undefined;
|
|
460
460
|
} & {
|
|
461
461
|
[k: string]: unknown;
|
|
@@ -562,9 +562,9 @@ export declare const refreshAllResponseSchema: z.ZodObject<{
|
|
|
562
562
|
verifiedDomains: z.ZodOptional<z.ZodArray<z.ZodType<import("./identity").VerifiedDomain, z.ZodTypeDef, import("./identity").VerifiedDomain>, "many">>;
|
|
563
563
|
}, z.ZodTypeAny, "passthrough">>;
|
|
564
564
|
}, "strip", z.ZodTypeAny, {
|
|
565
|
+
expiresAt: string;
|
|
565
566
|
authuser: number;
|
|
566
567
|
accessToken: string;
|
|
567
|
-
expiresAt: string;
|
|
568
568
|
sessionId: string;
|
|
569
569
|
user: {
|
|
570
570
|
name: UserNameResponse;
|
|
@@ -572,23 +572,23 @@ export declare const refreshAllResponseSchema: z.ZodObject<{
|
|
|
572
572
|
publicKey?: string | undefined;
|
|
573
573
|
did?: string | undefined;
|
|
574
574
|
verifiedDomains?: import("./identity").VerifiedDomain[] | undefined;
|
|
575
|
-
|
|
575
|
+
verified?: boolean | undefined;
|
|
576
576
|
username?: string | undefined;
|
|
577
|
+
_id?: string | undefined;
|
|
577
578
|
email?: string | undefined;
|
|
578
579
|
phone?: string | undefined;
|
|
579
580
|
address?: string | undefined;
|
|
580
581
|
birthday?: string | undefined;
|
|
581
582
|
avatar?: string | null | undefined;
|
|
582
583
|
color?: string | null | undefined;
|
|
583
|
-
verified?: boolean | undefined;
|
|
584
584
|
language?: string | undefined;
|
|
585
585
|
} & {
|
|
586
586
|
[k: string]: unknown;
|
|
587
587
|
};
|
|
588
588
|
}, {
|
|
589
|
+
expiresAt: string;
|
|
589
590
|
authuser: number;
|
|
590
591
|
accessToken: string;
|
|
591
|
-
expiresAt: string;
|
|
592
592
|
sessionId: string;
|
|
593
593
|
user: {
|
|
594
594
|
name: UserNameResponse;
|
|
@@ -596,15 +596,15 @@ export declare const refreshAllResponseSchema: z.ZodObject<{
|
|
|
596
596
|
publicKey?: string | undefined;
|
|
597
597
|
did?: string | undefined;
|
|
598
598
|
verifiedDomains?: import("./identity").VerifiedDomain[] | undefined;
|
|
599
|
-
|
|
599
|
+
verified?: boolean | undefined;
|
|
600
600
|
username?: string | undefined;
|
|
601
|
+
_id?: string | undefined;
|
|
601
602
|
email?: string | undefined;
|
|
602
603
|
phone?: string | undefined;
|
|
603
604
|
address?: string | undefined;
|
|
604
605
|
birthday?: string | undefined;
|
|
605
606
|
avatar?: string | null | undefined;
|
|
606
607
|
color?: string | null | undefined;
|
|
607
|
-
verified?: boolean | undefined;
|
|
608
608
|
language?: string | undefined;
|
|
609
609
|
} & {
|
|
610
610
|
[k: string]: unknown;
|
|
@@ -612,9 +612,9 @@ export declare const refreshAllResponseSchema: z.ZodObject<{
|
|
|
612
612
|
}>, "many">;
|
|
613
613
|
}, "strip", z.ZodTypeAny, {
|
|
614
614
|
accounts: {
|
|
615
|
+
expiresAt: string;
|
|
615
616
|
authuser: number;
|
|
616
617
|
accessToken: string;
|
|
617
|
-
expiresAt: string;
|
|
618
618
|
sessionId: string;
|
|
619
619
|
user: {
|
|
620
620
|
name: UserNameResponse;
|
|
@@ -622,15 +622,15 @@ export declare const refreshAllResponseSchema: z.ZodObject<{
|
|
|
622
622
|
publicKey?: string | undefined;
|
|
623
623
|
did?: string | undefined;
|
|
624
624
|
verifiedDomains?: import("./identity").VerifiedDomain[] | undefined;
|
|
625
|
-
|
|
625
|
+
verified?: boolean | undefined;
|
|
626
626
|
username?: string | undefined;
|
|
627
|
+
_id?: string | undefined;
|
|
627
628
|
email?: string | undefined;
|
|
628
629
|
phone?: string | undefined;
|
|
629
630
|
address?: string | undefined;
|
|
630
631
|
birthday?: string | undefined;
|
|
631
632
|
avatar?: string | null | undefined;
|
|
632
633
|
color?: string | null | undefined;
|
|
633
|
-
verified?: boolean | undefined;
|
|
634
634
|
language?: string | undefined;
|
|
635
635
|
} & {
|
|
636
636
|
[k: string]: unknown;
|
|
@@ -638,9 +638,9 @@ export declare const refreshAllResponseSchema: z.ZodObject<{
|
|
|
638
638
|
}[];
|
|
639
639
|
}, {
|
|
640
640
|
accounts: {
|
|
641
|
+
expiresAt: string;
|
|
641
642
|
authuser: number;
|
|
642
643
|
accessToken: string;
|
|
643
|
-
expiresAt: string;
|
|
644
644
|
sessionId: string;
|
|
645
645
|
user: {
|
|
646
646
|
name: UserNameResponse;
|
|
@@ -648,15 +648,15 @@ export declare const refreshAllResponseSchema: z.ZodObject<{
|
|
|
648
648
|
publicKey?: string | undefined;
|
|
649
649
|
did?: string | undefined;
|
|
650
650
|
verifiedDomains?: import("./identity").VerifiedDomain[] | undefined;
|
|
651
|
-
|
|
651
|
+
verified?: boolean | undefined;
|
|
652
652
|
username?: string | undefined;
|
|
653
|
+
_id?: string | undefined;
|
|
653
654
|
email?: string | undefined;
|
|
654
655
|
phone?: string | undefined;
|
|
655
656
|
address?: string | undefined;
|
|
656
657
|
birthday?: string | undefined;
|
|
657
658
|
avatar?: string | null | undefined;
|
|
658
659
|
color?: string | null | undefined;
|
|
659
|
-
verified?: boolean | undefined;
|
|
660
660
|
language?: string | undefined;
|
|
661
661
|
} & {
|
|
662
662
|
[k: string]: unknown;
|
|
@@ -766,15 +766,15 @@ export declare const currentUserResponseSchema: z.ZodObject<{
|
|
|
766
766
|
publicKey?: string | undefined;
|
|
767
767
|
did?: string | undefined;
|
|
768
768
|
verifiedDomains?: import("./identity").VerifiedDomain[] | undefined;
|
|
769
|
-
|
|
769
|
+
verified?: boolean | undefined;
|
|
770
770
|
username?: string | undefined;
|
|
771
|
+
_id?: string | undefined;
|
|
771
772
|
email?: string | undefined;
|
|
772
773
|
phone?: string | undefined;
|
|
773
774
|
address?: string | undefined;
|
|
774
775
|
birthday?: string | undefined;
|
|
775
776
|
avatar?: string | null | undefined;
|
|
776
777
|
color?: string | null | undefined;
|
|
777
|
-
verified?: boolean | undefined;
|
|
778
778
|
language?: string | undefined;
|
|
779
779
|
} & {
|
|
780
780
|
[k: string]: unknown;
|
|
@@ -786,15 +786,15 @@ export declare const currentUserResponseSchema: z.ZodObject<{
|
|
|
786
786
|
publicKey?: string | undefined;
|
|
787
787
|
did?: string | undefined;
|
|
788
788
|
verifiedDomains?: import("./identity").VerifiedDomain[] | undefined;
|
|
789
|
-
|
|
789
|
+
verified?: boolean | undefined;
|
|
790
790
|
username?: string | undefined;
|
|
791
|
+
_id?: string | undefined;
|
|
791
792
|
email?: string | undefined;
|
|
792
793
|
phone?: string | undefined;
|
|
793
794
|
address?: string | undefined;
|
|
794
795
|
birthday?: string | undefined;
|
|
795
796
|
avatar?: string | null | undefined;
|
|
796
797
|
color?: string | null | undefined;
|
|
797
|
-
verified?: boolean | undefined;
|
|
798
798
|
language?: string | undefined;
|
|
799
799
|
} & {
|
|
800
800
|
[k: string]: unknown;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oxyhq/contracts",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "OxyHQ API contracts — single source of truth for request/response Zod schemas and inferred types, shared by the backend and the client SDKs",
|
|
5
5
|
"main": "dist/cjs/index.js",
|
|
6
6
|
"module": "dist/esm/index.js",
|