@byoky/core 0.1.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/index.cjs ADDED
@@ -0,0 +1,286 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ BYOKY_MESSAGE_PREFIX: () => BYOKY_MESSAGE_PREFIX,
24
+ BYOKY_PROVIDER_KEY: () => BYOKY_PROVIDER_KEY,
25
+ ByokyError: () => ByokyError,
26
+ ByokyErrorCode: () => ByokyErrorCode,
27
+ PROVIDERS: () => PROVIDERS,
28
+ createConnectRequest: () => createConnectRequest,
29
+ createConnectResponse: () => createConnectResponse,
30
+ createErrorMessage: () => createErrorMessage,
31
+ createMessage: () => createMessage,
32
+ decrypt: () => decrypt,
33
+ deriveKey: () => deriveKey,
34
+ encrypt: () => encrypt,
35
+ getProvider: () => getProvider,
36
+ getProviderIds: () => getProviderIds,
37
+ hashPassword: () => hashPassword,
38
+ isByokyMessage: () => isByokyMessage,
39
+ maskKey: () => maskKey,
40
+ verifyPassword: () => verifyPassword
41
+ });
42
+ module.exports = __toCommonJS(index_exports);
43
+
44
+ // src/types.ts
45
+ var ByokyErrorCode = /* @__PURE__ */ ((ByokyErrorCode2) => {
46
+ ByokyErrorCode2["WALLET_NOT_INSTALLED"] = "WALLET_NOT_INSTALLED";
47
+ ByokyErrorCode2["USER_REJECTED"] = "USER_REJECTED";
48
+ ByokyErrorCode2["PROVIDER_UNAVAILABLE"] = "PROVIDER_UNAVAILABLE";
49
+ ByokyErrorCode2["SESSION_EXPIRED"] = "SESSION_EXPIRED";
50
+ ByokyErrorCode2["RATE_LIMITED"] = "RATE_LIMITED";
51
+ ByokyErrorCode2["QUOTA_EXCEEDED"] = "QUOTA_EXCEEDED";
52
+ ByokyErrorCode2["INVALID_KEY"] = "INVALID_KEY";
53
+ ByokyErrorCode2["TOKEN_EXPIRED"] = "TOKEN_EXPIRED";
54
+ ByokyErrorCode2["PROXY_ERROR"] = "PROXY_ERROR";
55
+ ByokyErrorCode2["UNKNOWN"] = "UNKNOWN";
56
+ return ByokyErrorCode2;
57
+ })(ByokyErrorCode || {});
58
+
59
+ // src/crypto.ts
60
+ var SALT_LENGTH = 16;
61
+ var IV_LENGTH = 12;
62
+ var KEY_LENGTH = 256;
63
+ var ITERATIONS = 6e5;
64
+ async function deriveKey(password, salt) {
65
+ const keyMaterial = await crypto.subtle.importKey(
66
+ "raw",
67
+ new TextEncoder().encode(password),
68
+ "PBKDF2",
69
+ false,
70
+ ["deriveKey"]
71
+ );
72
+ return crypto.subtle.deriveKey(
73
+ { name: "PBKDF2", salt, iterations: ITERATIONS, hash: "SHA-256" },
74
+ keyMaterial,
75
+ { name: "AES-GCM", length: KEY_LENGTH },
76
+ false,
77
+ ["encrypt", "decrypt"]
78
+ );
79
+ }
80
+ async function encrypt(plaintext, password) {
81
+ const salt = crypto.getRandomValues(new Uint8Array(SALT_LENGTH));
82
+ const iv = crypto.getRandomValues(new Uint8Array(IV_LENGTH));
83
+ const key = await deriveKey(password, salt);
84
+ const ciphertext = await crypto.subtle.encrypt(
85
+ { name: "AES-GCM", iv },
86
+ key,
87
+ new TextEncoder().encode(plaintext)
88
+ );
89
+ const combined = new Uint8Array(
90
+ salt.length + iv.length + new Uint8Array(ciphertext).length
91
+ );
92
+ combined.set(salt, 0);
93
+ combined.set(iv, salt.length);
94
+ combined.set(new Uint8Array(ciphertext), salt.length + iv.length);
95
+ return btoa(String.fromCharCode(...combined));
96
+ }
97
+ async function decrypt(encrypted, password) {
98
+ const combined = Uint8Array.from(atob(encrypted), (c) => c.charCodeAt(0));
99
+ const salt = combined.slice(0, SALT_LENGTH);
100
+ const iv = combined.slice(SALT_LENGTH, SALT_LENGTH + IV_LENGTH);
101
+ const ciphertext = combined.slice(SALT_LENGTH + IV_LENGTH);
102
+ const key = await deriveKey(password, salt);
103
+ const plaintext = await crypto.subtle.decrypt(
104
+ { name: "AES-GCM", iv },
105
+ key,
106
+ ciphertext
107
+ );
108
+ return new TextDecoder().decode(plaintext);
109
+ }
110
+ async function deriveRawHash(password, salt) {
111
+ const keyMaterial = await crypto.subtle.importKey(
112
+ "raw",
113
+ new TextEncoder().encode(password),
114
+ "PBKDF2",
115
+ false,
116
+ ["deriveBits"]
117
+ );
118
+ const bits = await crypto.subtle.deriveBits(
119
+ { name: "PBKDF2", salt, iterations: ITERATIONS, hash: "SHA-256" },
120
+ keyMaterial,
121
+ KEY_LENGTH
122
+ );
123
+ return new Uint8Array(bits);
124
+ }
125
+ async function hashPassword(password) {
126
+ const salt = crypto.getRandomValues(new Uint8Array(SALT_LENGTH));
127
+ const hash = await deriveRawHash(password, salt);
128
+ const combined = new Uint8Array(salt.length + hash.length);
129
+ combined.set(salt, 0);
130
+ combined.set(hash, salt.length);
131
+ return btoa(String.fromCharCode(...combined));
132
+ }
133
+ async function verifyPassword(password, storedHash) {
134
+ const combined = Uint8Array.from(atob(storedHash), (c) => c.charCodeAt(0));
135
+ const salt = combined.slice(0, SALT_LENGTH);
136
+ const originalHash = combined.slice(SALT_LENGTH);
137
+ const newHash = await deriveRawHash(password, salt);
138
+ if (originalHash.length !== newHash.length) return false;
139
+ return originalHash.every((byte, i) => byte === newHash[i]);
140
+ }
141
+ function maskKey(key) {
142
+ if (key.length <= 8) return "****";
143
+ return `${key.slice(0, 4)}...${key.slice(-4)}`;
144
+ }
145
+
146
+ // src/errors.ts
147
+ var ByokyError = class _ByokyError extends Error {
148
+ constructor(code, message, details) {
149
+ super(message);
150
+ this.code = code;
151
+ this.details = details;
152
+ this.name = "ByokyError";
153
+ }
154
+ static walletNotInstalled() {
155
+ return new _ByokyError(
156
+ "WALLET_NOT_INSTALLED" /* WALLET_NOT_INSTALLED */,
157
+ "byoky wallet extension is not installed"
158
+ );
159
+ }
160
+ static userRejected() {
161
+ return new _ByokyError(
162
+ "USER_REJECTED" /* USER_REJECTED */,
163
+ "User rejected the connection request"
164
+ );
165
+ }
166
+ static providerUnavailable(providerId) {
167
+ return new _ByokyError(
168
+ "PROVIDER_UNAVAILABLE" /* PROVIDER_UNAVAILABLE */,
169
+ `Provider "${providerId}" is not available`,
170
+ { providerId }
171
+ );
172
+ }
173
+ static sessionExpired() {
174
+ return new _ByokyError(
175
+ "SESSION_EXPIRED" /* SESSION_EXPIRED */,
176
+ "Session has expired \u2014 please reconnect"
177
+ );
178
+ }
179
+ static rateLimited(retryAfter) {
180
+ return new _ByokyError(
181
+ "RATE_LIMITED" /* RATE_LIMITED */,
182
+ `Rate limit exceeded${retryAfter ? ` \u2014 retry after ${retryAfter}s` : ""}`,
183
+ { retryAfter }
184
+ );
185
+ }
186
+ static quotaExceeded(providerId) {
187
+ return new _ByokyError(
188
+ "QUOTA_EXCEEDED" /* QUOTA_EXCEEDED */,
189
+ `Quota exceeded for ${providerId} \u2014 check your billing`,
190
+ { providerId }
191
+ );
192
+ }
193
+ static invalidKey(providerId) {
194
+ return new _ByokyError(
195
+ "INVALID_KEY" /* INVALID_KEY */,
196
+ `Invalid API key for ${providerId}`,
197
+ { providerId }
198
+ );
199
+ }
200
+ static tokenExpired(providerId) {
201
+ return new _ByokyError(
202
+ "TOKEN_EXPIRED" /* TOKEN_EXPIRED */,
203
+ `OAuth token expired for ${providerId} \u2014 re-authentication required`,
204
+ { providerId }
205
+ );
206
+ }
207
+ };
208
+
209
+ // src/protocol.ts
210
+ var BYOKY_PROVIDER_KEY = "__byoky__";
211
+ var BYOKY_MESSAGE_PREFIX = "BYOKY_";
212
+ function createMessage(type, payload, requestId) {
213
+ return {
214
+ type,
215
+ id: crypto.randomUUID(),
216
+ requestId,
217
+ payload
218
+ };
219
+ }
220
+ function isByokyMessage(data) {
221
+ return typeof data === "object" && data !== null && "type" in data && typeof data.type === "string" && data.type.startsWith(BYOKY_MESSAGE_PREFIX);
222
+ }
223
+ function createConnectRequest(request) {
224
+ return createMessage("BYOKY_CONNECT_REQUEST", request);
225
+ }
226
+ function createConnectResponse(response, requestId) {
227
+ return createMessage("BYOKY_CONNECT_RESPONSE", response, requestId);
228
+ }
229
+ function createErrorMessage(code, message, requestId) {
230
+ return createMessage("BYOKY_ERROR", { code, message }, requestId);
231
+ }
232
+
233
+ // src/providers.ts
234
+ var PROVIDERS = {
235
+ anthropic: {
236
+ id: "anthropic",
237
+ name: "Anthropic",
238
+ authMethods: ["api_key", "oauth"],
239
+ baseUrl: "https://api.anthropic.com",
240
+ oauthConfig: {
241
+ authorizationUrl: "https://console.anthropic.com/oauth/authorize",
242
+ tokenUrl: "https://console.anthropic.com/oauth/token",
243
+ scopes: []
244
+ }
245
+ },
246
+ openai: {
247
+ id: "openai",
248
+ name: "OpenAI",
249
+ authMethods: ["api_key"],
250
+ baseUrl: "https://api.openai.com"
251
+ },
252
+ gemini: {
253
+ id: "gemini",
254
+ name: "Google Gemini",
255
+ authMethods: ["api_key"],
256
+ baseUrl: "https://generativelanguage.googleapis.com"
257
+ }
258
+ };
259
+ function getProvider(id) {
260
+ return PROVIDERS[id];
261
+ }
262
+ function getProviderIds() {
263
+ return Object.keys(PROVIDERS);
264
+ }
265
+ // Annotate the CommonJS export names for ESM import in node:
266
+ 0 && (module.exports = {
267
+ BYOKY_MESSAGE_PREFIX,
268
+ BYOKY_PROVIDER_KEY,
269
+ ByokyError,
270
+ ByokyErrorCode,
271
+ PROVIDERS,
272
+ createConnectRequest,
273
+ createConnectResponse,
274
+ createErrorMessage,
275
+ createMessage,
276
+ decrypt,
277
+ deriveKey,
278
+ encrypt,
279
+ getProvider,
280
+ getProviderIds,
281
+ hashPassword,
282
+ isByokyMessage,
283
+ maskKey,
284
+ verifyPassword
285
+ });
286
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/types.ts","../src/crypto.ts","../src/errors.ts","../src/protocol.ts","../src/providers.ts"],"sourcesContent":["export * from './types.js';\nexport * from './crypto.js';\nexport * from './errors.js';\nexport * from './protocol.js';\nexport * from './providers.js';\n","export type ProviderId = 'anthropic' | 'openai' | 'gemini' | (string & {});\n\nexport type AuthMethod = 'api_key' | 'oauth';\n\nexport interface ProviderConfig {\n id: ProviderId;\n name: string;\n authMethods: AuthMethod[];\n baseUrl: string;\n oauthConfig?: OAuthConfig;\n}\n\nexport interface OAuthConfig {\n authorizationUrl: string;\n tokenUrl: string;\n scopes: string[];\n}\n\n// --- Credentials ---\n\nexport interface CredentialBase {\n id: string;\n providerId: ProviderId;\n label: string;\n authMethod: AuthMethod;\n createdAt: number;\n lastUsedAt?: number;\n}\n\nexport interface ApiKeyCredential extends CredentialBase {\n authMethod: 'api_key';\n encryptedKey: string;\n}\n\nexport interface OAuthCredential extends CredentialBase {\n authMethod: 'oauth';\n encryptedAccessToken: string;\n encryptedRefreshToken?: string;\n expiresAt?: number;\n}\n\nexport type Credential = ApiKeyCredential | OAuthCredential;\n\nexport interface CredentialMeta {\n id: string;\n providerId: ProviderId;\n label: string;\n authMethod: AuthMethod;\n createdAt: number;\n lastUsedAt?: number;\n maskedKey?: string;\n}\n\n// --- Sessions ---\n\nexport interface Session {\n id: string;\n sessionKey: string;\n appOrigin: string;\n appName?: string;\n providers: SessionProvider[];\n createdAt: number;\n expiresAt: number;\n}\n\nexport interface SessionProvider {\n providerId: ProviderId;\n credentialId: string;\n available: boolean;\n authMethod: AuthMethod;\n}\n\n// --- Connect ---\n\nexport interface ConnectRequest {\n providers?: ProviderRequirement[];\n capabilities?: string[];\n}\n\nexport interface ProviderRequirement {\n id: ProviderId;\n required: boolean;\n}\n\nexport interface ConnectResponse {\n sessionKey: string;\n proxyUrl: string;\n providers: Record<\n string,\n {\n available: boolean;\n authMethod: AuthMethod;\n }\n >;\n}\n\n// --- Proxy ---\n\nexport interface ProxyRequest {\n requestId: string;\n sessionKey: string;\n providerId: string;\n url: string;\n method: string;\n headers: Record<string, string>;\n body?: string;\n}\n\nexport interface ProxyResponseMeta {\n requestId: string;\n status: number;\n statusText: string;\n headers: Record<string, string>;\n}\n\nexport interface ProxyResponseChunk {\n requestId: string;\n chunk: string;\n}\n\nexport interface ProxyResponseError {\n requestId: string;\n status: number;\n error: { code: string; message: string };\n}\n\n// --- Protocol messages ---\n\nexport type MessageType =\n | 'BYOKY_CONNECT_REQUEST'\n | 'BYOKY_CONNECT_RESPONSE'\n | 'BYOKY_DISCONNECT'\n | 'BYOKY_PROXY_REQUEST'\n | 'BYOKY_PROXY_RESPONSE_META'\n | 'BYOKY_PROXY_RESPONSE_CHUNK'\n | 'BYOKY_PROXY_RESPONSE_DONE'\n | 'BYOKY_PROXY_RESPONSE_ERROR'\n | 'BYOKY_ERROR';\n\nexport interface ByokyMessage {\n type: MessageType;\n id: string;\n requestId?: string;\n payload: unknown;\n}\n\n// --- Errors ---\n\nexport enum ByokyErrorCode {\n WALLET_NOT_INSTALLED = 'WALLET_NOT_INSTALLED',\n USER_REJECTED = 'USER_REJECTED',\n PROVIDER_UNAVAILABLE = 'PROVIDER_UNAVAILABLE',\n SESSION_EXPIRED = 'SESSION_EXPIRED',\n RATE_LIMITED = 'RATE_LIMITED',\n QUOTA_EXCEEDED = 'QUOTA_EXCEEDED',\n INVALID_KEY = 'INVALID_KEY',\n TOKEN_EXPIRED = 'TOKEN_EXPIRED',\n PROXY_ERROR = 'PROXY_ERROR',\n UNKNOWN = 'UNKNOWN',\n}\n\n// --- Request log ---\n\nexport interface RequestLogEntry {\n id: string;\n sessionId: string;\n appOrigin: string;\n providerId: ProviderId;\n url: string;\n method: string;\n status: number;\n timestamp: number;\n error?: string;\n}\n\n// --- Pending approval ---\n\nexport interface PendingApproval {\n id: string;\n appOrigin: string;\n appName?: string;\n providers: ProviderRequirement[];\n timestamp: number;\n}\n","const SALT_LENGTH = 16;\nconst IV_LENGTH = 12;\nconst KEY_LENGTH = 256;\nconst ITERATIONS = 600_000;\n\nexport async function deriveKey(\n password: string,\n salt: Uint8Array,\n): Promise<CryptoKey> {\n const keyMaterial = await crypto.subtle.importKey(\n 'raw',\n new TextEncoder().encode(password),\n 'PBKDF2',\n false,\n ['deriveKey'],\n );\n\n return crypto.subtle.deriveKey(\n { name: 'PBKDF2', salt: salt as BufferSource, iterations: ITERATIONS, hash: 'SHA-256' },\n keyMaterial,\n { name: 'AES-GCM', length: KEY_LENGTH },\n false,\n ['encrypt', 'decrypt'],\n );\n}\n\nexport async function encrypt(\n plaintext: string,\n password: string,\n): Promise<string> {\n const salt = crypto.getRandomValues(new Uint8Array(SALT_LENGTH));\n const iv = crypto.getRandomValues(new Uint8Array(IV_LENGTH));\n const key = await deriveKey(password, salt);\n\n const ciphertext = await crypto.subtle.encrypt(\n { name: 'AES-GCM', iv },\n key,\n new TextEncoder().encode(plaintext),\n );\n\n const combined = new Uint8Array(\n salt.length + iv.length + new Uint8Array(ciphertext).length,\n );\n combined.set(salt, 0);\n combined.set(iv, salt.length);\n combined.set(new Uint8Array(ciphertext), salt.length + iv.length);\n\n return btoa(String.fromCharCode(...combined));\n}\n\nexport async function decrypt(\n encrypted: string,\n password: string,\n): Promise<string> {\n const combined = Uint8Array.from(atob(encrypted), (c) => c.charCodeAt(0));\n\n const salt = combined.slice(0, SALT_LENGTH);\n const iv = combined.slice(SALT_LENGTH, SALT_LENGTH + IV_LENGTH);\n const ciphertext = combined.slice(SALT_LENGTH + IV_LENGTH);\n\n const key = await deriveKey(password, salt);\n\n const plaintext = await crypto.subtle.decrypt(\n { name: 'AES-GCM', iv },\n key,\n ciphertext,\n );\n\n return new TextDecoder().decode(plaintext);\n}\n\nasync function deriveRawHash(\n password: string,\n salt: Uint8Array,\n): Promise<Uint8Array> {\n const keyMaterial = await crypto.subtle.importKey(\n 'raw',\n new TextEncoder().encode(password),\n 'PBKDF2',\n false,\n ['deriveBits'],\n );\n\n const bits = await crypto.subtle.deriveBits(\n { name: 'PBKDF2', salt: salt as BufferSource, iterations: ITERATIONS, hash: 'SHA-256' },\n keyMaterial,\n KEY_LENGTH,\n );\n\n return new Uint8Array(bits);\n}\n\nexport async function hashPassword(password: string): Promise<string> {\n const salt = crypto.getRandomValues(new Uint8Array(SALT_LENGTH));\n const hash = await deriveRawHash(password, salt);\n\n const combined = new Uint8Array(salt.length + hash.length);\n combined.set(salt, 0);\n combined.set(hash, salt.length);\n\n return btoa(String.fromCharCode(...combined));\n}\n\nexport async function verifyPassword(\n password: string,\n storedHash: string,\n): Promise<boolean> {\n const combined = Uint8Array.from(atob(storedHash), (c) => c.charCodeAt(0));\n const salt = combined.slice(0, SALT_LENGTH);\n const originalHash = combined.slice(SALT_LENGTH);\n\n const newHash = await deriveRawHash(password, salt);\n\n if (originalHash.length !== newHash.length) return false;\n return originalHash.every((byte, i) => byte === newHash[i]);\n}\n\nexport function maskKey(key: string): string {\n if (key.length <= 8) return '****';\n return `${key.slice(0, 4)}...${key.slice(-4)}`;\n}\n","import { ByokyErrorCode } from './types.js';\n\nexport class ByokyError extends Error {\n constructor(\n public readonly code: ByokyErrorCode,\n message: string,\n public readonly details?: Record<string, unknown>,\n ) {\n super(message);\n this.name = 'ByokyError';\n }\n\n static walletNotInstalled() {\n return new ByokyError(\n ByokyErrorCode.WALLET_NOT_INSTALLED,\n 'byoky wallet extension is not installed',\n );\n }\n\n static userRejected() {\n return new ByokyError(\n ByokyErrorCode.USER_REJECTED,\n 'User rejected the connection request',\n );\n }\n\n static providerUnavailable(providerId: string) {\n return new ByokyError(\n ByokyErrorCode.PROVIDER_UNAVAILABLE,\n `Provider \"${providerId}\" is not available`,\n { providerId },\n );\n }\n\n static sessionExpired() {\n return new ByokyError(\n ByokyErrorCode.SESSION_EXPIRED,\n 'Session has expired — please reconnect',\n );\n }\n\n static rateLimited(retryAfter?: number) {\n return new ByokyError(\n ByokyErrorCode.RATE_LIMITED,\n `Rate limit exceeded${retryAfter ? ` — retry after ${retryAfter}s` : ''}`,\n { retryAfter },\n );\n }\n\n static quotaExceeded(providerId: string) {\n return new ByokyError(\n ByokyErrorCode.QUOTA_EXCEEDED,\n `Quota exceeded for ${providerId} — check your billing`,\n { providerId },\n );\n }\n\n static invalidKey(providerId: string) {\n return new ByokyError(\n ByokyErrorCode.INVALID_KEY,\n `Invalid API key for ${providerId}`,\n { providerId },\n );\n }\n\n static tokenExpired(providerId: string) {\n return new ByokyError(\n ByokyErrorCode.TOKEN_EXPIRED,\n `OAuth token expired for ${providerId} — re-authentication required`,\n { providerId },\n );\n }\n}\n","import type {\n ByokyMessage,\n ConnectRequest,\n ConnectResponse,\n MessageType,\n} from './types.js';\n\nexport const BYOKY_PROVIDER_KEY = '__byoky__';\nexport const BYOKY_MESSAGE_PREFIX = 'BYOKY_';\n\nexport function createMessage(\n type: MessageType,\n payload: unknown,\n requestId?: string,\n): ByokyMessage {\n return {\n type,\n id: crypto.randomUUID(),\n requestId,\n payload,\n };\n}\n\nexport function isByokyMessage(data: unknown): data is ByokyMessage {\n return (\n typeof data === 'object' &&\n data !== null &&\n 'type' in data &&\n typeof (data as ByokyMessage).type === 'string' &&\n (data as ByokyMessage).type.startsWith(BYOKY_MESSAGE_PREFIX)\n );\n}\n\nexport function createConnectRequest(request: ConnectRequest): ByokyMessage {\n return createMessage('BYOKY_CONNECT_REQUEST', request);\n}\n\nexport function createConnectResponse(\n response: ConnectResponse,\n requestId: string,\n): ByokyMessage {\n return createMessage('BYOKY_CONNECT_RESPONSE', response, requestId);\n}\n\nexport function createErrorMessage(\n code: string,\n message: string,\n requestId?: string,\n): ByokyMessage {\n return createMessage('BYOKY_ERROR', { code, message }, requestId);\n}\n","import type { ProviderConfig } from './types.js';\n\nexport const PROVIDERS: Record<string, ProviderConfig> = {\n anthropic: {\n id: 'anthropic',\n name: 'Anthropic',\n authMethods: ['api_key', 'oauth'],\n baseUrl: 'https://api.anthropic.com',\n oauthConfig: {\n authorizationUrl: 'https://console.anthropic.com/oauth/authorize',\n tokenUrl: 'https://console.anthropic.com/oauth/token',\n scopes: [],\n },\n },\n openai: {\n id: 'openai',\n name: 'OpenAI',\n authMethods: ['api_key'],\n baseUrl: 'https://api.openai.com',\n },\n gemini: {\n id: 'gemini',\n name: 'Google Gemini',\n authMethods: ['api_key'],\n baseUrl: 'https://generativelanguage.googleapis.com',\n },\n};\n\nexport function getProvider(id: string): ProviderConfig | undefined {\n return PROVIDERS[id];\n}\n\nexport function getProviderIds(): string[] {\n return Object.keys(PROVIDERS);\n}\n"],"mappings":"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","names":["ByokyErrorCode"]}
@@ -0,0 +1,172 @@
1
+ type ProviderId = 'anthropic' | 'openai' | 'gemini' | (string & {});
2
+ type AuthMethod = 'api_key' | 'oauth';
3
+ interface ProviderConfig {
4
+ id: ProviderId;
5
+ name: string;
6
+ authMethods: AuthMethod[];
7
+ baseUrl: string;
8
+ oauthConfig?: OAuthConfig;
9
+ }
10
+ interface OAuthConfig {
11
+ authorizationUrl: string;
12
+ tokenUrl: string;
13
+ scopes: string[];
14
+ }
15
+ interface CredentialBase {
16
+ id: string;
17
+ providerId: ProviderId;
18
+ label: string;
19
+ authMethod: AuthMethod;
20
+ createdAt: number;
21
+ lastUsedAt?: number;
22
+ }
23
+ interface ApiKeyCredential extends CredentialBase {
24
+ authMethod: 'api_key';
25
+ encryptedKey: string;
26
+ }
27
+ interface OAuthCredential extends CredentialBase {
28
+ authMethod: 'oauth';
29
+ encryptedAccessToken: string;
30
+ encryptedRefreshToken?: string;
31
+ expiresAt?: number;
32
+ }
33
+ type Credential = ApiKeyCredential | OAuthCredential;
34
+ interface CredentialMeta {
35
+ id: string;
36
+ providerId: ProviderId;
37
+ label: string;
38
+ authMethod: AuthMethod;
39
+ createdAt: number;
40
+ lastUsedAt?: number;
41
+ maskedKey?: string;
42
+ }
43
+ interface Session {
44
+ id: string;
45
+ sessionKey: string;
46
+ appOrigin: string;
47
+ appName?: string;
48
+ providers: SessionProvider[];
49
+ createdAt: number;
50
+ expiresAt: number;
51
+ }
52
+ interface SessionProvider {
53
+ providerId: ProviderId;
54
+ credentialId: string;
55
+ available: boolean;
56
+ authMethod: AuthMethod;
57
+ }
58
+ interface ConnectRequest {
59
+ providers?: ProviderRequirement[];
60
+ capabilities?: string[];
61
+ }
62
+ interface ProviderRequirement {
63
+ id: ProviderId;
64
+ required: boolean;
65
+ }
66
+ interface ConnectResponse {
67
+ sessionKey: string;
68
+ proxyUrl: string;
69
+ providers: Record<string, {
70
+ available: boolean;
71
+ authMethod: AuthMethod;
72
+ }>;
73
+ }
74
+ interface ProxyRequest {
75
+ requestId: string;
76
+ sessionKey: string;
77
+ providerId: string;
78
+ url: string;
79
+ method: string;
80
+ headers: Record<string, string>;
81
+ body?: string;
82
+ }
83
+ interface ProxyResponseMeta {
84
+ requestId: string;
85
+ status: number;
86
+ statusText: string;
87
+ headers: Record<string, string>;
88
+ }
89
+ interface ProxyResponseChunk {
90
+ requestId: string;
91
+ chunk: string;
92
+ }
93
+ interface ProxyResponseError {
94
+ requestId: string;
95
+ status: number;
96
+ error: {
97
+ code: string;
98
+ message: string;
99
+ };
100
+ }
101
+ type MessageType = 'BYOKY_CONNECT_REQUEST' | 'BYOKY_CONNECT_RESPONSE' | 'BYOKY_DISCONNECT' | 'BYOKY_PROXY_REQUEST' | 'BYOKY_PROXY_RESPONSE_META' | 'BYOKY_PROXY_RESPONSE_CHUNK' | 'BYOKY_PROXY_RESPONSE_DONE' | 'BYOKY_PROXY_RESPONSE_ERROR' | 'BYOKY_ERROR';
102
+ interface ByokyMessage {
103
+ type: MessageType;
104
+ id: string;
105
+ requestId?: string;
106
+ payload: unknown;
107
+ }
108
+ declare enum ByokyErrorCode {
109
+ WALLET_NOT_INSTALLED = "WALLET_NOT_INSTALLED",
110
+ USER_REJECTED = "USER_REJECTED",
111
+ PROVIDER_UNAVAILABLE = "PROVIDER_UNAVAILABLE",
112
+ SESSION_EXPIRED = "SESSION_EXPIRED",
113
+ RATE_LIMITED = "RATE_LIMITED",
114
+ QUOTA_EXCEEDED = "QUOTA_EXCEEDED",
115
+ INVALID_KEY = "INVALID_KEY",
116
+ TOKEN_EXPIRED = "TOKEN_EXPIRED",
117
+ PROXY_ERROR = "PROXY_ERROR",
118
+ UNKNOWN = "UNKNOWN"
119
+ }
120
+ interface RequestLogEntry {
121
+ id: string;
122
+ sessionId: string;
123
+ appOrigin: string;
124
+ providerId: ProviderId;
125
+ url: string;
126
+ method: string;
127
+ status: number;
128
+ timestamp: number;
129
+ error?: string;
130
+ }
131
+ interface PendingApproval {
132
+ id: string;
133
+ appOrigin: string;
134
+ appName?: string;
135
+ providers: ProviderRequirement[];
136
+ timestamp: number;
137
+ }
138
+
139
+ declare function deriveKey(password: string, salt: Uint8Array): Promise<CryptoKey>;
140
+ declare function encrypt(plaintext: string, password: string): Promise<string>;
141
+ declare function decrypt(encrypted: string, password: string): Promise<string>;
142
+ declare function hashPassword(password: string): Promise<string>;
143
+ declare function verifyPassword(password: string, storedHash: string): Promise<boolean>;
144
+ declare function maskKey(key: string): string;
145
+
146
+ declare class ByokyError extends Error {
147
+ readonly code: ByokyErrorCode;
148
+ readonly details?: Record<string, unknown> | undefined;
149
+ constructor(code: ByokyErrorCode, message: string, details?: Record<string, unknown> | undefined);
150
+ static walletNotInstalled(): ByokyError;
151
+ static userRejected(): ByokyError;
152
+ static providerUnavailable(providerId: string): ByokyError;
153
+ static sessionExpired(): ByokyError;
154
+ static rateLimited(retryAfter?: number): ByokyError;
155
+ static quotaExceeded(providerId: string): ByokyError;
156
+ static invalidKey(providerId: string): ByokyError;
157
+ static tokenExpired(providerId: string): ByokyError;
158
+ }
159
+
160
+ declare const BYOKY_PROVIDER_KEY = "__byoky__";
161
+ declare const BYOKY_MESSAGE_PREFIX = "BYOKY_";
162
+ declare function createMessage(type: MessageType, payload: unknown, requestId?: string): ByokyMessage;
163
+ declare function isByokyMessage(data: unknown): data is ByokyMessage;
164
+ declare function createConnectRequest(request: ConnectRequest): ByokyMessage;
165
+ declare function createConnectResponse(response: ConnectResponse, requestId: string): ByokyMessage;
166
+ declare function createErrorMessage(code: string, message: string, requestId?: string): ByokyMessage;
167
+
168
+ declare const PROVIDERS: Record<string, ProviderConfig>;
169
+ declare function getProvider(id: string): ProviderConfig | undefined;
170
+ declare function getProviderIds(): string[];
171
+
172
+ export { type ApiKeyCredential, type AuthMethod, BYOKY_MESSAGE_PREFIX, BYOKY_PROVIDER_KEY, ByokyError, ByokyErrorCode, type ByokyMessage, type ConnectRequest, type ConnectResponse, type Credential, type CredentialBase, type CredentialMeta, type MessageType, type OAuthConfig, type OAuthCredential, PROVIDERS, type PendingApproval, type ProviderConfig, type ProviderId, type ProviderRequirement, type ProxyRequest, type ProxyResponseChunk, type ProxyResponseError, type ProxyResponseMeta, type RequestLogEntry, type Session, type SessionProvider, createConnectRequest, createConnectResponse, createErrorMessage, createMessage, decrypt, deriveKey, encrypt, getProvider, getProviderIds, hashPassword, isByokyMessage, maskKey, verifyPassword };
@@ -0,0 +1,172 @@
1
+ type ProviderId = 'anthropic' | 'openai' | 'gemini' | (string & {});
2
+ type AuthMethod = 'api_key' | 'oauth';
3
+ interface ProviderConfig {
4
+ id: ProviderId;
5
+ name: string;
6
+ authMethods: AuthMethod[];
7
+ baseUrl: string;
8
+ oauthConfig?: OAuthConfig;
9
+ }
10
+ interface OAuthConfig {
11
+ authorizationUrl: string;
12
+ tokenUrl: string;
13
+ scopes: string[];
14
+ }
15
+ interface CredentialBase {
16
+ id: string;
17
+ providerId: ProviderId;
18
+ label: string;
19
+ authMethod: AuthMethod;
20
+ createdAt: number;
21
+ lastUsedAt?: number;
22
+ }
23
+ interface ApiKeyCredential extends CredentialBase {
24
+ authMethod: 'api_key';
25
+ encryptedKey: string;
26
+ }
27
+ interface OAuthCredential extends CredentialBase {
28
+ authMethod: 'oauth';
29
+ encryptedAccessToken: string;
30
+ encryptedRefreshToken?: string;
31
+ expiresAt?: number;
32
+ }
33
+ type Credential = ApiKeyCredential | OAuthCredential;
34
+ interface CredentialMeta {
35
+ id: string;
36
+ providerId: ProviderId;
37
+ label: string;
38
+ authMethod: AuthMethod;
39
+ createdAt: number;
40
+ lastUsedAt?: number;
41
+ maskedKey?: string;
42
+ }
43
+ interface Session {
44
+ id: string;
45
+ sessionKey: string;
46
+ appOrigin: string;
47
+ appName?: string;
48
+ providers: SessionProvider[];
49
+ createdAt: number;
50
+ expiresAt: number;
51
+ }
52
+ interface SessionProvider {
53
+ providerId: ProviderId;
54
+ credentialId: string;
55
+ available: boolean;
56
+ authMethod: AuthMethod;
57
+ }
58
+ interface ConnectRequest {
59
+ providers?: ProviderRequirement[];
60
+ capabilities?: string[];
61
+ }
62
+ interface ProviderRequirement {
63
+ id: ProviderId;
64
+ required: boolean;
65
+ }
66
+ interface ConnectResponse {
67
+ sessionKey: string;
68
+ proxyUrl: string;
69
+ providers: Record<string, {
70
+ available: boolean;
71
+ authMethod: AuthMethod;
72
+ }>;
73
+ }
74
+ interface ProxyRequest {
75
+ requestId: string;
76
+ sessionKey: string;
77
+ providerId: string;
78
+ url: string;
79
+ method: string;
80
+ headers: Record<string, string>;
81
+ body?: string;
82
+ }
83
+ interface ProxyResponseMeta {
84
+ requestId: string;
85
+ status: number;
86
+ statusText: string;
87
+ headers: Record<string, string>;
88
+ }
89
+ interface ProxyResponseChunk {
90
+ requestId: string;
91
+ chunk: string;
92
+ }
93
+ interface ProxyResponseError {
94
+ requestId: string;
95
+ status: number;
96
+ error: {
97
+ code: string;
98
+ message: string;
99
+ };
100
+ }
101
+ type MessageType = 'BYOKY_CONNECT_REQUEST' | 'BYOKY_CONNECT_RESPONSE' | 'BYOKY_DISCONNECT' | 'BYOKY_PROXY_REQUEST' | 'BYOKY_PROXY_RESPONSE_META' | 'BYOKY_PROXY_RESPONSE_CHUNK' | 'BYOKY_PROXY_RESPONSE_DONE' | 'BYOKY_PROXY_RESPONSE_ERROR' | 'BYOKY_ERROR';
102
+ interface ByokyMessage {
103
+ type: MessageType;
104
+ id: string;
105
+ requestId?: string;
106
+ payload: unknown;
107
+ }
108
+ declare enum ByokyErrorCode {
109
+ WALLET_NOT_INSTALLED = "WALLET_NOT_INSTALLED",
110
+ USER_REJECTED = "USER_REJECTED",
111
+ PROVIDER_UNAVAILABLE = "PROVIDER_UNAVAILABLE",
112
+ SESSION_EXPIRED = "SESSION_EXPIRED",
113
+ RATE_LIMITED = "RATE_LIMITED",
114
+ QUOTA_EXCEEDED = "QUOTA_EXCEEDED",
115
+ INVALID_KEY = "INVALID_KEY",
116
+ TOKEN_EXPIRED = "TOKEN_EXPIRED",
117
+ PROXY_ERROR = "PROXY_ERROR",
118
+ UNKNOWN = "UNKNOWN"
119
+ }
120
+ interface RequestLogEntry {
121
+ id: string;
122
+ sessionId: string;
123
+ appOrigin: string;
124
+ providerId: ProviderId;
125
+ url: string;
126
+ method: string;
127
+ status: number;
128
+ timestamp: number;
129
+ error?: string;
130
+ }
131
+ interface PendingApproval {
132
+ id: string;
133
+ appOrigin: string;
134
+ appName?: string;
135
+ providers: ProviderRequirement[];
136
+ timestamp: number;
137
+ }
138
+
139
+ declare function deriveKey(password: string, salt: Uint8Array): Promise<CryptoKey>;
140
+ declare function encrypt(plaintext: string, password: string): Promise<string>;
141
+ declare function decrypt(encrypted: string, password: string): Promise<string>;
142
+ declare function hashPassword(password: string): Promise<string>;
143
+ declare function verifyPassword(password: string, storedHash: string): Promise<boolean>;
144
+ declare function maskKey(key: string): string;
145
+
146
+ declare class ByokyError extends Error {
147
+ readonly code: ByokyErrorCode;
148
+ readonly details?: Record<string, unknown> | undefined;
149
+ constructor(code: ByokyErrorCode, message: string, details?: Record<string, unknown> | undefined);
150
+ static walletNotInstalled(): ByokyError;
151
+ static userRejected(): ByokyError;
152
+ static providerUnavailable(providerId: string): ByokyError;
153
+ static sessionExpired(): ByokyError;
154
+ static rateLimited(retryAfter?: number): ByokyError;
155
+ static quotaExceeded(providerId: string): ByokyError;
156
+ static invalidKey(providerId: string): ByokyError;
157
+ static tokenExpired(providerId: string): ByokyError;
158
+ }
159
+
160
+ declare const BYOKY_PROVIDER_KEY = "__byoky__";
161
+ declare const BYOKY_MESSAGE_PREFIX = "BYOKY_";
162
+ declare function createMessage(type: MessageType, payload: unknown, requestId?: string): ByokyMessage;
163
+ declare function isByokyMessage(data: unknown): data is ByokyMessage;
164
+ declare function createConnectRequest(request: ConnectRequest): ByokyMessage;
165
+ declare function createConnectResponse(response: ConnectResponse, requestId: string): ByokyMessage;
166
+ declare function createErrorMessage(code: string, message: string, requestId?: string): ByokyMessage;
167
+
168
+ declare const PROVIDERS: Record<string, ProviderConfig>;
169
+ declare function getProvider(id: string): ProviderConfig | undefined;
170
+ declare function getProviderIds(): string[];
171
+
172
+ export { type ApiKeyCredential, type AuthMethod, BYOKY_MESSAGE_PREFIX, BYOKY_PROVIDER_KEY, ByokyError, ByokyErrorCode, type ByokyMessage, type ConnectRequest, type ConnectResponse, type Credential, type CredentialBase, type CredentialMeta, type MessageType, type OAuthConfig, type OAuthCredential, PROVIDERS, type PendingApproval, type ProviderConfig, type ProviderId, type ProviderRequirement, type ProxyRequest, type ProxyResponseChunk, type ProxyResponseError, type ProxyResponseMeta, type RequestLogEntry, type Session, type SessionProvider, createConnectRequest, createConnectResponse, createErrorMessage, createMessage, decrypt, deriveKey, encrypt, getProvider, getProviderIds, hashPassword, isByokyMessage, maskKey, verifyPassword };
package/dist/index.js ADDED
@@ -0,0 +1,242 @@
1
+ // src/types.ts
2
+ var ByokyErrorCode = /* @__PURE__ */ ((ByokyErrorCode2) => {
3
+ ByokyErrorCode2["WALLET_NOT_INSTALLED"] = "WALLET_NOT_INSTALLED";
4
+ ByokyErrorCode2["USER_REJECTED"] = "USER_REJECTED";
5
+ ByokyErrorCode2["PROVIDER_UNAVAILABLE"] = "PROVIDER_UNAVAILABLE";
6
+ ByokyErrorCode2["SESSION_EXPIRED"] = "SESSION_EXPIRED";
7
+ ByokyErrorCode2["RATE_LIMITED"] = "RATE_LIMITED";
8
+ ByokyErrorCode2["QUOTA_EXCEEDED"] = "QUOTA_EXCEEDED";
9
+ ByokyErrorCode2["INVALID_KEY"] = "INVALID_KEY";
10
+ ByokyErrorCode2["TOKEN_EXPIRED"] = "TOKEN_EXPIRED";
11
+ ByokyErrorCode2["PROXY_ERROR"] = "PROXY_ERROR";
12
+ ByokyErrorCode2["UNKNOWN"] = "UNKNOWN";
13
+ return ByokyErrorCode2;
14
+ })(ByokyErrorCode || {});
15
+
16
+ // src/crypto.ts
17
+ var SALT_LENGTH = 16;
18
+ var IV_LENGTH = 12;
19
+ var KEY_LENGTH = 256;
20
+ var ITERATIONS = 6e5;
21
+ async function deriveKey(password, salt) {
22
+ const keyMaterial = await crypto.subtle.importKey(
23
+ "raw",
24
+ new TextEncoder().encode(password),
25
+ "PBKDF2",
26
+ false,
27
+ ["deriveKey"]
28
+ );
29
+ return crypto.subtle.deriveKey(
30
+ { name: "PBKDF2", salt, iterations: ITERATIONS, hash: "SHA-256" },
31
+ keyMaterial,
32
+ { name: "AES-GCM", length: KEY_LENGTH },
33
+ false,
34
+ ["encrypt", "decrypt"]
35
+ );
36
+ }
37
+ async function encrypt(plaintext, password) {
38
+ const salt = crypto.getRandomValues(new Uint8Array(SALT_LENGTH));
39
+ const iv = crypto.getRandomValues(new Uint8Array(IV_LENGTH));
40
+ const key = await deriveKey(password, salt);
41
+ const ciphertext = await crypto.subtle.encrypt(
42
+ { name: "AES-GCM", iv },
43
+ key,
44
+ new TextEncoder().encode(plaintext)
45
+ );
46
+ const combined = new Uint8Array(
47
+ salt.length + iv.length + new Uint8Array(ciphertext).length
48
+ );
49
+ combined.set(salt, 0);
50
+ combined.set(iv, salt.length);
51
+ combined.set(new Uint8Array(ciphertext), salt.length + iv.length);
52
+ return btoa(String.fromCharCode(...combined));
53
+ }
54
+ async function decrypt(encrypted, password) {
55
+ const combined = Uint8Array.from(atob(encrypted), (c) => c.charCodeAt(0));
56
+ const salt = combined.slice(0, SALT_LENGTH);
57
+ const iv = combined.slice(SALT_LENGTH, SALT_LENGTH + IV_LENGTH);
58
+ const ciphertext = combined.slice(SALT_LENGTH + IV_LENGTH);
59
+ const key = await deriveKey(password, salt);
60
+ const plaintext = await crypto.subtle.decrypt(
61
+ { name: "AES-GCM", iv },
62
+ key,
63
+ ciphertext
64
+ );
65
+ return new TextDecoder().decode(plaintext);
66
+ }
67
+ async function deriveRawHash(password, salt) {
68
+ const keyMaterial = await crypto.subtle.importKey(
69
+ "raw",
70
+ new TextEncoder().encode(password),
71
+ "PBKDF2",
72
+ false,
73
+ ["deriveBits"]
74
+ );
75
+ const bits = await crypto.subtle.deriveBits(
76
+ { name: "PBKDF2", salt, iterations: ITERATIONS, hash: "SHA-256" },
77
+ keyMaterial,
78
+ KEY_LENGTH
79
+ );
80
+ return new Uint8Array(bits);
81
+ }
82
+ async function hashPassword(password) {
83
+ const salt = crypto.getRandomValues(new Uint8Array(SALT_LENGTH));
84
+ const hash = await deriveRawHash(password, salt);
85
+ const combined = new Uint8Array(salt.length + hash.length);
86
+ combined.set(salt, 0);
87
+ combined.set(hash, salt.length);
88
+ return btoa(String.fromCharCode(...combined));
89
+ }
90
+ async function verifyPassword(password, storedHash) {
91
+ const combined = Uint8Array.from(atob(storedHash), (c) => c.charCodeAt(0));
92
+ const salt = combined.slice(0, SALT_LENGTH);
93
+ const originalHash = combined.slice(SALT_LENGTH);
94
+ const newHash = await deriveRawHash(password, salt);
95
+ if (originalHash.length !== newHash.length) return false;
96
+ return originalHash.every((byte, i) => byte === newHash[i]);
97
+ }
98
+ function maskKey(key) {
99
+ if (key.length <= 8) return "****";
100
+ return `${key.slice(0, 4)}...${key.slice(-4)}`;
101
+ }
102
+
103
+ // src/errors.ts
104
+ var ByokyError = class _ByokyError extends Error {
105
+ constructor(code, message, details) {
106
+ super(message);
107
+ this.code = code;
108
+ this.details = details;
109
+ this.name = "ByokyError";
110
+ }
111
+ static walletNotInstalled() {
112
+ return new _ByokyError(
113
+ "WALLET_NOT_INSTALLED" /* WALLET_NOT_INSTALLED */,
114
+ "byoky wallet extension is not installed"
115
+ );
116
+ }
117
+ static userRejected() {
118
+ return new _ByokyError(
119
+ "USER_REJECTED" /* USER_REJECTED */,
120
+ "User rejected the connection request"
121
+ );
122
+ }
123
+ static providerUnavailable(providerId) {
124
+ return new _ByokyError(
125
+ "PROVIDER_UNAVAILABLE" /* PROVIDER_UNAVAILABLE */,
126
+ `Provider "${providerId}" is not available`,
127
+ { providerId }
128
+ );
129
+ }
130
+ static sessionExpired() {
131
+ return new _ByokyError(
132
+ "SESSION_EXPIRED" /* SESSION_EXPIRED */,
133
+ "Session has expired \u2014 please reconnect"
134
+ );
135
+ }
136
+ static rateLimited(retryAfter) {
137
+ return new _ByokyError(
138
+ "RATE_LIMITED" /* RATE_LIMITED */,
139
+ `Rate limit exceeded${retryAfter ? ` \u2014 retry after ${retryAfter}s` : ""}`,
140
+ { retryAfter }
141
+ );
142
+ }
143
+ static quotaExceeded(providerId) {
144
+ return new _ByokyError(
145
+ "QUOTA_EXCEEDED" /* QUOTA_EXCEEDED */,
146
+ `Quota exceeded for ${providerId} \u2014 check your billing`,
147
+ { providerId }
148
+ );
149
+ }
150
+ static invalidKey(providerId) {
151
+ return new _ByokyError(
152
+ "INVALID_KEY" /* INVALID_KEY */,
153
+ `Invalid API key for ${providerId}`,
154
+ { providerId }
155
+ );
156
+ }
157
+ static tokenExpired(providerId) {
158
+ return new _ByokyError(
159
+ "TOKEN_EXPIRED" /* TOKEN_EXPIRED */,
160
+ `OAuth token expired for ${providerId} \u2014 re-authentication required`,
161
+ { providerId }
162
+ );
163
+ }
164
+ };
165
+
166
+ // src/protocol.ts
167
+ var BYOKY_PROVIDER_KEY = "__byoky__";
168
+ var BYOKY_MESSAGE_PREFIX = "BYOKY_";
169
+ function createMessage(type, payload, requestId) {
170
+ return {
171
+ type,
172
+ id: crypto.randomUUID(),
173
+ requestId,
174
+ payload
175
+ };
176
+ }
177
+ function isByokyMessage(data) {
178
+ return typeof data === "object" && data !== null && "type" in data && typeof data.type === "string" && data.type.startsWith(BYOKY_MESSAGE_PREFIX);
179
+ }
180
+ function createConnectRequest(request) {
181
+ return createMessage("BYOKY_CONNECT_REQUEST", request);
182
+ }
183
+ function createConnectResponse(response, requestId) {
184
+ return createMessage("BYOKY_CONNECT_RESPONSE", response, requestId);
185
+ }
186
+ function createErrorMessage(code, message, requestId) {
187
+ return createMessage("BYOKY_ERROR", { code, message }, requestId);
188
+ }
189
+
190
+ // src/providers.ts
191
+ var PROVIDERS = {
192
+ anthropic: {
193
+ id: "anthropic",
194
+ name: "Anthropic",
195
+ authMethods: ["api_key", "oauth"],
196
+ baseUrl: "https://api.anthropic.com",
197
+ oauthConfig: {
198
+ authorizationUrl: "https://console.anthropic.com/oauth/authorize",
199
+ tokenUrl: "https://console.anthropic.com/oauth/token",
200
+ scopes: []
201
+ }
202
+ },
203
+ openai: {
204
+ id: "openai",
205
+ name: "OpenAI",
206
+ authMethods: ["api_key"],
207
+ baseUrl: "https://api.openai.com"
208
+ },
209
+ gemini: {
210
+ id: "gemini",
211
+ name: "Google Gemini",
212
+ authMethods: ["api_key"],
213
+ baseUrl: "https://generativelanguage.googleapis.com"
214
+ }
215
+ };
216
+ function getProvider(id) {
217
+ return PROVIDERS[id];
218
+ }
219
+ function getProviderIds() {
220
+ return Object.keys(PROVIDERS);
221
+ }
222
+ export {
223
+ BYOKY_MESSAGE_PREFIX,
224
+ BYOKY_PROVIDER_KEY,
225
+ ByokyError,
226
+ ByokyErrorCode,
227
+ PROVIDERS,
228
+ createConnectRequest,
229
+ createConnectResponse,
230
+ createErrorMessage,
231
+ createMessage,
232
+ decrypt,
233
+ deriveKey,
234
+ encrypt,
235
+ getProvider,
236
+ getProviderIds,
237
+ hashPassword,
238
+ isByokyMessage,
239
+ maskKey,
240
+ verifyPassword
241
+ };
242
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/types.ts","../src/crypto.ts","../src/errors.ts","../src/protocol.ts","../src/providers.ts"],"sourcesContent":["export type ProviderId = 'anthropic' | 'openai' | 'gemini' | (string & {});\n\nexport type AuthMethod = 'api_key' | 'oauth';\n\nexport interface ProviderConfig {\n id: ProviderId;\n name: string;\n authMethods: AuthMethod[];\n baseUrl: string;\n oauthConfig?: OAuthConfig;\n}\n\nexport interface OAuthConfig {\n authorizationUrl: string;\n tokenUrl: string;\n scopes: string[];\n}\n\n// --- Credentials ---\n\nexport interface CredentialBase {\n id: string;\n providerId: ProviderId;\n label: string;\n authMethod: AuthMethod;\n createdAt: number;\n lastUsedAt?: number;\n}\n\nexport interface ApiKeyCredential extends CredentialBase {\n authMethod: 'api_key';\n encryptedKey: string;\n}\n\nexport interface OAuthCredential extends CredentialBase {\n authMethod: 'oauth';\n encryptedAccessToken: string;\n encryptedRefreshToken?: string;\n expiresAt?: number;\n}\n\nexport type Credential = ApiKeyCredential | OAuthCredential;\n\nexport interface CredentialMeta {\n id: string;\n providerId: ProviderId;\n label: string;\n authMethod: AuthMethod;\n createdAt: number;\n lastUsedAt?: number;\n maskedKey?: string;\n}\n\n// --- Sessions ---\n\nexport interface Session {\n id: string;\n sessionKey: string;\n appOrigin: string;\n appName?: string;\n providers: SessionProvider[];\n createdAt: number;\n expiresAt: number;\n}\n\nexport interface SessionProvider {\n providerId: ProviderId;\n credentialId: string;\n available: boolean;\n authMethod: AuthMethod;\n}\n\n// --- Connect ---\n\nexport interface ConnectRequest {\n providers?: ProviderRequirement[];\n capabilities?: string[];\n}\n\nexport interface ProviderRequirement {\n id: ProviderId;\n required: boolean;\n}\n\nexport interface ConnectResponse {\n sessionKey: string;\n proxyUrl: string;\n providers: Record<\n string,\n {\n available: boolean;\n authMethod: AuthMethod;\n }\n >;\n}\n\n// --- Proxy ---\n\nexport interface ProxyRequest {\n requestId: string;\n sessionKey: string;\n providerId: string;\n url: string;\n method: string;\n headers: Record<string, string>;\n body?: string;\n}\n\nexport interface ProxyResponseMeta {\n requestId: string;\n status: number;\n statusText: string;\n headers: Record<string, string>;\n}\n\nexport interface ProxyResponseChunk {\n requestId: string;\n chunk: string;\n}\n\nexport interface ProxyResponseError {\n requestId: string;\n status: number;\n error: { code: string; message: string };\n}\n\n// --- Protocol messages ---\n\nexport type MessageType =\n | 'BYOKY_CONNECT_REQUEST'\n | 'BYOKY_CONNECT_RESPONSE'\n | 'BYOKY_DISCONNECT'\n | 'BYOKY_PROXY_REQUEST'\n | 'BYOKY_PROXY_RESPONSE_META'\n | 'BYOKY_PROXY_RESPONSE_CHUNK'\n | 'BYOKY_PROXY_RESPONSE_DONE'\n | 'BYOKY_PROXY_RESPONSE_ERROR'\n | 'BYOKY_ERROR';\n\nexport interface ByokyMessage {\n type: MessageType;\n id: string;\n requestId?: string;\n payload: unknown;\n}\n\n// --- Errors ---\n\nexport enum ByokyErrorCode {\n WALLET_NOT_INSTALLED = 'WALLET_NOT_INSTALLED',\n USER_REJECTED = 'USER_REJECTED',\n PROVIDER_UNAVAILABLE = 'PROVIDER_UNAVAILABLE',\n SESSION_EXPIRED = 'SESSION_EXPIRED',\n RATE_LIMITED = 'RATE_LIMITED',\n QUOTA_EXCEEDED = 'QUOTA_EXCEEDED',\n INVALID_KEY = 'INVALID_KEY',\n TOKEN_EXPIRED = 'TOKEN_EXPIRED',\n PROXY_ERROR = 'PROXY_ERROR',\n UNKNOWN = 'UNKNOWN',\n}\n\n// --- Request log ---\n\nexport interface RequestLogEntry {\n id: string;\n sessionId: string;\n appOrigin: string;\n providerId: ProviderId;\n url: string;\n method: string;\n status: number;\n timestamp: number;\n error?: string;\n}\n\n// --- Pending approval ---\n\nexport interface PendingApproval {\n id: string;\n appOrigin: string;\n appName?: string;\n providers: ProviderRequirement[];\n timestamp: number;\n}\n","const SALT_LENGTH = 16;\nconst IV_LENGTH = 12;\nconst KEY_LENGTH = 256;\nconst ITERATIONS = 600_000;\n\nexport async function deriveKey(\n password: string,\n salt: Uint8Array,\n): Promise<CryptoKey> {\n const keyMaterial = await crypto.subtle.importKey(\n 'raw',\n new TextEncoder().encode(password),\n 'PBKDF2',\n false,\n ['deriveKey'],\n );\n\n return crypto.subtle.deriveKey(\n { name: 'PBKDF2', salt: salt as BufferSource, iterations: ITERATIONS, hash: 'SHA-256' },\n keyMaterial,\n { name: 'AES-GCM', length: KEY_LENGTH },\n false,\n ['encrypt', 'decrypt'],\n );\n}\n\nexport async function encrypt(\n plaintext: string,\n password: string,\n): Promise<string> {\n const salt = crypto.getRandomValues(new Uint8Array(SALT_LENGTH));\n const iv = crypto.getRandomValues(new Uint8Array(IV_LENGTH));\n const key = await deriveKey(password, salt);\n\n const ciphertext = await crypto.subtle.encrypt(\n { name: 'AES-GCM', iv },\n key,\n new TextEncoder().encode(plaintext),\n );\n\n const combined = new Uint8Array(\n salt.length + iv.length + new Uint8Array(ciphertext).length,\n );\n combined.set(salt, 0);\n combined.set(iv, salt.length);\n combined.set(new Uint8Array(ciphertext), salt.length + iv.length);\n\n return btoa(String.fromCharCode(...combined));\n}\n\nexport async function decrypt(\n encrypted: string,\n password: string,\n): Promise<string> {\n const combined = Uint8Array.from(atob(encrypted), (c) => c.charCodeAt(0));\n\n const salt = combined.slice(0, SALT_LENGTH);\n const iv = combined.slice(SALT_LENGTH, SALT_LENGTH + IV_LENGTH);\n const ciphertext = combined.slice(SALT_LENGTH + IV_LENGTH);\n\n const key = await deriveKey(password, salt);\n\n const plaintext = await crypto.subtle.decrypt(\n { name: 'AES-GCM', iv },\n key,\n ciphertext,\n );\n\n return new TextDecoder().decode(plaintext);\n}\n\nasync function deriveRawHash(\n password: string,\n salt: Uint8Array,\n): Promise<Uint8Array> {\n const keyMaterial = await crypto.subtle.importKey(\n 'raw',\n new TextEncoder().encode(password),\n 'PBKDF2',\n false,\n ['deriveBits'],\n );\n\n const bits = await crypto.subtle.deriveBits(\n { name: 'PBKDF2', salt: salt as BufferSource, iterations: ITERATIONS, hash: 'SHA-256' },\n keyMaterial,\n KEY_LENGTH,\n );\n\n return new Uint8Array(bits);\n}\n\nexport async function hashPassword(password: string): Promise<string> {\n const salt = crypto.getRandomValues(new Uint8Array(SALT_LENGTH));\n const hash = await deriveRawHash(password, salt);\n\n const combined = new Uint8Array(salt.length + hash.length);\n combined.set(salt, 0);\n combined.set(hash, salt.length);\n\n return btoa(String.fromCharCode(...combined));\n}\n\nexport async function verifyPassword(\n password: string,\n storedHash: string,\n): Promise<boolean> {\n const combined = Uint8Array.from(atob(storedHash), (c) => c.charCodeAt(0));\n const salt = combined.slice(0, SALT_LENGTH);\n const originalHash = combined.slice(SALT_LENGTH);\n\n const newHash = await deriveRawHash(password, salt);\n\n if (originalHash.length !== newHash.length) return false;\n return originalHash.every((byte, i) => byte === newHash[i]);\n}\n\nexport function maskKey(key: string): string {\n if (key.length <= 8) return '****';\n return `${key.slice(0, 4)}...${key.slice(-4)}`;\n}\n","import { ByokyErrorCode } from './types.js';\n\nexport class ByokyError extends Error {\n constructor(\n public readonly code: ByokyErrorCode,\n message: string,\n public readonly details?: Record<string, unknown>,\n ) {\n super(message);\n this.name = 'ByokyError';\n }\n\n static walletNotInstalled() {\n return new ByokyError(\n ByokyErrorCode.WALLET_NOT_INSTALLED,\n 'byoky wallet extension is not installed',\n );\n }\n\n static userRejected() {\n return new ByokyError(\n ByokyErrorCode.USER_REJECTED,\n 'User rejected the connection request',\n );\n }\n\n static providerUnavailable(providerId: string) {\n return new ByokyError(\n ByokyErrorCode.PROVIDER_UNAVAILABLE,\n `Provider \"${providerId}\" is not available`,\n { providerId },\n );\n }\n\n static sessionExpired() {\n return new ByokyError(\n ByokyErrorCode.SESSION_EXPIRED,\n 'Session has expired — please reconnect',\n );\n }\n\n static rateLimited(retryAfter?: number) {\n return new ByokyError(\n ByokyErrorCode.RATE_LIMITED,\n `Rate limit exceeded${retryAfter ? ` — retry after ${retryAfter}s` : ''}`,\n { retryAfter },\n );\n }\n\n static quotaExceeded(providerId: string) {\n return new ByokyError(\n ByokyErrorCode.QUOTA_EXCEEDED,\n `Quota exceeded for ${providerId} — check your billing`,\n { providerId },\n );\n }\n\n static invalidKey(providerId: string) {\n return new ByokyError(\n ByokyErrorCode.INVALID_KEY,\n `Invalid API key for ${providerId}`,\n { providerId },\n );\n }\n\n static tokenExpired(providerId: string) {\n return new ByokyError(\n ByokyErrorCode.TOKEN_EXPIRED,\n `OAuth token expired for ${providerId} — re-authentication required`,\n { providerId },\n );\n }\n}\n","import type {\n ByokyMessage,\n ConnectRequest,\n ConnectResponse,\n MessageType,\n} from './types.js';\n\nexport const BYOKY_PROVIDER_KEY = '__byoky__';\nexport const BYOKY_MESSAGE_PREFIX = 'BYOKY_';\n\nexport function createMessage(\n type: MessageType,\n payload: unknown,\n requestId?: string,\n): ByokyMessage {\n return {\n type,\n id: crypto.randomUUID(),\n requestId,\n payload,\n };\n}\n\nexport function isByokyMessage(data: unknown): data is ByokyMessage {\n return (\n typeof data === 'object' &&\n data !== null &&\n 'type' in data &&\n typeof (data as ByokyMessage).type === 'string' &&\n (data as ByokyMessage).type.startsWith(BYOKY_MESSAGE_PREFIX)\n );\n}\n\nexport function createConnectRequest(request: ConnectRequest): ByokyMessage {\n return createMessage('BYOKY_CONNECT_REQUEST', request);\n}\n\nexport function createConnectResponse(\n response: ConnectResponse,\n requestId: string,\n): ByokyMessage {\n return createMessage('BYOKY_CONNECT_RESPONSE', response, requestId);\n}\n\nexport function createErrorMessage(\n code: string,\n message: string,\n requestId?: string,\n): ByokyMessage {\n return createMessage('BYOKY_ERROR', { code, message }, requestId);\n}\n","import type { ProviderConfig } from './types.js';\n\nexport const PROVIDERS: Record<string, ProviderConfig> = {\n anthropic: {\n id: 'anthropic',\n name: 'Anthropic',\n authMethods: ['api_key', 'oauth'],\n baseUrl: 'https://api.anthropic.com',\n oauthConfig: {\n authorizationUrl: 'https://console.anthropic.com/oauth/authorize',\n tokenUrl: 'https://console.anthropic.com/oauth/token',\n scopes: [],\n },\n },\n openai: {\n id: 'openai',\n name: 'OpenAI',\n authMethods: ['api_key'],\n baseUrl: 'https://api.openai.com',\n },\n gemini: {\n id: 'gemini',\n name: 'Google Gemini',\n authMethods: ['api_key'],\n baseUrl: 'https://generativelanguage.googleapis.com',\n },\n};\n\nexport function getProvider(id: string): ProviderConfig | undefined {\n return PROVIDERS[id];\n}\n\nexport function getProviderIds(): string[] {\n return Object.keys(PROVIDERS);\n}\n"],"mappings":"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","names":["ByokyErrorCode"]}
package/package.json ADDED
@@ -0,0 +1,32 @@
1
+ {
2
+ "name": "@byoky/core",
3
+ "version": "0.1.0",
4
+ "type": "module",
5
+ "main": "./dist/index.cjs",
6
+ "module": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.js",
12
+ "require": "./dist/index.cjs"
13
+ }
14
+ },
15
+ "files": ["dist", "README.md", "LICENSE"],
16
+ "scripts": {
17
+ "build": "tsup",
18
+ "typecheck": "tsc --noEmit",
19
+ "clean": "rm -rf dist"
20
+ },
21
+ "license": "MIT",
22
+ "repository": {
23
+ "type": "git",
24
+ "url": "git+https://github.com/MichaelLod/byoky.git",
25
+ "directory": "packages/core"
26
+ },
27
+ "homepage": "https://byoky.com",
28
+ "keywords": ["byoky", "ai", "api-keys", "wallet", "encryption", "llm"],
29
+ "devDependencies": {
30
+ "typescript": "^5.7.0"
31
+ }
32
+ }