@seedkey/sdk-client 0.0.1

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/CHANGELOG.md ADDED
@@ -0,0 +1,3 @@
1
+ # Changelog
2
+
3
+ v0.0.1
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Maksim Bessarab
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,262 @@
1
+ # 🔐 SeedKey Client SDK
2
+
3
+ ![license](https://img.shields.io/badge/license-MIT-blue)
4
+
5
+ SeedKey Client SDK — a client library for passwordless authentication via a browser extension, part of the SeedKey open-source ecosystem.
6
+
7
+ ## Table of Contents
8
+
9
+ - [🔍 Interaction architecture](#-interaction-architecture)
10
+ - [🧩 Features](#-features)
11
+ - [📦 Installation](#-installation)
12
+ - [🚀 Quick start](#-quick-start)
13
+ - [🔧 SDK methods](#-sdk-methods)
14
+ - [🔌 Backend integration](#-backend-integration)
15
+ - [🤝 Contributing](#-contributing)
16
+ - [🛡️ Vulnerability disclosure](#-vulnerability-disclosure)
17
+ - [📄 License](#-license)
18
+
19
+ ## 🔍 Interaction architecture
20
+
21
+ ![SeedKey Architecture](doc/SeedKeyArchitecture.png)
22
+
23
+ ## 🧩 Features
24
+
25
+ The SDK provides:
26
+
27
+ - **Extension communication** — get `publicKey`, sign a `challenge`, or sign custom messages.
28
+ - **High-level API** — a ready authentication flow with your backend via the REST contract `auth()` / `register()` / `authenticate()`.
29
+ - **Low-level API** — flexible customization: `getPublicKey()` / `signChallenge()` / `requestChallenge()`.
30
+ - **Token storage helpers** in `localStorage`.
31
+
32
+ Important: your **backend** must implement the REST API (see [Backend integration](#-backend-integration) below).
33
+
34
+ The SDK also provides tools to simplify authentication integration into your service:
35
+
36
+ - **Protocol types** — interfaces for `Challenge`, `User`, `Token`, `Session`.
37
+ - **Cryptographic utilities** — Ed25519 signature verification.
38
+ - **Authentication services** — `AuthService` and `KeyService`.
39
+ - **Storage abstractions** — adapter interfaces for databases.
40
+ - **Error types** — `SeedKeyError` + `ERROR_CODES`.
41
+
42
+ ## 📦 Installation
43
+
44
+ ```bash
45
+ npm install @seedkey/sdk-client
46
+ ```
47
+
48
+ ```bash
49
+ yarn add @seedkey/sdk-client
50
+ ```
51
+
52
+ ```bash
53
+ pnpm add @seedkey/sdk-client
54
+ ```
55
+
56
+ ## 🚀 Quick start
57
+
58
+ ```ts
59
+ import { getSeedKey, saveTokens, SeedKeyError } from '@seedkey/sdk-client';
60
+
61
+ // SDK initialization
62
+ const sdk = getSeedKey({
63
+ backendUrl: 'https://api.example.com',
64
+ timeout: 60000,
65
+ debug: true,
66
+ });
67
+
68
+ // Check extension availability
69
+ const available = await sdk.isAvailable();
70
+ if (!available) {
71
+ console.log('Install the SeedKey extension');
72
+ return;
73
+ }
74
+
75
+ // Check extension initialization (identity exists)
76
+ const initialized = await sdk.isInitialized();
77
+ if (!initialized) {
78
+ console.log('Create an Identity in the SeedKey extension');
79
+ return;
80
+ }
81
+
82
+ // Authentication (auto-register if user is new)
83
+ try {
84
+ const result = await sdk.auth();
85
+ console.log('User ID:', result.user.id);
86
+ console.log('Access Token:', result.token.accessToken);
87
+
88
+ // Save tokens to localStorage
89
+ saveTokens(result.token, result.user.id);
90
+ } catch (error) {
91
+ if (error instanceof SeedKeyError) {
92
+ console.error('Code:', error.code, 'Message:', error.message);
93
+ }
94
+ }
95
+ ```
96
+
97
+ Token handling:
98
+
99
+ ```ts
100
+ import {
101
+ saveTokens,
102
+ getAccessToken,
103
+ getRefreshToken,
104
+ getUserId,
105
+ isTokenExpired,
106
+ hasToken,
107
+ clearTokens,
108
+ getSession,
109
+ getSeedKey,
110
+ } from '@seedkey/sdk-client';
111
+
112
+ const sdk = getSeedKey();
113
+
114
+ // Get access token
115
+ const token = getAccessToken();
116
+
117
+ // Check token expiration
118
+ if (isTokenExpired()) {
119
+ const newTokens = await sdk.refreshToken(getRefreshToken()!);
120
+ saveTokens(newTokens, getUserId() ?? undefined);
121
+ }
122
+
123
+ // Get full session
124
+ const session = getSession();
125
+ // { accessToken, refreshToken, userId, isExpired }
126
+
127
+ // Clear on logout
128
+ clearTokens();
129
+ ```
130
+
131
+ Error handling:
132
+
133
+ ```ts
134
+ import { getSeedKey, SeedKeyError, ERROR_CODES } from '@seedkey/sdk-client';
135
+
136
+ const sdk = getSeedKey();
137
+
138
+ try {
139
+ await sdk.auth();
140
+ } catch (error) {
141
+ if (error instanceof SeedKeyError) {
142
+ switch (error.code) {
143
+ // Extension errors
144
+ case ERROR_CODES.EXTENSION_NOT_FOUND:
145
+ // Extension is not installed
146
+ break;
147
+ case ERROR_CODES.NOT_INITIALIZED:
148
+ // Identity is not configured
149
+ break;
150
+ case ERROR_CODES.EXTENSION_LOCKED:
151
+ // Extension is locked
152
+ break;
153
+ case ERROR_CODES.TIMEOUT:
154
+ // Operation timeout
155
+ break;
156
+
157
+ // User actions
158
+ case ERROR_CODES.USER_REJECTED:
159
+ // User rejected the request
160
+ break;
161
+
162
+ // Network errors
163
+ case ERROR_CODES.NETWORK_ERROR:
164
+ // Network error
165
+ break;
166
+ case ERROR_CODES.SERVER_ERROR:
167
+ // Server error
168
+ break;
169
+
170
+ // Auth errors
171
+ case ERROR_CODES.USER_NOT_FOUND:
172
+ // User not found
173
+ break;
174
+ case ERROR_CODES.USER_EXISTS:
175
+ // User already exists
176
+ break;
177
+ case ERROR_CODES.INVALID_SIGNATURE:
178
+ // Invalid signature
179
+ break;
180
+ case ERROR_CODES.INVALID_TOKEN:
181
+ // Invalid token
182
+ break;
183
+ }
184
+
185
+ console.log('Code:', error.code);
186
+ console.log('Message:', error.message);
187
+ console.log('Hint:', error.hint);
188
+ }
189
+ }
190
+ ```
191
+
192
+ You can rely on the SDK and let it handle the routine for you, or implement the logic yourself using the library’s low-level API.
193
+
194
+ In the basic variant, the authentication flow looks like this:
195
+
196
+ 1. Extension: `sdk.getPublicKey()`
197
+ 2. Backend: `POST /api/v1/seedkey/challenge` `{ publicKey, action: "authenticate" }`
198
+ 3. Extension: `sdk.signChallenge()`
199
+ 4. Backend: `POST /api/v1/seedkey/verify` `{ challengeId, challenge, signature, publicKey }`
200
+
201
+ Registration flow:
202
+
203
+ 1. Extension: `sdk.getPublicKey()`
204
+ 2. Backend: `POST /api/v1/seedkey/challenge` `{ publicKey, action: "register" }`
205
+ 3. Extension: `sdk.signChallenge()`
206
+ 4. Backend: `POST /api/v1/seedkey/register` `{ publicKey, challenge, signature, metadata }`
207
+
208
+ ## 🔧 SDK methods
209
+
210
+ | Method | Description | Returns |
211
+ |:--|:--|:--|
212
+ | `isAvailable()` | Check if the extension is installed | `Promise<boolean>` |
213
+ | `isInitialized()` | Check if the extension is initialized | `Promise<boolean>` |
214
+ | `getPublicKey()` | Get the public key for the current domain | `Promise<string>` |
215
+ | `signMessage(message)` | Sign a message (optional) | `Promise<SignMessageResult>` |
216
+ | `signChallenge(challenge: Challenge)` | Sign a `Challenge` | `Promise<SignChallengeResult>` |
217
+ | `register(opts?)` | Register a new account | `Promise<AuthResult>` |
218
+ | `authenticate()` | Authenticate an existing account | `Promise<AuthResult>` |
219
+ | `auth(opts?)` | Smart auth (register/login) | `Promise<AuthResult>` |
220
+ | `getUser(accessToken)` | Get the current user profile | `Promise<UserProfile>` |
221
+ | `logout(accessToken)` | Logout (invalidate access token) | `Promise<void>` |
222
+ | `refreshToken(refreshToken)` | Refresh token pair | `Promise<TokenInfo>` |
223
+ | `getVersion()` | Get SDK version | `string` |
224
+ | `destroy()` | Cleanup resources | `void` |
225
+
226
+ Important: your **backend** must support the request/response types sent by the SDK and/or implement full endpoints — depending on your chosen integration.
227
+
228
+ REST API used by the SDK:
229
+
230
+ | Route | Method | Purpose | Request (JSON / headers) | Response |
231
+ |:--|:--|:--|:--|:--|
232
+ | `/api/v1/seedkey/challenge` | `POST` | Get a challenge to sign in the extension | Body: `{ publicKey, action: "register" \| "authenticate" }` | `ChallengeResponse` |
233
+ | `/api/v1/seedkey/register` | `POST` | Create a new user by signed challenge | Body: `{ publicKey, challenge, signature, metadata }` | `AuthResult` |
234
+ | `/api/v1/seedkey/verify` | `POST` | Verify challenge signature and issue tokens | Body: `{ challengeId, challenge, signature, publicKey }` | `AuthResult` |
235
+ | `/api/v1/seedkey/user` | `GET` | Get current user profile | Header: `Authorization: Bearer <accessToken>` | `{ user: UserProfile }` |
236
+ | `/api/v1/seedkey/logout` | `POST` | Invalidate session | Header: `Authorization: Bearer <accessToken>`; Body: `{}` (or empty) | `{ success: boolean }` |
237
+ | `/api/v1/seedkey/refresh` | `POST` | Refresh token pair using refresh token | Body: `{ refreshToken }` | `TokenInfo` / `{ accessToken, refreshToken, expiresIn }` |
238
+
239
+ ## 🔌 Backend integration
240
+
241
+ For efficient integration with your backend:
242
+
243
+ - use `seedkey-sdk-server` — a library to implement the authentication mechanism yourself;
244
+ - or deploy the ready self-hosted service `seedkey-auth-service`.
245
+
246
+ Also check out other repositories in the ecosystem:
247
+
248
+ - `seedkey-auth-service-migrations` — Liquibase migrations for `seedkey-auth-service`.
249
+ - `seedkey-auth-service-helm-chart` — Helm Chart for deploying `seedkey-auth-service` + `seedkey-auth-service-migrations`.
250
+ - `seedkey-browser-extension` — browser extension.
251
+
252
+ ## 🤝 Contributing
253
+
254
+ If you have ideas and want to contribute — feel free to open an issue or a pull request.
255
+
256
+ ## 🛡️ Vulnerability disclosure
257
+
258
+ Please **do not publish** vulnerabilities in public issues. Report them privately via `maks@besssarab.ru` or open a private security advisory on GitHub.
259
+
260
+ ## 📄 License
261
+
262
+ See `LICENSE`.
package/dist/api.d.ts ADDED
@@ -0,0 +1,34 @@
1
+ /**
2
+ * API client for backend integration
3
+ */
4
+ import { UserProfile } from './types';
5
+ export declare class ApiClient {
6
+ private baseUrl;
7
+ constructor(baseUrl: string);
8
+ /**
9
+ * Get user profile
10
+ */
11
+ getUser(accessToken: string): Promise<UserProfile>;
12
+ /**
13
+ * Logout (invalidate token)
14
+ */
15
+ logout(accessToken: string): Promise<void>;
16
+ /**
17
+ * Refresh token
18
+ */
19
+ refreshToken(refreshToken: string): Promise<{
20
+ accessToken: string;
21
+ refreshToken: string;
22
+ expiresIn: number;
23
+ }>;
24
+ /**
25
+ * Base fetch with defaults
26
+ */
27
+ private fetch;
28
+ }
29
+ export declare function getApiClient(baseUrl?: string): ApiClient;
30
+ /**
31
+ * Reset singleton API client instance
32
+ */
33
+ export declare function resetApiClient(): void;
34
+ //# sourceMappingURL=api.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,WAAW,EAA6B,MAAM,SAAS,CAAC;AAOjE,qBAAa,SAAS;IACR,OAAO,CAAC,OAAO;gBAAP,OAAO,EAAE,MAAM;IAInC;;OAEG;IACG,OAAO,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IAuBxD;;OAEG;IACG,MAAM,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAqBhD;;OAEG;IACG,YAAY,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC;QAChD,WAAW,EAAE,MAAM,CAAC;QACpB,YAAY,EAAE,MAAM,CAAC;QACrB,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;IAqBF;;OAEG;YACW,KAAK;CA0BpB;AAQD,wBAAgB,YAAY,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAUxD;AAED;;GAEG;AACH,wBAAgB,cAAc,IAAI,IAAI,CAErC"}
package/dist/api.js ADDED
@@ -0,0 +1,115 @@
1
+ /**
2
+ * API client for backend integration
3
+ */
4
+ import { SeedKeyError, ERROR_CODES } from './types';
5
+ import { apiLogger as log } from './logger';
6
+ // ============================================================================
7
+ // API Client
8
+ // ============================================================================
9
+ export class ApiClient {
10
+ constructor(baseUrl) {
11
+ this.baseUrl = baseUrl;
12
+ log.info('ApiClient initialized', { baseUrl });
13
+ }
14
+ /**
15
+ * Get user profile
16
+ */
17
+ async getUser(accessToken) {
18
+ log.debug('GET /api/v1/seedkey/user');
19
+ const response = await this.fetch('/api/v1/seedkey/user', {
20
+ method: 'GET',
21
+ headers: {
22
+ 'Authorization': `Bearer ${accessToken}`,
23
+ },
24
+ });
25
+ if (!response.ok) {
26
+ const error = await response.json();
27
+ log.error('Failed to get user', { status: response.status, error });
28
+ throw new SeedKeyError(error.error || ERROR_CODES.SERVER_ERROR, error.message || 'Failed to get user');
29
+ }
30
+ const data = await response.json();
31
+ log.info('User retrieved', { userId: data.user?.id });
32
+ return data.user;
33
+ }
34
+ /**
35
+ * Logout (invalidate token)
36
+ */
37
+ async logout(accessToken) {
38
+ log.debug('POST /api/v1/seedkey/logout');
39
+ const response = await this.fetch('/api/v1/seedkey/logout', {
40
+ method: 'POST',
41
+ headers: {
42
+ 'Authorization': `Bearer ${accessToken}`,
43
+ },
44
+ });
45
+ if (!response.ok) {
46
+ const error = await response.json();
47
+ log.error('Logout failed', { status: response.status, error });
48
+ throw new SeedKeyError(error.error || ERROR_CODES.SERVER_ERROR, error.message || 'Logout failed');
49
+ }
50
+ log.info('Logout successful');
51
+ }
52
+ /**
53
+ * Refresh token
54
+ */
55
+ async refreshToken(refreshToken) {
56
+ log.debug('POST /api/v1/seedkey/refresh');
57
+ const response = await this.fetch('/api/v1/seedkey/refresh', {
58
+ method: 'POST',
59
+ body: JSON.stringify({ refreshToken }),
60
+ });
61
+ if (!response.ok) {
62
+ const error = await response.json();
63
+ log.error('Token refresh failed', { status: response.status, error });
64
+ throw new SeedKeyError(error.error || ERROR_CODES.INVALID_TOKEN, error.message || 'Token refresh failed');
65
+ }
66
+ const result = await response.json();
67
+ log.info('Token refreshed', { expiresIn: result.expiresIn });
68
+ return result;
69
+ }
70
+ /**
71
+ * Base fetch with defaults
72
+ */
73
+ async fetch(endpoint, options = {}) {
74
+ const url = `${this.baseUrl}${endpoint}`;
75
+ const headers = {
76
+ 'Content-Type': 'application/json',
77
+ ...options.headers,
78
+ };
79
+ log.time(`fetch ${endpoint}`);
80
+ try {
81
+ const response = await fetch(url, {
82
+ ...options,
83
+ headers,
84
+ });
85
+ log.timeEnd(`fetch ${endpoint}`);
86
+ log.debug(`${options.method || 'GET'} ${endpoint}`, { status: response.status, ok: response.ok });
87
+ return response;
88
+ }
89
+ catch (error) {
90
+ log.timeEnd(`fetch ${endpoint}`);
91
+ log.error(`Network error: ${endpoint}`, error);
92
+ throw new SeedKeyError(ERROR_CODES.NETWORK_ERROR, `Network error: ${error instanceof Error ? error.message : 'Unknown error'}`);
93
+ }
94
+ }
95
+ }
96
+ // ============================================================================
97
+ // Singleton Instance
98
+ // ============================================================================
99
+ let apiClientInstance = null;
100
+ export function getApiClient(baseUrl) {
101
+ if (!apiClientInstance && baseUrl) {
102
+ apiClientInstance = new ApiClient(baseUrl);
103
+ }
104
+ if (!apiClientInstance) {
105
+ throw new Error('ApiClient not initialized. Call getApiClient with baseUrl first.');
106
+ }
107
+ return apiClientInstance;
108
+ }
109
+ /**
110
+ * Reset singleton API client instance
111
+ */
112
+ export function resetApiClient() {
113
+ apiClientInstance = null;
114
+ }
115
+ //# sourceMappingURL=api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.js","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,55 @@
1
+ /**
2
+ * SeedKey Auth SDK
3
+ *
4
+ * Client library for authentication via the SeedKey browser extension
5
+ *
6
+ * ## Two usage modes
7
+ *
8
+ * ### 1. Ready-to-use methods (REST API) - recommended
9
+ *
10
+ * @example
11
+ * ```ts
12
+ * import { SeedKey, getSeedKey } from '@seedkey/sdk-client';
13
+ *
14
+ * const sdk = getSeedKey({ backendUrl: 'http://localhost:3000', debug: true });
15
+ *
16
+ * // Extension check
17
+ * const status = await sdk.getExtensionStatus();
18
+ * if (!status.installed) {
19
+ * console.log('Install extension:', status.downloadUrl);
20
+ * return;
21
+ * }
22
+ *
23
+ * // Full authentication (register if user doesn't exist)
24
+ * const result = await sdk.auth();
25
+ * console.log('User ID:', result.user.id);
26
+ * ```
27
+ *
28
+ * ### 2. Low-level methods for custom authentication
29
+ *
30
+ * @example
31
+ * ```ts
32
+ * const sdk = getSeedKey({ backendUrl: 'http://localhost:3000' });
33
+ *
34
+ * // Extension check (throws if there are issues)
35
+ * await sdk.checkExtension();
36
+ *
37
+ * // Custom flow
38
+ * const publicKey = await sdk.getPublicKey();
39
+ * const { challenge, challengeId } = await sdk.requestChallenge(publicKey, 'authenticate');
40
+ * const { signature } = await sdk.signChallenge(challenge);
41
+ *
42
+ * // Send to your backend
43
+ * await fetch('/my-api/verify', {
44
+ * method: 'POST',
45
+ * body: JSON.stringify({ challengeId, signature, publicKey })
46
+ * });
47
+ * ```
48
+ */
49
+ export { SeedKey, getSeedKey, resetSeedKey, getRequestEventName, getResponseEventName, } from './seedkey';
50
+ export { ApiClient, getApiClient, resetApiClient } from './api';
51
+ export { saveTokens, clearTokens, getAccessToken, getRefreshToken, getUserId, isTokenExpired, hasToken, getSession, } from './storage';
52
+ export { createLogger, enableDebug, disableDebug, sdkLogger, authLogger, apiLogger, storageLogger, uiLogger, } from './logger';
53
+ export type { Challenge, TokenInfo, UserInfo, AuthResult, PublicKeyInfo, UserProfile, SeedKeyOptions, AuthOptions, SeedKeyAction, SeedKeyRequest, SeedKeyResponse, PublicKeyResult, SignChallengeResult, SignMessageResult, ChallengeResponse, RegisterRequest, VerifyRequest, ErrorCode, ExtensionStatus, } from './types';
54
+ export { SeedKeyError, ExtensionNotFoundError, ExtensionNotConfiguredError, ERROR_CODES, EXTENSION_DOWNLOAD_URL, SDK_VERSION, REQUEST_EVENT, RESPONSE_EVENT, } from './types';
55
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+CG;AAGH,OAAO,EACL,OAAO,EACP,UAAU,EACV,YAAY,EACZ,mBAAmB,EACnB,oBAAoB,GACrB,MAAM,WAAW,CAAC;AAGnB,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,OAAO,CAAC;AAGhE,OAAO,EACL,UAAU,EACV,WAAW,EACX,cAAc,EACd,eAAe,EACf,SAAS,EACT,cAAc,EACd,QAAQ,EACR,UAAU,GACX,MAAM,WAAW,CAAC;AAGnB,OAAO,EACL,YAAY,EACZ,WAAW,EACX,YAAY,EACZ,SAAS,EACT,UAAU,EACV,SAAS,EACT,aAAa,EACb,QAAQ,GACT,MAAM,UAAU,CAAC;AAGlB,YAAY,EACV,SAAS,EACT,SAAS,EACT,QAAQ,EACR,UAAU,EACV,aAAa,EACb,WAAW,EACX,cAAc,EACd,WAAW,EACX,aAAa,EACb,cAAc,EACd,eAAe,EACf,eAAe,EACf,mBAAmB,EACnB,iBAAiB,EACjB,iBAAiB,EACjB,eAAe,EACf,aAAa,EACb,SAAS,EACT,eAAe,GAChB,MAAM,SAAS,CAAC;AAGjB,OAAO,EACL,YAAY,EACZ,sBAAsB,EACtB,2BAA2B,EAC3B,WAAW,EACX,sBAAsB,EACtB,WAAW,EACX,aAAa,EACb,cAAc,GACf,MAAM,SAAS,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,59 @@
1
+ /**
2
+ * SeedKey Auth SDK
3
+ *
4
+ * Client library for authentication via the SeedKey browser extension
5
+ *
6
+ * ## Two usage modes
7
+ *
8
+ * ### 1. Ready-to-use methods (REST API) - recommended
9
+ *
10
+ * @example
11
+ * ```ts
12
+ * import { SeedKey, getSeedKey } from '@seedkey/sdk-client';
13
+ *
14
+ * const sdk = getSeedKey({ backendUrl: 'http://localhost:3000', debug: true });
15
+ *
16
+ * // Extension check
17
+ * const status = await sdk.getExtensionStatus();
18
+ * if (!status.installed) {
19
+ * console.log('Install extension:', status.downloadUrl);
20
+ * return;
21
+ * }
22
+ *
23
+ * // Full authentication (register if user doesn't exist)
24
+ * const result = await sdk.auth();
25
+ * console.log('User ID:', result.user.id);
26
+ * ```
27
+ *
28
+ * ### 2. Low-level methods for custom authentication
29
+ *
30
+ * @example
31
+ * ```ts
32
+ * const sdk = getSeedKey({ backendUrl: 'http://localhost:3000' });
33
+ *
34
+ * // Extension check (throws if there are issues)
35
+ * await sdk.checkExtension();
36
+ *
37
+ * // Custom flow
38
+ * const publicKey = await sdk.getPublicKey();
39
+ * const { challenge, challengeId } = await sdk.requestChallenge(publicKey, 'authenticate');
40
+ * const { signature } = await sdk.signChallenge(challenge);
41
+ *
42
+ * // Send to your backend
43
+ * await fetch('/my-api/verify', {
44
+ * method: 'POST',
45
+ * body: JSON.stringify({ challengeId, signature, publicKey })
46
+ * });
47
+ * ```
48
+ */
49
+ // SDK
50
+ export { SeedKey, getSeedKey, resetSeedKey, getRequestEventName, getResponseEventName, } from './seedkey';
51
+ // API Client
52
+ export { ApiClient, getApiClient, resetApiClient } from './api';
53
+ // Storage
54
+ export { saveTokens, clearTokens, getAccessToken, getRefreshToken, getUserId, isTokenExpired, hasToken, getSession, } from './storage';
55
+ // Logger
56
+ export { createLogger, enableDebug, disableDebug, sdkLogger, authLogger, apiLogger, storageLogger, uiLogger, } from './logger';
57
+ // Errors & Constants
58
+ export { SeedKeyError, ExtensionNotFoundError, ExtensionNotConfiguredError, ERROR_CODES, EXTENSION_DOWNLOAD_URL, SDK_VERSION, REQUEST_EVENT, RESPONSE_EVENT, } from './types';
59
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+CG;AAEH,MAAM;AACN,OAAO,EACL,OAAO,EACP,UAAU,EACV,YAAY,EACZ,mBAAmB,EACnB,oBAAoB,GACrB,MAAM,WAAW,CAAC;AAEnB,aAAa;AACb,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,OAAO,CAAC;AAEhE,UAAU;AACV,OAAO,EACL,UAAU,EACV,WAAW,EACX,cAAc,EACd,eAAe,EACf,SAAS,EACT,cAAc,EACd,QAAQ,EACR,UAAU,GACX,MAAM,WAAW,CAAC;AAEnB,SAAS;AACT,OAAO,EACL,YAAY,EACZ,WAAW,EACX,YAAY,EACZ,SAAS,EACT,UAAU,EACV,SAAS,EACT,aAAa,EACb,QAAQ,GACT,MAAM,UAAU,CAAC;AAyBlB,qBAAqB;AACrB,OAAO,EACL,YAAY,EACZ,sBAAsB,EACtB,2BAA2B,EAC3B,WAAW,EACX,sBAAsB,EACtB,WAAW,EACX,aAAa,EACb,cAAc,GACf,MAAM,SAAS,CAAC"}
@@ -0,0 +1,111 @@
1
+ /**
2
+ * Debug Logger
3
+ */
4
+ /**
5
+ * Enable debug logging
6
+ */
7
+ export declare function enableDebug(): void;
8
+ /**
9
+ * Disable debug logging
10
+ */
11
+ export declare function disableDebug(): void;
12
+ /**
13
+ * Create a module logger
14
+ */
15
+ export declare function createLogger(module: string): {
16
+ debug: (message: string, data?: unknown) => void;
17
+ info: (message: string, data?: unknown) => void;
18
+ warn: (message: string, data?: unknown) => void;
19
+ error: (message: string, data?: unknown) => void;
20
+ /** Log grouping */
21
+ group: (label: string, collapsed?: boolean) => void;
22
+ /** End group */
23
+ groupEnd: () => void;
24
+ /** Data table */
25
+ table: (data: unknown) => void;
26
+ /** Timing */
27
+ time: (label: string) => void;
28
+ /** End timing */
29
+ timeEnd: (label: string) => void;
30
+ };
31
+ export declare const sdkLogger: {
32
+ debug: (message: string, data?: unknown) => void;
33
+ info: (message: string, data?: unknown) => void;
34
+ warn: (message: string, data?: unknown) => void;
35
+ error: (message: string, data?: unknown) => void;
36
+ /** Log grouping */
37
+ group: (label: string, collapsed?: boolean) => void;
38
+ /** End group */
39
+ groupEnd: () => void;
40
+ /** Data table */
41
+ table: (data: unknown) => void;
42
+ /** Timing */
43
+ time: (label: string) => void;
44
+ /** End timing */
45
+ timeEnd: (label: string) => void;
46
+ };
47
+ export declare const authLogger: {
48
+ debug: (message: string, data?: unknown) => void;
49
+ info: (message: string, data?: unknown) => void;
50
+ warn: (message: string, data?: unknown) => void;
51
+ error: (message: string, data?: unknown) => void;
52
+ /** Log grouping */
53
+ group: (label: string, collapsed?: boolean) => void;
54
+ /** End group */
55
+ groupEnd: () => void;
56
+ /** Data table */
57
+ table: (data: unknown) => void;
58
+ /** Timing */
59
+ time: (label: string) => void;
60
+ /** End timing */
61
+ timeEnd: (label: string) => void;
62
+ };
63
+ export declare const apiLogger: {
64
+ debug: (message: string, data?: unknown) => void;
65
+ info: (message: string, data?: unknown) => void;
66
+ warn: (message: string, data?: unknown) => void;
67
+ error: (message: string, data?: unknown) => void;
68
+ /** Log grouping */
69
+ group: (label: string, collapsed?: boolean) => void;
70
+ /** End group */
71
+ groupEnd: () => void;
72
+ /** Data table */
73
+ table: (data: unknown) => void;
74
+ /** Timing */
75
+ time: (label: string) => void;
76
+ /** End timing */
77
+ timeEnd: (label: string) => void;
78
+ };
79
+ export declare const storageLogger: {
80
+ debug: (message: string, data?: unknown) => void;
81
+ info: (message: string, data?: unknown) => void;
82
+ warn: (message: string, data?: unknown) => void;
83
+ error: (message: string, data?: unknown) => void;
84
+ /** Log grouping */
85
+ group: (label: string, collapsed?: boolean) => void;
86
+ /** End group */
87
+ groupEnd: () => void;
88
+ /** Data table */
89
+ table: (data: unknown) => void;
90
+ /** Timing */
91
+ time: (label: string) => void;
92
+ /** End timing */
93
+ timeEnd: (label: string) => void;
94
+ };
95
+ export declare const uiLogger: {
96
+ debug: (message: string, data?: unknown) => void;
97
+ info: (message: string, data?: unknown) => void;
98
+ warn: (message: string, data?: unknown) => void;
99
+ error: (message: string, data?: unknown) => void;
100
+ /** Log grouping */
101
+ group: (label: string, collapsed?: boolean) => void;
102
+ /** End group */
103
+ groupEnd: () => void;
104
+ /** Data table */
105
+ table: (data: unknown) => void;
106
+ /** Timing */
107
+ time: (label: string) => void;
108
+ /** End timing */
109
+ timeEnd: (label: string) => void;
110
+ };
111
+ //# sourceMappingURL=logger.d.ts.map