@liveauth-labs/sdk 0.1.1 → 0.2.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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/errors.ts"],"sourcesContent":["import type {\n LiveAuthResult,\n VerifyOptions,\n PowChallengeResponse,\n PowVerifyRequest,\n PowVerifyResponse,\n PowSolution,\n AuthStartResponse,\n AuthConfirmResponse,\n LiveAuthConfig, LightningStart\n} from './types';\nimport {LiveAuthCancelledError, LiveAuthTimeoutError} from \"./errors\";\n\nexport class LiveAuth {\n private readonly baseUrl: string;\n private readonly headers: HeadersInit;\n\n constructor(private readonly config: LiveAuthConfig) {\n if (!config.publicKey) {\n throw new Error('LiveAuth: publicKey is required');\n }\n\n this.baseUrl = config.baseUrl ?? 'https://api.liveauth.app';\n\n this.headers = {\n 'Content-Type': 'application/json',\n 'X-LW-Public': config.publicKey\n };\n }\n\n /* ======================================================\n * PUBLIC ENTRYPOINT\n * ====================================================== */\n\n async verify(): Promise<LiveAuthResult> {\n const startedAt = performance.now();\n\n const challenge = await this.getPowChallenge();\n const solution = await this.solvePow(challenge);\n\n const verifyRes = await this.verifyPow({\n challengeHex: challenge.challengeHex,\n nonce: solution.nonce,\n hashHex: solution.hashHex,\n expiresAtUnix: challenge.expiresAtUnix,\n sig: challenge.sig\n });\n\n if (verifyRes.verified && verifyRes.token) {\n return {\n method: 'pow',\n token: verifyRes.token,\n solveMs: Math.round(performance.now() - startedAt),\n difficultyBits: challenge.difficultyBits\n };\n }\n\n if (verifyRes.fallback === 'lightning') {\n const lightning = await this.startLightning();\n return {\n method: 'lightning',\n lightning\n };\n }\n\n throw new Error('LiveAuth: verification failed');\n }\n\n /* ======================================================\n * POW FLOW\n * ====================================================== */\n\n private async getPowChallenge(): Promise<PowChallengeResponse> {\n const res = await fetch(`${this.baseUrl}/api/public/pow/challenge`, {\n headers: this.headers\n });\n\n if (!res.ok) throw new Error('PoW challenge failed');\n return res.json();\n }\n\n private async verifyPow(req: PowVerifyRequest): Promise<PowVerifyResponse> {\n const res = await fetch(`${this.baseUrl}/api/public/pow/verify`, {\n method: 'POST',\n headers: this.headers,\n body: JSON.stringify(req)\n });\n\n if (!res.ok) throw new Error('PoW verify failed');\n return res.json();\n }\n\n /* ======================================================\n * POW SOLVER (WORKER)\n * ====================================================== */\n\n private solvePow(challenge: PowChallengeResponse): Promise<PowSolution> {\n if (!this.canUsePow()) {\n return Promise.reject(\n new Error('LiveAuth: PoW not supported in this environment')\n );\n }\n\n return new Promise((resolve, reject) => {\n const worker = new Worker(\n new URL('./pow.worker.js', import.meta.url),\n {type: 'module'}\n );\n\n worker.onmessage = e => {\n worker.terminate();\n resolve(e.data);\n };\n\n worker.onerror = e => {\n worker.terminate();\n reject(e);\n };\n\n worker.postMessage({\n projectPublicKey: challenge.projectPublicKey,\n challengeHex: challenge.challengeHex,\n targetHex: challenge.targetHex\n });\n });\n }\n\n /* ======================================================\n * LIGHTNING FALLBACK\n * ====================================================== */\n\n private async startLightning(): Promise<LightningStart> {\n const res = await fetch(`${this.baseUrl}/api/public/auth/start`, {\n method: 'POST',\n headers: this.headers,\n body: JSON.stringify({userHint: 'browser'})\n });\n\n if (!res.ok) {\n throw new Error('Lightning auth start failed');\n }\n\n return res.json();\n }\n\n private canUsePow(): boolean {\n try {\n // SSR / Node guard\n if (typeof window === 'undefined') return false;\n\n // Worker support\n if (typeof Worker === 'undefined') return false;\n\n // Basic URL support (needed for module workers)\n if (typeof URL === 'undefined') return false;\n\n return true;\n } catch {\n return false;\n }\n }\n\n async pollLightning(\n sessionId: string,\n options?: {\n timeoutMs?: number;\n signal?: AbortSignal;\n intervalMs?: number;\n }\n ): Promise<string> {\n const timeoutMs = options?.timeoutMs ?? 5 * 60_000; // 5 min\n const intervalMs = options?.intervalMs ?? 2000;\n const externalSignal = options?.signal;\n\n const controller = new AbortController();\n const signal = controller.signal;\n\n // If caller passes a signal, bridge it\n if (externalSignal) {\n if (externalSignal.aborted) {\n throw new LiveAuthCancelledError();\n }\n\n externalSignal.addEventListener('abort', () => {\n controller.abort();\n });\n }\n\n // Timeout enforcement\n const timeoutId = setTimeout(() => {\n controller.abort();\n }, timeoutMs);\n\n try {\n while (true) {\n if (signal.aborted) {\n throw externalSignal?.aborted\n ? new LiveAuthCancelledError()\n : new LiveAuthTimeoutError();\n }\n\n const res = await fetch(\n `${this.baseUrl}/api/public/auth/confirm`,\n {\n method: 'POST',\n headers: this.headers,\n body: JSON.stringify({sessionId}),\n signal\n }\n );\n\n if (!res.ok) {\n throw new Error('Lightning confirm failed');\n }\n\n const json = await res.json();\n\n if (json.verified && json.token) {\n return json.token;\n }\n\n await sleep(intervalMs);\n }\n } finally {\n clearTimeout(timeoutId);\n }\n }\n\n\n}\n\n/* ======================================================\n * UTILS\n * ====================================================== */\n\nconst sleep = (ms: number) =>\n new Promise(resolve => setTimeout(resolve, ms));\n","export class LiveAuthTimeoutError extends Error {\n constructor(message = 'Lightning verification timed out') {\n super(message);\n this.name = 'LiveAuthTimeoutError';\n }\n}\n\nexport class LiveAuthCancelledError extends Error {\n constructor(message = 'Lightning verification cancelled') {\n super(message);\n this.name = 'LiveAuthCancelledError';\n }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/index.ts","../src/errors.ts"],"sourcesContent":["import type {\n LiveAuthResult,\n VerifyOptions,\n PowChallengeResponse,\n PowVerifyRequest,\n PowVerifyResponse,\n PowSolution,\n LiveAuthConfig,\n LightningStart\n} from './types';\nimport {\n LiveAuthCancelledError,\n LiveAuthTimeoutError,\n LiveAuthNetworkError,\n LiveAuthPowUnsupportedError,\n LiveAuthPowTimeoutError\n} from './errors';\nimport type { PowWorkerResult } from './pow.worker';\n\n// Re-export for consumers\nexport * from './types';\nexport * from './errors';\n\nconst SDK_VERSION = '0.2.0';\n\nexport class LiveAuth {\n private readonly baseUrl: string;\n private readonly headers: HeadersInit;\n\n constructor(private readonly config: LiveAuthConfig) {\n if (!config.publicKey) {\n throw new Error('LiveAuth: publicKey is required');\n }\n\n this.baseUrl = config.baseUrl ?? 'https://api.liveauth.app';\n\n this.headers = {\n 'Content-Type': 'application/json',\n 'X-LW-Public': config.publicKey,\n 'X-LW-SDK-Version': SDK_VERSION\n };\n }\n\n /* ======================================================\n * PUBLIC ENTRYPOINT\n * ====================================================== */\n\n async verify(options: VerifyOptions = {}): Promise<LiveAuthResult> {\n const { \n forceLightning = false, \n onProgress,\n powTimeoutMs = 30_000,\n maxPowIterations = 50_000_000\n } = options;\n\n // Skip PoW if forced to Lightning or PoW not supported\n if (forceLightning) {\n const lightning = await this.startLightning();\n return {\n method: 'lightning',\n lightning,\n diagnostics: { reason: 'forced_lightning' }\n };\n }\n\n if (!this.canUsePow()) {\n const lightning = await this.startLightning();\n return {\n method: 'lightning',\n lightning,\n diagnostics: { reason: 'pow_unsupported' }\n };\n }\n\n const startedAt = performance.now();\n\n try {\n const challenge = await this.getPowChallenge();\n const solution = await this.solvePow(challenge, { \n onProgress, \n timeoutMs: powTimeoutMs,\n maxIterations: maxPowIterations\n });\n\n const verifyRes = await this.verifyPow({\n challengeHex: challenge.challengeHex,\n nonce: solution.nonce,\n hashHex: solution.hashHex,\n expiresAtUnix: challenge.expiresAtUnix,\n difficultyBits: challenge.difficultyBits,\n sig: challenge.sig\n });\n\n if (verifyRes.verified && verifyRes.token) {\n return {\n method: 'pow',\n token: verifyRes.token,\n solveMs: Math.round(performance.now() - startedAt),\n difficultyBits: challenge.difficultyBits\n };\n }\n\n if (verifyRes.fallback === 'lightning') {\n const lightning = await this.startLightning();\n return {\n method: 'lightning',\n lightning,\n diagnostics: { reason: 'pow_server_fallback' }\n };\n }\n\n throw new Error('LiveAuth: verification failed');\n\n } catch (err) {\n // On PoW failure, fall back to Lightning\n if (err instanceof LiveAuthPowTimeoutError || err instanceof LiveAuthPowUnsupportedError) {\n const lightning = await this.startLightning();\n return {\n method: 'lightning',\n lightning,\n diagnostics: { \n reason: 'pow_failed', \n detail: err.message \n }\n };\n }\n throw err;\n }\n }\n\n /* ======================================================\n * POW FLOW\n * ====================================================== */\n\n private async getPowChallenge(): Promise<PowChallengeResponse> {\n const res = await this.fetchWithRetry(`${this.baseUrl}/api/public/pow/challenge`, {\n headers: this.headers\n });\n\n if (!res.ok) throw new LiveAuthNetworkError('PoW challenge failed');\n return res.json();\n }\n\n private async verifyPow(req: PowVerifyRequest): Promise<PowVerifyResponse> {\n const res = await this.fetchWithRetry(`${this.baseUrl}/api/public/pow/verify`, {\n method: 'POST',\n headers: this.headers,\n body: JSON.stringify(req)\n });\n\n if (!res.ok) throw new LiveAuthNetworkError('PoW verify failed');\n return res.json();\n }\n\n /* ======================================================\n * POW SOLVER (WORKER)\n * ====================================================== */\n\n private solvePow(\n challenge: PowChallengeResponse, \n options: {\n onProgress?: (hashesPerSec: number, iterations: number) => void;\n timeoutMs?: number;\n maxIterations?: number;\n } = {}\n ): Promise<PowSolution> {\n const { onProgress, timeoutMs = 30_000, maxIterations = 50_000_000 } = options;\n\n if (!this.canUsePow()) {\n return Promise.reject(new LiveAuthPowUnsupportedError());\n }\n\n return new Promise((resolve, reject) => {\n const worker = new Worker(\n new URL('./pow.worker.js', import.meta.url),\n { type: 'module' }\n );\n\n const timeoutId = setTimeout(() => {\n worker.terminate();\n reject(new LiveAuthPowTimeoutError(`PoW timed out after ${timeoutMs}ms`));\n }, timeoutMs);\n\n worker.onmessage = (e: MessageEvent<PowWorkerResult>) => {\n const data = e.data;\n\n if (data.type === 'progress') {\n onProgress?.(data.hashesPerSec ?? 0, data.iterations ?? 0);\n return;\n }\n\n if (data.type === 'timeout') {\n clearTimeout(timeoutId);\n worker.terminate();\n reject(new LiveAuthPowTimeoutError(`PoW hit max iterations (${maxIterations})`));\n return;\n }\n\n if (data.type === 'solution' && data.nonce !== undefined && data.hashHex) {\n clearTimeout(timeoutId);\n worker.terminate();\n resolve({ nonce: data.nonce, hashHex: data.hashHex });\n return;\n }\n };\n\n worker.onerror = e => {\n clearTimeout(timeoutId);\n worker.terminate();\n reject(new LiveAuthPowUnsupportedError(`Worker error: ${e.message}`));\n };\n\n worker.postMessage({\n projectPublicKey: challenge.projectPublicKey,\n challengeHex: challenge.challengeHex,\n targetHex: challenge.targetHex,\n maxIterations\n });\n });\n }\n\n /* ======================================================\n * LIGHTNING FALLBACK\n * ====================================================== */\n\n private async startLightning(): Promise<LightningStart> {\n const res = await this.fetchWithRetry(`${this.baseUrl}/api/public/auth/start`, {\n method: 'POST',\n headers: this.headers,\n body: JSON.stringify({ userHint: 'browser' })\n });\n\n if (!res.ok) {\n throw new LiveAuthNetworkError('Lightning auth start failed');\n }\n\n return res.json();\n }\n\n async pollLightning(\n sessionId: string,\n options?: {\n timeoutMs?: number;\n signal?: AbortSignal;\n intervalMs?: number;\n }\n ): Promise<string> {\n const timeoutMs = options?.timeoutMs ?? 5 * 60_000; // 5 min\n const intervalMs = options?.intervalMs ?? 2000;\n const externalSignal = options?.signal;\n\n const controller = new AbortController();\n const signal = controller.signal;\n\n // If caller passes a signal, bridge it\n if (externalSignal) {\n if (externalSignal.aborted) {\n throw new LiveAuthCancelledError();\n }\n\n externalSignal.addEventListener('abort', () => {\n controller.abort();\n });\n }\n\n // Timeout enforcement\n const timeoutId = setTimeout(() => {\n controller.abort();\n }, timeoutMs);\n\n try {\n while (true) {\n if (signal.aborted) {\n throw externalSignal?.aborted\n ? new LiveAuthCancelledError()\n : new LiveAuthTimeoutError();\n }\n\n const res = await fetch(\n `${this.baseUrl}/api/public/auth/confirm`,\n {\n method: 'POST',\n headers: this.headers,\n body: JSON.stringify({ sessionId }),\n signal\n }\n );\n\n if (!res.ok) {\n throw new LiveAuthNetworkError('Lightning confirm failed');\n }\n\n const json = await res.json();\n\n if (json.verified && json.token) {\n return json.token;\n }\n\n await sleep(intervalMs);\n }\n } finally {\n clearTimeout(timeoutId);\n }\n }\n\n /* ======================================================\n * UTILITIES\n * ====================================================== */\n\n private canUsePow(): boolean {\n try {\n // SSR / Node guard\n if (typeof window === 'undefined') return false;\n\n // Worker support\n if (typeof Worker === 'undefined') return false;\n\n // Basic URL support (needed for module workers)\n if (typeof URL === 'undefined') return false;\n\n // Crypto.subtle required for SHA-256\n if (typeof crypto === 'undefined' || !crypto.subtle) return false;\n\n return true;\n } catch {\n return false;\n }\n }\n\n private async fetchWithRetry(\n url: string,\n init?: RequestInit,\n retries = 2,\n backoffMs = 500\n ): Promise<Response> {\n let lastError: Error | undefined;\n\n for (let attempt = 0; attempt <= retries; attempt++) {\n try {\n const res = await fetch(url, init);\n return res;\n } catch (err) {\n lastError = err instanceof Error ? err : new Error(String(err));\n \n if (attempt < retries) {\n await sleep(backoffMs * Math.pow(2, attempt));\n }\n }\n }\n\n throw new LiveAuthNetworkError(\n `Request failed after ${retries + 1} attempts`,\n lastError\n );\n }\n}\n\n/* ======================================================\n * UTILS\n * ====================================================== */\n\nconst sleep = (ms: number) =>\n new Promise(resolve => setTimeout(resolve, ms));\n","export class LiveAuthTimeoutError extends Error {\n constructor(message = 'LiveAuth verification timed out') {\n super(message);\n this.name = 'LiveAuthTimeoutError';\n }\n}\n\nexport class LiveAuthCancelledError extends Error {\n constructor(message = 'LiveAuth verification cancelled') {\n super(message);\n this.name = 'LiveAuthCancelledError';\n }\n}\n\nexport class LiveAuthNetworkError extends Error {\n constructor(message = 'LiveAuth network request failed', public readonly cause?: Error) {\n super(message);\n this.name = 'LiveAuthNetworkError';\n }\n}\n\nexport class LiveAuthPowUnsupportedError extends Error {\n constructor(message = 'Proof-of-Work is not supported in this environment') {\n super(message);\n this.name = 'LiveAuthPowUnsupportedError';\n }\n}\n\nexport class LiveAuthPowTimeoutError extends Error {\n constructor(message = 'Proof-of-Work timed out') {\n super(message);\n this.name = 'LiveAuthPowTimeoutError';\n }\n}\n"],"mappings":"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","names":[]}
package/dist/index.d.cts CHANGED
@@ -4,9 +4,40 @@ interface LiveAuthConfig {
4
4
  /** Optional API base URL (defaults to liveauth.app) */
5
5
  baseUrl?: string;
6
6
  }
7
- interface LiveAuthDiagnostics {
8
- reason?: 'forced_lightning' | 'pow_unsupported' | 'pow_failed' | 'pow_server_fallback' | 'unknown';
9
- detail?: string;
7
+ interface VerifyOptions {
8
+ /** Skip PoW and go straight to Lightning */
9
+ forceLightning?: boolean;
10
+ /** Progress callback for PoW solving */
11
+ onProgress?: (hashesPerSec: number, iterations: number) => void;
12
+ /** Max time to spend on PoW before falling back to Lightning (default: 30s) */
13
+ powTimeoutMs?: number;
14
+ /** Max iterations for PoW before falling back (default: 50M) */
15
+ maxPowIterations?: number;
16
+ }
17
+ interface PowChallengeResponse {
18
+ projectPublicKey: string;
19
+ challengeHex: string;
20
+ targetHex: string;
21
+ difficultyBits: number;
22
+ expiresAtUnix: number;
23
+ sig: string;
24
+ }
25
+ interface PowSolution {
26
+ nonce: number;
27
+ hashHex: string;
28
+ }
29
+ interface PowVerifyRequest {
30
+ challengeHex: string;
31
+ nonce: number;
32
+ hashHex: string;
33
+ expiresAtUnix: number;
34
+ difficultyBits: number;
35
+ sig: string;
36
+ }
37
+ interface PowVerifyResponse {
38
+ verified: boolean;
39
+ token?: string;
40
+ fallback?: 'lightning';
10
41
  }
11
42
  interface LightningStart {
12
43
  sessionId: string;
@@ -15,6 +46,22 @@ interface LightningStart {
15
46
  expiresAtUnix: number;
16
47
  mode: 'TEST' | 'LIVE';
17
48
  }
49
+ interface AuthStartResponse {
50
+ sessionId: string;
51
+ invoice?: string;
52
+ amountSats: number;
53
+ expiresAtUnix: number;
54
+ mode?: 'TEST' | 'LIVE';
55
+ }
56
+ interface AuthConfirmResponse {
57
+ verified: boolean;
58
+ token?: string;
59
+ }
60
+ interface LiveAuthDiagnostics {
61
+ reason?: 'forced_lightning' | 'pow_unsupported' | 'pow_failed' | 'pow_server_fallback';
62
+ detail?: string;
63
+ }
64
+ type LiveAuthMethod = 'pow' | 'lightning';
18
65
  type LiveAuthResult = {
19
66
  method: 'pow';
20
67
  token: string;
@@ -24,24 +71,43 @@ type LiveAuthResult = {
24
71
  } | {
25
72
  method: 'lightning';
26
73
  lightning: LightningStart;
74
+ diagnostics?: LiveAuthDiagnostics;
27
75
  };
28
76
 
77
+ declare class LiveAuthTimeoutError extends Error {
78
+ constructor(message?: string);
79
+ }
80
+ declare class LiveAuthCancelledError extends Error {
81
+ constructor(message?: string);
82
+ }
83
+ declare class LiveAuthNetworkError extends Error {
84
+ readonly cause?: Error | undefined;
85
+ constructor(message?: string, cause?: Error | undefined);
86
+ }
87
+ declare class LiveAuthPowUnsupportedError extends Error {
88
+ constructor(message?: string);
89
+ }
90
+ declare class LiveAuthPowTimeoutError extends Error {
91
+ constructor(message?: string);
92
+ }
93
+
29
94
  declare class LiveAuth {
30
95
  private readonly config;
31
96
  private readonly baseUrl;
32
97
  private readonly headers;
33
98
  constructor(config: LiveAuthConfig);
34
- verify(): Promise<LiveAuthResult>;
99
+ verify(options?: VerifyOptions): Promise<LiveAuthResult>;
35
100
  private getPowChallenge;
36
101
  private verifyPow;
37
102
  private solvePow;
38
103
  private startLightning;
39
- private canUsePow;
40
104
  pollLightning(sessionId: string, options?: {
41
105
  timeoutMs?: number;
42
106
  signal?: AbortSignal;
43
107
  intervalMs?: number;
44
108
  }): Promise<string>;
109
+ private canUsePow;
110
+ private fetchWithRetry;
45
111
  }
46
112
 
47
- export { LiveAuth };
113
+ export { type AuthConfirmResponse, type AuthStartResponse, type LightningStart, LiveAuth, LiveAuthCancelledError, type LiveAuthConfig, type LiveAuthDiagnostics, type LiveAuthMethod, LiveAuthNetworkError, LiveAuthPowTimeoutError, LiveAuthPowUnsupportedError, type LiveAuthResult, LiveAuthTimeoutError, type PowChallengeResponse, type PowSolution, type PowVerifyRequest, type PowVerifyResponse, type VerifyOptions };
package/dist/index.d.ts CHANGED
@@ -4,9 +4,40 @@ interface LiveAuthConfig {
4
4
  /** Optional API base URL (defaults to liveauth.app) */
5
5
  baseUrl?: string;
6
6
  }
7
- interface LiveAuthDiagnostics {
8
- reason?: 'forced_lightning' | 'pow_unsupported' | 'pow_failed' | 'pow_server_fallback' | 'unknown';
9
- detail?: string;
7
+ interface VerifyOptions {
8
+ /** Skip PoW and go straight to Lightning */
9
+ forceLightning?: boolean;
10
+ /** Progress callback for PoW solving */
11
+ onProgress?: (hashesPerSec: number, iterations: number) => void;
12
+ /** Max time to spend on PoW before falling back to Lightning (default: 30s) */
13
+ powTimeoutMs?: number;
14
+ /** Max iterations for PoW before falling back (default: 50M) */
15
+ maxPowIterations?: number;
16
+ }
17
+ interface PowChallengeResponse {
18
+ projectPublicKey: string;
19
+ challengeHex: string;
20
+ targetHex: string;
21
+ difficultyBits: number;
22
+ expiresAtUnix: number;
23
+ sig: string;
24
+ }
25
+ interface PowSolution {
26
+ nonce: number;
27
+ hashHex: string;
28
+ }
29
+ interface PowVerifyRequest {
30
+ challengeHex: string;
31
+ nonce: number;
32
+ hashHex: string;
33
+ expiresAtUnix: number;
34
+ difficultyBits: number;
35
+ sig: string;
36
+ }
37
+ interface PowVerifyResponse {
38
+ verified: boolean;
39
+ token?: string;
40
+ fallback?: 'lightning';
10
41
  }
11
42
  interface LightningStart {
12
43
  sessionId: string;
@@ -15,6 +46,22 @@ interface LightningStart {
15
46
  expiresAtUnix: number;
16
47
  mode: 'TEST' | 'LIVE';
17
48
  }
49
+ interface AuthStartResponse {
50
+ sessionId: string;
51
+ invoice?: string;
52
+ amountSats: number;
53
+ expiresAtUnix: number;
54
+ mode?: 'TEST' | 'LIVE';
55
+ }
56
+ interface AuthConfirmResponse {
57
+ verified: boolean;
58
+ token?: string;
59
+ }
60
+ interface LiveAuthDiagnostics {
61
+ reason?: 'forced_lightning' | 'pow_unsupported' | 'pow_failed' | 'pow_server_fallback';
62
+ detail?: string;
63
+ }
64
+ type LiveAuthMethod = 'pow' | 'lightning';
18
65
  type LiveAuthResult = {
19
66
  method: 'pow';
20
67
  token: string;
@@ -24,24 +71,43 @@ type LiveAuthResult = {
24
71
  } | {
25
72
  method: 'lightning';
26
73
  lightning: LightningStart;
74
+ diagnostics?: LiveAuthDiagnostics;
27
75
  };
28
76
 
77
+ declare class LiveAuthTimeoutError extends Error {
78
+ constructor(message?: string);
79
+ }
80
+ declare class LiveAuthCancelledError extends Error {
81
+ constructor(message?: string);
82
+ }
83
+ declare class LiveAuthNetworkError extends Error {
84
+ readonly cause?: Error | undefined;
85
+ constructor(message?: string, cause?: Error | undefined);
86
+ }
87
+ declare class LiveAuthPowUnsupportedError extends Error {
88
+ constructor(message?: string);
89
+ }
90
+ declare class LiveAuthPowTimeoutError extends Error {
91
+ constructor(message?: string);
92
+ }
93
+
29
94
  declare class LiveAuth {
30
95
  private readonly config;
31
96
  private readonly baseUrl;
32
97
  private readonly headers;
33
98
  constructor(config: LiveAuthConfig);
34
- verify(): Promise<LiveAuthResult>;
99
+ verify(options?: VerifyOptions): Promise<LiveAuthResult>;
35
100
  private getPowChallenge;
36
101
  private verifyPow;
37
102
  private solvePow;
38
103
  private startLightning;
39
- private canUsePow;
40
104
  pollLightning(sessionId: string, options?: {
41
105
  timeoutMs?: number;
42
106
  signal?: AbortSignal;
43
107
  intervalMs?: number;
44
108
  }): Promise<string>;
109
+ private canUsePow;
110
+ private fetchWithRetry;
45
111
  }
46
112
 
47
- export { LiveAuth };
113
+ export { type AuthConfirmResponse, type AuthStartResponse, type LightningStart, LiveAuth, LiveAuthCancelledError, type LiveAuthConfig, type LiveAuthDiagnostics, type LiveAuthMethod, LiveAuthNetworkError, LiveAuthPowTimeoutError, LiveAuthPowUnsupportedError, type LiveAuthResult, LiveAuthTimeoutError, type PowChallengeResponse, type PowSolution, type PowVerifyRequest, type PowVerifyResponse, type VerifyOptions };
package/dist/index.js CHANGED
@@ -1,18 +1,38 @@
1
1
  // src/errors.ts
2
2
  var LiveAuthTimeoutError = class extends Error {
3
- constructor(message = "Lightning verification timed out") {
3
+ constructor(message = "LiveAuth verification timed out") {
4
4
  super(message);
5
5
  this.name = "LiveAuthTimeoutError";
6
6
  }
7
7
  };
8
8
  var LiveAuthCancelledError = class extends Error {
9
- constructor(message = "Lightning verification cancelled") {
9
+ constructor(message = "LiveAuth verification cancelled") {
10
10
  super(message);
11
11
  this.name = "LiveAuthCancelledError";
12
12
  }
13
13
  };
14
+ var LiveAuthNetworkError = class extends Error {
15
+ constructor(message = "LiveAuth network request failed", cause) {
16
+ super(message);
17
+ this.cause = cause;
18
+ this.name = "LiveAuthNetworkError";
19
+ }
20
+ };
21
+ var LiveAuthPowUnsupportedError = class extends Error {
22
+ constructor(message = "Proof-of-Work is not supported in this environment") {
23
+ super(message);
24
+ this.name = "LiveAuthPowUnsupportedError";
25
+ }
26
+ };
27
+ var LiveAuthPowTimeoutError = class extends Error {
28
+ constructor(message = "Proof-of-Work timed out") {
29
+ super(message);
30
+ this.name = "LiveAuthPowTimeoutError";
31
+ }
32
+ };
14
33
 
15
34
  // src/index.ts
35
+ var SDK_VERSION = "0.2.0";
16
36
  var LiveAuth = class {
17
37
  constructor(config) {
18
38
  this.config = config;
@@ -22,85 +42,149 @@ var LiveAuth = class {
22
42
  this.baseUrl = config.baseUrl ?? "https://api.liveauth.app";
23
43
  this.headers = {
24
44
  "Content-Type": "application/json",
25
- "X-LW-Public": config.publicKey
45
+ "X-LW-Public": config.publicKey,
46
+ "X-LW-SDK-Version": SDK_VERSION
26
47
  };
27
48
  }
28
49
  /* ======================================================
29
50
  * PUBLIC ENTRYPOINT
30
51
  * ====================================================== */
31
- async verify() {
32
- const startedAt = performance.now();
33
- const challenge = await this.getPowChallenge();
34
- const solution = await this.solvePow(challenge);
35
- const verifyRes = await this.verifyPow({
36
- challengeHex: challenge.challengeHex,
37
- nonce: solution.nonce,
38
- hashHex: solution.hashHex,
39
- expiresAtUnix: challenge.expiresAtUnix,
40
- sig: challenge.sig
41
- });
42
- if (verifyRes.verified && verifyRes.token) {
52
+ async verify(options = {}) {
53
+ const {
54
+ forceLightning = false,
55
+ onProgress,
56
+ powTimeoutMs = 3e4,
57
+ maxPowIterations = 5e7
58
+ } = options;
59
+ if (forceLightning) {
60
+ const lightning = await this.startLightning();
43
61
  return {
44
- method: "pow",
45
- token: verifyRes.token,
46
- solveMs: Math.round(performance.now() - startedAt),
47
- difficultyBits: challenge.difficultyBits
62
+ method: "lightning",
63
+ lightning,
64
+ diagnostics: { reason: "forced_lightning" }
48
65
  };
49
66
  }
50
- if (verifyRes.fallback === "lightning") {
67
+ if (!this.canUsePow()) {
51
68
  const lightning = await this.startLightning();
52
69
  return {
53
70
  method: "lightning",
54
- lightning
71
+ lightning,
72
+ diagnostics: { reason: "pow_unsupported" }
55
73
  };
56
74
  }
57
- throw new Error("LiveAuth: verification failed");
75
+ const startedAt = performance.now();
76
+ try {
77
+ const challenge = await this.getPowChallenge();
78
+ const solution = await this.solvePow(challenge, {
79
+ onProgress,
80
+ timeoutMs: powTimeoutMs,
81
+ maxIterations: maxPowIterations
82
+ });
83
+ const verifyRes = await this.verifyPow({
84
+ challengeHex: challenge.challengeHex,
85
+ nonce: solution.nonce,
86
+ hashHex: solution.hashHex,
87
+ expiresAtUnix: challenge.expiresAtUnix,
88
+ difficultyBits: challenge.difficultyBits,
89
+ sig: challenge.sig
90
+ });
91
+ if (verifyRes.verified && verifyRes.token) {
92
+ return {
93
+ method: "pow",
94
+ token: verifyRes.token,
95
+ solveMs: Math.round(performance.now() - startedAt),
96
+ difficultyBits: challenge.difficultyBits
97
+ };
98
+ }
99
+ if (verifyRes.fallback === "lightning") {
100
+ const lightning = await this.startLightning();
101
+ return {
102
+ method: "lightning",
103
+ lightning,
104
+ diagnostics: { reason: "pow_server_fallback" }
105
+ };
106
+ }
107
+ throw new Error("LiveAuth: verification failed");
108
+ } catch (err) {
109
+ if (err instanceof LiveAuthPowTimeoutError || err instanceof LiveAuthPowUnsupportedError) {
110
+ const lightning = await this.startLightning();
111
+ return {
112
+ method: "lightning",
113
+ lightning,
114
+ diagnostics: {
115
+ reason: "pow_failed",
116
+ detail: err.message
117
+ }
118
+ };
119
+ }
120
+ throw err;
121
+ }
58
122
  }
59
123
  /* ======================================================
60
124
  * POW FLOW
61
125
  * ====================================================== */
62
126
  async getPowChallenge() {
63
- const res = await fetch(`${this.baseUrl}/api/public/pow/challenge`, {
127
+ const res = await this.fetchWithRetry(`${this.baseUrl}/api/public/pow/challenge`, {
64
128
  headers: this.headers
65
129
  });
66
- if (!res.ok) throw new Error("PoW challenge failed");
130
+ if (!res.ok) throw new LiveAuthNetworkError("PoW challenge failed");
67
131
  return res.json();
68
132
  }
69
133
  async verifyPow(req) {
70
- const res = await fetch(`${this.baseUrl}/api/public/pow/verify`, {
134
+ const res = await this.fetchWithRetry(`${this.baseUrl}/api/public/pow/verify`, {
71
135
  method: "POST",
72
136
  headers: this.headers,
73
137
  body: JSON.stringify(req)
74
138
  });
75
- if (!res.ok) throw new Error("PoW verify failed");
139
+ if (!res.ok) throw new LiveAuthNetworkError("PoW verify failed");
76
140
  return res.json();
77
141
  }
78
142
  /* ======================================================
79
143
  * POW SOLVER (WORKER)
80
144
  * ====================================================== */
81
- solvePow(challenge) {
145
+ solvePow(challenge, options = {}) {
146
+ const { onProgress, timeoutMs = 3e4, maxIterations = 5e7 } = options;
82
147
  if (!this.canUsePow()) {
83
- return Promise.reject(
84
- new Error("LiveAuth: PoW not supported in this environment")
85
- );
148
+ return Promise.reject(new LiveAuthPowUnsupportedError());
86
149
  }
87
150
  return new Promise((resolve, reject) => {
88
151
  const worker = new Worker(
89
152
  new URL("./pow.worker.js", import.meta.url),
90
153
  { type: "module" }
91
154
  );
92
- worker.onmessage = (e) => {
155
+ const timeoutId = setTimeout(() => {
93
156
  worker.terminate();
94
- resolve(e.data);
157
+ reject(new LiveAuthPowTimeoutError(`PoW timed out after ${timeoutMs}ms`));
158
+ }, timeoutMs);
159
+ worker.onmessage = (e) => {
160
+ const data = e.data;
161
+ if (data.type === "progress") {
162
+ onProgress?.(data.hashesPerSec ?? 0, data.iterations ?? 0);
163
+ return;
164
+ }
165
+ if (data.type === "timeout") {
166
+ clearTimeout(timeoutId);
167
+ worker.terminate();
168
+ reject(new LiveAuthPowTimeoutError(`PoW hit max iterations (${maxIterations})`));
169
+ return;
170
+ }
171
+ if (data.type === "solution" && data.nonce !== void 0 && data.hashHex) {
172
+ clearTimeout(timeoutId);
173
+ worker.terminate();
174
+ resolve({ nonce: data.nonce, hashHex: data.hashHex });
175
+ return;
176
+ }
95
177
  };
96
178
  worker.onerror = (e) => {
179
+ clearTimeout(timeoutId);
97
180
  worker.terminate();
98
- reject(e);
181
+ reject(new LiveAuthPowUnsupportedError(`Worker error: ${e.message}`));
99
182
  };
100
183
  worker.postMessage({
101
184
  projectPublicKey: challenge.projectPublicKey,
102
185
  challengeHex: challenge.challengeHex,
103
- targetHex: challenge.targetHex
186
+ targetHex: challenge.targetHex,
187
+ maxIterations
104
188
  });
105
189
  });
106
190
  }
@@ -108,26 +192,16 @@ var LiveAuth = class {
108
192
  * LIGHTNING FALLBACK
109
193
  * ====================================================== */
110
194
  async startLightning() {
111
- const res = await fetch(`${this.baseUrl}/api/public/auth/start`, {
195
+ const res = await this.fetchWithRetry(`${this.baseUrl}/api/public/auth/start`, {
112
196
  method: "POST",
113
197
  headers: this.headers,
114
198
  body: JSON.stringify({ userHint: "browser" })
115
199
  });
116
200
  if (!res.ok) {
117
- throw new Error("Lightning auth start failed");
201
+ throw new LiveAuthNetworkError("Lightning auth start failed");
118
202
  }
119
203
  return res.json();
120
204
  }
121
- canUsePow() {
122
- try {
123
- if (typeof window === "undefined") return false;
124
- if (typeof Worker === "undefined") return false;
125
- if (typeof URL === "undefined") return false;
126
- return true;
127
- } catch {
128
- return false;
129
- }
130
- }
131
205
  async pollLightning(sessionId, options) {
132
206
  const timeoutMs = options?.timeoutMs ?? 5 * 6e4;
133
207
  const intervalMs = options?.intervalMs ?? 2e3;
@@ -160,7 +234,7 @@ var LiveAuth = class {
160
234
  }
161
235
  );
162
236
  if (!res.ok) {
163
- throw new Error("Lightning confirm failed");
237
+ throw new LiveAuthNetworkError("Lightning confirm failed");
164
238
  }
165
239
  const json = await res.json();
166
240
  if (json.verified && json.token) {
@@ -172,9 +246,46 @@ var LiveAuth = class {
172
246
  clearTimeout(timeoutId);
173
247
  }
174
248
  }
249
+ /* ======================================================
250
+ * UTILITIES
251
+ * ====================================================== */
252
+ canUsePow() {
253
+ try {
254
+ if (typeof window === "undefined") return false;
255
+ if (typeof Worker === "undefined") return false;
256
+ if (typeof URL === "undefined") return false;
257
+ if (typeof crypto === "undefined" || !crypto.subtle) return false;
258
+ return true;
259
+ } catch {
260
+ return false;
261
+ }
262
+ }
263
+ async fetchWithRetry(url, init, retries = 2, backoffMs = 500) {
264
+ let lastError;
265
+ for (let attempt = 0; attempt <= retries; attempt++) {
266
+ try {
267
+ const res = await fetch(url, init);
268
+ return res;
269
+ } catch (err) {
270
+ lastError = err instanceof Error ? err : new Error(String(err));
271
+ if (attempt < retries) {
272
+ await sleep(backoffMs * Math.pow(2, attempt));
273
+ }
274
+ }
275
+ }
276
+ throw new LiveAuthNetworkError(
277
+ `Request failed after ${retries + 1} attempts`,
278
+ lastError
279
+ );
280
+ }
175
281
  };
176
282
  var sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
177
283
  export {
178
- LiveAuth
284
+ LiveAuth,
285
+ LiveAuthCancelledError,
286
+ LiveAuthNetworkError,
287
+ LiveAuthPowTimeoutError,
288
+ LiveAuthPowUnsupportedError,
289
+ LiveAuthTimeoutError
179
290
  };
180
291
  //# sourceMappingURL=index.js.map