@oxyhq/contracts 0.14.2 → 0.16.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/deviceBoot.js +6 -12
- package/dist/cjs/identity.js +1 -1
- package/dist/cjs/index.js +13 -2
- package/dist/cjs/keyRecovery.js +91 -0
- package/dist/cjs/keyRotation.js +75 -0
- package/dist/esm/.tsbuildinfo +1 -1
- package/dist/esm/deviceBoot.js +6 -12
- package/dist/esm/identity.js +1 -1
- package/dist/esm/index.js +6 -0
- package/dist/esm/keyRecovery.js +88 -0
- package/dist/esm/keyRotation.js +72 -0
- package/dist/types/.tsbuildinfo +1 -1
- package/dist/types/deviceBoot.d.ts +10 -18
- package/dist/types/identity.d.ts +7 -7
- package/dist/types/index.d.ts +5 -1
- package/dist/types/keyRecovery.d.ts +138 -0
- package/dist/types/keyRotation.d.ts +103 -0
- package/package.json +2 -2
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* First-party login result contract.
|
|
3
3
|
*
|
|
4
|
-
* SINGLE SOURCE OF TRUTH for the first-party
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
4
|
+
* SINGLE SOURCE OF TRUTH for the first-party login result (the session arm). The
|
|
5
|
+
* API validates its OUTPUT against this schema; every consumer (`@oxyhq/core`'s
|
|
6
|
+
* auth mixin) validates its INPUT against the same definition, so producer and
|
|
7
|
+
* consumers cannot drift. Sign-in is passkey (WebAuthn) or Commons handoff —
|
|
8
|
+
* password and 2FA were removed, so the only outcome is a completed session.
|
|
8
9
|
*
|
|
9
10
|
* The device transport is `deviceId` + `deviceSecret` + `POST /session/device/token`
|
|
10
11
|
* (see `deviceSession.ts`). The legacy cookie/bootstrap/refresh-family lanes were
|
|
@@ -39,18 +40,9 @@ export interface SecurityAlert {
|
|
|
39
40
|
anomalies: SecurityAlertAnomaly[];
|
|
40
41
|
}
|
|
41
42
|
/**
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
|
|
45
|
-
export interface LoginTwoFactorRequired {
|
|
46
|
-
twoFactorRequired: true;
|
|
47
|
-
loginToken: string;
|
|
48
|
-
}
|
|
49
|
-
/**
|
|
50
|
-
* `POST /auth/login` when authentication completed in one step. Matches the
|
|
51
|
-
* API's `SessionAuthResponse` EXACTLY (`buildSessionAuthResponse`). `user` is the
|
|
52
|
-
* truncated session-user shape the login endpoint emits (NOT the full
|
|
53
|
-
* `userResponseSchema`).
|
|
43
|
+
* A successful sign-in. Matches the API's `SessionAuthResponse` EXACTLY
|
|
44
|
+
* (`buildSessionAuthResponse`). `user` is the truncated session-user shape the
|
|
45
|
+
* sign-in endpoints emit (NOT the full `userResponseSchema`).
|
|
54
46
|
*/
|
|
55
47
|
export interface LoginSessionResult {
|
|
56
48
|
sessionId: string;
|
|
@@ -77,6 +69,6 @@ export interface LoginSessionResult {
|
|
|
77
69
|
avatar?: string;
|
|
78
70
|
};
|
|
79
71
|
}
|
|
80
|
-
/** The
|
|
81
|
-
export type LoginResult =
|
|
72
|
+
/** The outcome of a successful sign-in — always a completed session. */
|
|
73
|
+
export type LoginResult = LoginSessionResult;
|
|
82
74
|
export declare const loginResultSchema: z.ZodType<LoginResult>;
|
package/dist/types/identity.d.ts
CHANGED
|
@@ -275,15 +275,15 @@ export declare const domainVerificationInstructionsSchema: z.ZodObject<{
|
|
|
275
275
|
export type DomainVerificationInstructions = z.infer<typeof domainVerificationInstructionsSchema>;
|
|
276
276
|
/**
|
|
277
277
|
* One linked authentication method. Mirrors a `User.authMethods[]` entry.
|
|
278
|
-
* `verificationMethodId` is present for `identity` methods (a key)
|
|
279
|
-
*
|
|
280
|
-
*
|
|
281
|
-
*
|
|
282
|
-
*
|
|
283
|
-
*
|
|
278
|
+
* `verificationMethodId` is present for `identity` methods (a key), linking the
|
|
279
|
+
* auth method to its DID verification-method fragment. For `webauthn` methods
|
|
280
|
+
* `credentialId` identifies the specific passkey (one entry per registered
|
|
281
|
+
* credential) and `name` is its user-facing label; a passkey is NOT a DID
|
|
282
|
+
* verification method, so it carries no `verificationMethodId` (a passkey-only
|
|
283
|
+
* account stays custodial).
|
|
284
284
|
*/
|
|
285
285
|
export interface AuthMethodEntry {
|
|
286
|
-
type: 'identity' | '
|
|
286
|
+
type: 'identity' | 'webauthn';
|
|
287
287
|
linkedAt: string | Date;
|
|
288
288
|
verificationMethodId?: string;
|
|
289
289
|
credentialId?: string;
|
package/dist/types/index.d.ts
CHANGED
|
@@ -30,7 +30,11 @@ export type { LinkPreviewStatus, LinkPreview, LinkPreviewBatchRequest, LinkPrevi
|
|
|
30
30
|
export { sessionAccountSchema, deviceSessionStateSchema, activeTokenSchema, deviceSessionSyncSchema, deviceTokenMintRequestSchema, deviceTokenMintResponseSchema, deviceHubTicketIssueRequestSchema, deviceHubTicketIssueResponseSchema, deviceHubTicketRedeemRequestSchema, deviceHubTicketRedeemResponseSchema, SESSION_ACCOUNTS_CHANGED_EVENT, sessionAccountsChangedReasonSchema, sessionAccountsChangedEventSchema, } from './deviceSession';
|
|
31
31
|
export type { SessionAccount, DeviceSessionState, ActiveToken, DeviceSessionSync, DeviceTokenMintRequest, DeviceTokenMintResponse, DeviceHubTicketIssueRequest, DeviceHubTicketIssueResponse, DeviceHubTicketRedeemRequest, DeviceHubTicketRedeemResponse, SessionAccountsChangedReason, SessionAccountsChangedEvent, } from './deviceSession';
|
|
32
32
|
export { loginResultSchema, } from './deviceBoot';
|
|
33
|
-
export type {
|
|
33
|
+
export type { LoginSessionResult, LoginResult, SecurityAlert, SecurityAlertAnomaly, } from './deviceBoot';
|
|
34
|
+
export { rotateKeyChallengeResponseSchema, rotateKeyCompleteRequestSchema, rotateKeyCompleteResponseSchema, } from './keyRotation';
|
|
35
|
+
export type { RotateKeyChallengeResponse, RotateKeyCompleteRequest, RotateKeyCompleteResponse, } from './keyRotation';
|
|
36
|
+
export { backupLookupIdSchema, encryptedBackupEnvelopeSchema, backupUploadRequestSchema, backupStatusResponseSchema, } from './keyRecovery';
|
|
37
|
+
export type { EncryptedBackupEnvelope, BackupUploadRequest, BackupStatusResponse, } from './keyRecovery';
|
|
34
38
|
export { updatePlatformSchema, updateStatusSchema, updateAssetStatusSchema, sha256HexSchema, channelNameSchema, runtimeVersionSchema, rolloutPercentSchema, assetInitItemSchema, assetInitRequestSchema, assetUploadTicketSchema, assetInitResponseSchema, assetCompleteRequestSchema, assetCompleteResultItemSchema, assetCompleteResponseSchema, updateAssetRefSchema, createUpdateRequestSchema, updateSchema, createUpdateResponseSchema, rollbackToEmbeddedEntrySchema, channelSchema, channelListResponseSchema, updateListResponseSchema, rollbackRequestSchema, rollbackToEmbeddedRequestSchema, promoteRequestSchema, updateRolloutPatchSchema, } from './updates';
|
|
35
39
|
export type { UpdatePlatform, UpdateStatus, UpdateAssetStatus, AssetInitItem, AssetInitRequest, AssetUploadTicket, AssetInitResponse, AssetCompleteRequest, AssetCompleteResultItem, AssetCompleteResponse, UpdateAssetRef, CreateUpdateRequest, Update, CreateUpdateResponse, RollbackToEmbeddedEntry, Channel, ChannelListResponse, UpdateListResponse, RollbackRequest, RollbackToEmbeddedRequest, PromoteRequest, UpdateRolloutPatch, } from './updates';
|
|
36
40
|
export { webauthnRegisterOptionsRequestSchema, webauthnLoginOptionsRequestSchema, webauthnRegisterVerifyRequestSchema, webauthnLoginVerifyRequestSchema, } from './webauthn';
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Encrypted off-device identity backup contract (b3 Feature 1).
|
|
3
|
+
*
|
|
4
|
+
* SINGLE SOURCE OF TRUTH for the "encrypted identity backup" flow, where a
|
|
5
|
+
* client stores an encrypted copy of its self-custody identity key off-device so
|
|
6
|
+
* a lost/wiped device can be recovered from the recovery phrase ALONE — without
|
|
7
|
+
* the platform ever seeing the phrase, the derived encryption key, or the
|
|
8
|
+
* plaintext private key.
|
|
9
|
+
*
|
|
10
|
+
* Zero-knowledge design (mirrors the zero-cookie `DeviceSession.secretHash`
|
|
11
|
+
* pattern): the client derives, from the FULL 64-byte BIP-39 seed, both an
|
|
12
|
+
* encryption key (`backupKey`) and a locator (`lookupId`) via HKDF with
|
|
13
|
+
* domain-separated `info` labels. It uploads ONLY the XChaCha20-Poly1305
|
|
14
|
+
* ciphertext plus the raw `lookupId`; the server stores the ciphertext and
|
|
15
|
+
* `sha256(lookupId)` (never the raw `lookupId`). Restoration re-derives both
|
|
16
|
+
* from the phrase, fetches the envelope by `lookupId`, and decrypts locally.
|
|
17
|
+
*
|
|
18
|
+
* The server can neither locate a backup (it lacks the seed to compute the
|
|
19
|
+
* lookup id) nor decrypt one (it lacks the seed to compute the backup key) — a
|
|
20
|
+
* DB dump yields only opaque ciphertext keyed by an un-invertible hash.
|
|
21
|
+
*
|
|
22
|
+
* The producer (`@oxyhq/api`) validates its request/response against these
|
|
23
|
+
* schemas; the consumer (`@oxyhq/core` identity-backup mixin) validates its
|
|
24
|
+
* input against the same definitions, so the wire shape cannot drift.
|
|
25
|
+
*
|
|
26
|
+
* All shapes here are FLAT (no nested objects), so `z.infer<>` is safe under a
|
|
27
|
+
* consumer's node10 `moduleResolution`. Platform-agnostic — zod only, ESM-safe
|
|
28
|
+
* (no `require()`).
|
|
29
|
+
*/
|
|
30
|
+
import { z } from 'zod';
|
|
31
|
+
/** 256-bit backup locator (32 bytes), lowercase/uppercase hex. */
|
|
32
|
+
export declare const backupLookupIdSchema: z.ZodString;
|
|
33
|
+
/**
|
|
34
|
+
* The stored, self-describing encrypted backup as it lives at rest and travels
|
|
35
|
+
* on the public restore endpoint. Contains NO secret and NO locator: the
|
|
36
|
+
* `lookupId` is uploaded separately (see {@link backupUploadRequestSchema}) and
|
|
37
|
+
* only its hash is ever persisted.
|
|
38
|
+
*
|
|
39
|
+
* - `version` — envelope/KDF version, so a future scheme migration is
|
|
40
|
+
* distinguishable at rest.
|
|
41
|
+
* - `algorithm` — the AEAD used. Pinned literal so a mismatched decryptor
|
|
42
|
+
* fails loudly rather than silently.
|
|
43
|
+
* - `kdfInfo` — the HKDF `info` label used to derive the encryption key
|
|
44
|
+
* (domain-separation tag; documents exactly which context produced the key).
|
|
45
|
+
* - `nonce` — the 24-byte XChaCha20-Poly1305 nonce, hex.
|
|
46
|
+
* - `ciphertext` — the encrypted `{privateKey, publicKey, createdAt}` payload
|
|
47
|
+
* with the appended Poly1305 tag, hex.
|
|
48
|
+
* - `publicKeyHint` — a short, non-sensitive prefix of the backed-up identity's
|
|
49
|
+
* public key, so the owner can recognise WHICH identity a backup belongs to
|
|
50
|
+
* without exposing the full key. Bound into the AEAD associated data.
|
|
51
|
+
* - `createdAt` — ISO-8601 creation timestamp.
|
|
52
|
+
*/
|
|
53
|
+
export declare const encryptedBackupEnvelopeSchema: z.ZodObject<{
|
|
54
|
+
version: z.ZodNumber;
|
|
55
|
+
algorithm: z.ZodLiteral<"xchacha20poly1305">;
|
|
56
|
+
kdfInfo: z.ZodString;
|
|
57
|
+
nonce: z.ZodString;
|
|
58
|
+
ciphertext: z.ZodString;
|
|
59
|
+
publicKeyHint: z.ZodString;
|
|
60
|
+
createdAt: z.ZodString;
|
|
61
|
+
}, "strip", z.ZodTypeAny, {
|
|
62
|
+
version: number;
|
|
63
|
+
nonce: string;
|
|
64
|
+
algorithm: "xchacha20poly1305";
|
|
65
|
+
kdfInfo: string;
|
|
66
|
+
ciphertext: string;
|
|
67
|
+
publicKeyHint: string;
|
|
68
|
+
createdAt: string;
|
|
69
|
+
}, {
|
|
70
|
+
version: number;
|
|
71
|
+
nonce: string;
|
|
72
|
+
algorithm: "xchacha20poly1305";
|
|
73
|
+
kdfInfo: string;
|
|
74
|
+
ciphertext: string;
|
|
75
|
+
publicKeyHint: string;
|
|
76
|
+
createdAt: string;
|
|
77
|
+
}>;
|
|
78
|
+
export type EncryptedBackupEnvelope = z.infer<typeof encryptedBackupEnvelopeSchema>;
|
|
79
|
+
/**
|
|
80
|
+
* Request body of `POST /identity/backup` — the envelope PLUS the raw
|
|
81
|
+
* `lookupId`. The server sha256-hashes `lookupId` before storing it (it never
|
|
82
|
+
* persists the raw value), and upserts by the authenticated user id so a
|
|
83
|
+
* re-upload REPLACES the prior backup rather than accumulating duplicates.
|
|
84
|
+
*/
|
|
85
|
+
export declare const backupUploadRequestSchema: z.ZodObject<{
|
|
86
|
+
version: z.ZodNumber;
|
|
87
|
+
algorithm: z.ZodLiteral<"xchacha20poly1305">;
|
|
88
|
+
kdfInfo: z.ZodString;
|
|
89
|
+
nonce: z.ZodString;
|
|
90
|
+
ciphertext: z.ZodString;
|
|
91
|
+
publicKeyHint: z.ZodString;
|
|
92
|
+
createdAt: z.ZodString;
|
|
93
|
+
} & {
|
|
94
|
+
/**
|
|
95
|
+
* The raw 256-bit backup locator (hex), derived client-side from the seed
|
|
96
|
+
* with a domain-separated HKDF `info`. The server stores ONLY its sha256; a
|
|
97
|
+
* DB dump therefore cannot recompute a locator to enumerate backups.
|
|
98
|
+
*/
|
|
99
|
+
lookupId: z.ZodString;
|
|
100
|
+
}, "strip", z.ZodTypeAny, {
|
|
101
|
+
version: number;
|
|
102
|
+
nonce: string;
|
|
103
|
+
algorithm: "xchacha20poly1305";
|
|
104
|
+
kdfInfo: string;
|
|
105
|
+
ciphertext: string;
|
|
106
|
+
publicKeyHint: string;
|
|
107
|
+
createdAt: string;
|
|
108
|
+
lookupId: string;
|
|
109
|
+
}, {
|
|
110
|
+
version: number;
|
|
111
|
+
nonce: string;
|
|
112
|
+
algorithm: "xchacha20poly1305";
|
|
113
|
+
kdfInfo: string;
|
|
114
|
+
ciphertext: string;
|
|
115
|
+
publicKeyHint: string;
|
|
116
|
+
createdAt: string;
|
|
117
|
+
lookupId: string;
|
|
118
|
+
}>;
|
|
119
|
+
export type BackupUploadRequest = z.infer<typeof backupUploadRequestSchema>;
|
|
120
|
+
/**
|
|
121
|
+
* Response of `GET /identity/backup/status` (and the write/delete acks): whether
|
|
122
|
+
* the authenticated user has a stored backup, plus the non-sensitive hint +
|
|
123
|
+
* timestamp when one exists. Carries no ciphertext and no locator.
|
|
124
|
+
*/
|
|
125
|
+
export declare const backupStatusResponseSchema: z.ZodObject<{
|
|
126
|
+
exists: z.ZodBoolean;
|
|
127
|
+
publicKeyHint: z.ZodOptional<z.ZodString>;
|
|
128
|
+
createdAt: z.ZodOptional<z.ZodString>;
|
|
129
|
+
}, "strip", z.ZodTypeAny, {
|
|
130
|
+
exists: boolean;
|
|
131
|
+
publicKeyHint?: string | undefined;
|
|
132
|
+
createdAt?: string | undefined;
|
|
133
|
+
}, {
|
|
134
|
+
exists: boolean;
|
|
135
|
+
publicKeyHint?: string | undefined;
|
|
136
|
+
createdAt?: string | undefined;
|
|
137
|
+
}>;
|
|
138
|
+
export type BackupStatusResponse = z.infer<typeof backupStatusResponseSchema>;
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Key-rotation contract (b3 Feature 3 — key rotation + last-credential replacement).
|
|
3
|
+
*
|
|
4
|
+
* SINGLE SOURCE OF TRUTH for the atomic key-rotation flow:
|
|
5
|
+
* - `POST /auth/rotate/challenge` — mint a single-use `rotate_key` challenge.
|
|
6
|
+
* - `POST /auth/rotate/complete` — prove control of the CURRENT (old) key and
|
|
7
|
+
* atomically swap in the new one.
|
|
8
|
+
*
|
|
9
|
+
* Rotation is an atomic REPLACE of the single identity key, never a
|
|
10
|
+
* remove-then-add, so it never passes through a zero-auth-method state and is
|
|
11
|
+
* independent of the unlink guards. Because the client proves possession of the
|
|
12
|
+
* current key (from SecureStore OR a recovery-phrase re-derivation), the LAST
|
|
13
|
+
* remaining credential can be replaced — the server only cares that the
|
|
14
|
+
* signature validates against the current `publicKey`.
|
|
15
|
+
*
|
|
16
|
+
* The API validates its output against these schemas; `@oxyhq/core`'s identity
|
|
17
|
+
* mixin validates its input against the same definitions, so producer and
|
|
18
|
+
* consumer cannot drift.
|
|
19
|
+
*
|
|
20
|
+
* All shapes here are FLAT (no nested objects), so `z.infer<>` is safe under a
|
|
21
|
+
* consumer's node10 `moduleResolution` — no interface-pinning needed.
|
|
22
|
+
*
|
|
23
|
+
* Platform-agnostic — zod only, ESM-safe (no `require()`).
|
|
24
|
+
*/
|
|
25
|
+
import { z } from 'zod';
|
|
26
|
+
/**
|
|
27
|
+
* Response of `POST /auth/rotate/challenge`: the single-use `rotate_key`
|
|
28
|
+
* challenge the client must sign with its CURRENT key, plus its expiry.
|
|
29
|
+
*/
|
|
30
|
+
export declare const rotateKeyChallengeResponseSchema: z.ZodObject<{
|
|
31
|
+
challenge: z.ZodString;
|
|
32
|
+
/** ISO-8601 expiry timestamp. */
|
|
33
|
+
expiresAt: z.ZodString;
|
|
34
|
+
}, "strip", z.ZodTypeAny, {
|
|
35
|
+
expiresAt: string;
|
|
36
|
+
challenge: string;
|
|
37
|
+
}, {
|
|
38
|
+
expiresAt: string;
|
|
39
|
+
challenge: string;
|
|
40
|
+
}>;
|
|
41
|
+
export type RotateKeyChallengeResponse = z.infer<typeof rotateKeyChallengeResponseSchema>;
|
|
42
|
+
/**
|
|
43
|
+
* Request body of `POST /auth/rotate/complete`.
|
|
44
|
+
*
|
|
45
|
+
* Two proofs are required:
|
|
46
|
+
* - `signature` — the CURRENT (old) key signs
|
|
47
|
+
* `JSON.stringify({ action: 'rotate_key', userId, oldPublicKey, newPublicKey,
|
|
48
|
+
* challenge, timestamp })` (proves control of the key being replaced).
|
|
49
|
+
* - `newKeyProof` — the NEW key signs
|
|
50
|
+
* `JSON.stringify({ action: 'rotate_key_new', userId, newPublicKey, challenge,
|
|
51
|
+
* timestamp })` (proof-of-possession of the key being rotated IN; prevents an
|
|
52
|
+
* attacker rotating their account to a re-encoding of someone else's key they
|
|
53
|
+
* do not control).
|
|
54
|
+
*
|
|
55
|
+
* The request carries ONLY `newPublicKey` — `oldPublicKey` and `userId` are
|
|
56
|
+
* derived server-side from the authenticated user document (never
|
|
57
|
+
* client-supplied), so a caller cannot prove control of key X while rotating
|
|
58
|
+
* key Y.
|
|
59
|
+
*/
|
|
60
|
+
export declare const rotateKeyCompleteRequestSchema: z.ZodObject<{
|
|
61
|
+
newPublicKey: z.ZodString;
|
|
62
|
+
challenge: z.ZodString;
|
|
63
|
+
signature: z.ZodString;
|
|
64
|
+
/** Proof-of-possession: the NEW key signs the rotate_key_new payload. */
|
|
65
|
+
newKeyProof: z.ZodString;
|
|
66
|
+
timestamp: z.ZodNumber;
|
|
67
|
+
/**
|
|
68
|
+
* When true, all OTHER active sessions for the account are revoked after a
|
|
69
|
+
* successful rotation (the rotating device stays signed in). Use it when the
|
|
70
|
+
* old key is presumed compromised.
|
|
71
|
+
*/
|
|
72
|
+
signOutEverywhere: z.ZodOptional<z.ZodBoolean>;
|
|
73
|
+
}, "strip", z.ZodTypeAny, {
|
|
74
|
+
signature: string;
|
|
75
|
+
challenge: string;
|
|
76
|
+
newPublicKey: string;
|
|
77
|
+
newKeyProof: string;
|
|
78
|
+
timestamp: number;
|
|
79
|
+
signOutEverywhere?: boolean | undefined;
|
|
80
|
+
}, {
|
|
81
|
+
signature: string;
|
|
82
|
+
challenge: string;
|
|
83
|
+
newPublicKey: string;
|
|
84
|
+
newKeyProof: string;
|
|
85
|
+
timestamp: number;
|
|
86
|
+
signOutEverywhere?: boolean | undefined;
|
|
87
|
+
}>;
|
|
88
|
+
export type RotateKeyCompleteRequest = z.infer<typeof rotateKeyCompleteRequestSchema>;
|
|
89
|
+
/** Response of `POST /auth/rotate/complete`: the account's new (rotated) public key. */
|
|
90
|
+
export declare const rotateKeyCompleteResponseSchema: z.ZodObject<{
|
|
91
|
+
success: z.ZodBoolean;
|
|
92
|
+
publicKey: z.ZodString;
|
|
93
|
+
message: z.ZodString;
|
|
94
|
+
}, "strip", z.ZodTypeAny, {
|
|
95
|
+
message: string;
|
|
96
|
+
publicKey: string;
|
|
97
|
+
success: boolean;
|
|
98
|
+
}, {
|
|
99
|
+
message: string;
|
|
100
|
+
publicKey: string;
|
|
101
|
+
success: boolean;
|
|
102
|
+
}>;
|
|
103
|
+
export type RotateKeyCompleteResponse = z.infer<typeof rotateKeyCompleteResponseSchema>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oxyhq/contracts",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.16.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",
|
|
@@ -78,7 +78,7 @@
|
|
|
78
78
|
},
|
|
79
79
|
"devDependencies": {
|
|
80
80
|
"@biomejs/biome": "^1.9.4",
|
|
81
|
-
"@types/node": "^20.19.
|
|
81
|
+
"@types/node": "^20.19.43",
|
|
82
82
|
"release-it": "^19.0.6",
|
|
83
83
|
"typescript": "^5.9.2"
|
|
84
84
|
}
|