@liveauth-labs/sdk 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/LICENSE ADDED
File without changes
package/README.md ADDED
@@ -0,0 +1,103 @@
1
+ # LiveAuth – Developer Portal Documentation
2
+
3
+ ## Getting Started
4
+
5
+ LiveAuth verifies humans economically instead of heuristically.
6
+
7
+ Instead of CAPTCHAs or tracking, LiveAuth asks the browser to perform a short
8
+ cryptographic proof. If that fails or is skipped, it falls back to a small
9
+ Bitcoin Lightning payment.
10
+
11
+ No cookies.
12
+ No fingerprinting.
13
+ No behavioral profiling.
14
+
15
+ ---
16
+
17
+ ## What LiveAuth Does
18
+
19
+ When a user clicks “Verify”:
20
+
21
+ 1. **Browser attempts Proof-of-Work (PoW)**
22
+ – Takes ~200–800ms for a real device
23
+ – Bots pay CPU / battery cost
24
+
25
+ 2. **If PoW fails → Lightning fallback**
26
+ – Small payment (e.g. 21 sats)
27
+ – Real economic cost to bots
28
+
29
+ 3. **LiveAuth returns a short-lived JWT**
30
+ – Verifiable on your backend
31
+ – No user identity required
32
+
33
+ Most humans never see the Lightning step.
34
+
35
+ ---
36
+
37
+ ## Installation (JavaScript)
38
+
39
+ ```bash
40
+ npm install @liveauth/sdk
41
+ ```
42
+
43
+ ---
44
+
45
+ ## Basic Usage
46
+
47
+ ```ts
48
+ import { LiveAuth } from '@liveauth/sdk';
49
+
50
+ const liveauth = new LiveAuth({
51
+ publicKey: 'la_pk_XXXXXXXX'
52
+ });
53
+
54
+ const result = await liveauth.verify();
55
+ ```
56
+
57
+ ---
58
+
59
+ ## Example Result
60
+
61
+ ```ts
62
+ {
63
+ token: "eyJhbGciOi...",
64
+ method: "pow",
65
+ solveMs: 412,
66
+ difficultyBits: 18
67
+ }
68
+ ```
69
+
70
+ ---
71
+
72
+ ## Verifying on Your Backend
73
+
74
+ Send the JWT to your backend and verify it using your LiveAuth secret key.
75
+
76
+ The token includes:
77
+
78
+ - projectId
79
+ - projectPublicKey
80
+ - authType (pow or lightning)
81
+ - short expiration (default: 10 minutes)
82
+
83
+ ---
84
+
85
+ ## Why LiveAuth
86
+
87
+ | CAPTCHA | LiveAuth |
88
+ |-------|----------|
89
+ | Tracks behavior | No tracking |
90
+ | ML heuristics | Cryptography |
91
+ | CAPTCHA farms | Real economic cost |
92
+ | Bad UX | Invisible to humans |
93
+
94
+ ---
95
+
96
+ ## Debug Mode
97
+
98
+ Add `?liveauth_debug=1` to your URL to see:
99
+
100
+ - Verification method
101
+ - PoW difficulty
102
+ - Solve time
103
+ - Lightning fallback (demo mode)
package/dist/index.cjs ADDED
@@ -0,0 +1,208 @@
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 src_exports = {};
22
+ __export(src_exports, {
23
+ LiveAuth: () => LiveAuth
24
+ });
25
+ module.exports = __toCommonJS(src_exports);
26
+
27
+ // src/errors.ts
28
+ var LiveAuthTimeoutError = class extends Error {
29
+ constructor(message = "Lightning verification timed out") {
30
+ super(message);
31
+ this.name = "LiveAuthTimeoutError";
32
+ }
33
+ };
34
+ var LiveAuthCancelledError = class extends Error {
35
+ constructor(message = "Lightning verification cancelled") {
36
+ super(message);
37
+ this.name = "LiveAuthCancelledError";
38
+ }
39
+ };
40
+
41
+ // src/index.ts
42
+ var import_meta = {};
43
+ var LiveAuth = class {
44
+ constructor(config) {
45
+ this.config = config;
46
+ if (!config.publicKey) {
47
+ throw new Error("LiveAuth: publicKey is required");
48
+ }
49
+ this.baseUrl = config.baseUrl ?? "https://api.liveauth.app";
50
+ this.headers = {
51
+ "Content-Type": "application/json",
52
+ "X-LW-Public": config.publicKey
53
+ };
54
+ }
55
+ /* ======================================================
56
+ * PUBLIC ENTRYPOINT
57
+ * ====================================================== */
58
+ async verify() {
59
+ const startedAt = performance.now();
60
+ const challenge = await this.getPowChallenge();
61
+ const solution = await this.solvePow(challenge);
62
+ const verifyRes = await this.verifyPow({
63
+ challengeHex: challenge.challengeHex,
64
+ nonce: solution.nonce,
65
+ hashHex: solution.hashHex,
66
+ expiresAtUnix: challenge.expiresAtUnix,
67
+ sig: challenge.sig
68
+ });
69
+ if (verifyRes.verified && verifyRes.token) {
70
+ return {
71
+ method: "pow",
72
+ token: verifyRes.token,
73
+ solveMs: Math.round(performance.now() - startedAt),
74
+ difficultyBits: challenge.difficultyBits
75
+ };
76
+ }
77
+ if (verifyRes.fallback === "lightning") {
78
+ const lightning = await this.startLightning();
79
+ return {
80
+ method: "lightning",
81
+ lightning
82
+ };
83
+ }
84
+ throw new Error("LiveAuth: verification failed");
85
+ }
86
+ /* ======================================================
87
+ * POW FLOW
88
+ * ====================================================== */
89
+ async getPowChallenge() {
90
+ const res = await fetch(`${this.baseUrl}/api/public/pow/challenge`, {
91
+ headers: this.headers
92
+ });
93
+ if (!res.ok) throw new Error("PoW challenge failed");
94
+ return res.json();
95
+ }
96
+ async verifyPow(req) {
97
+ const res = await fetch(`${this.baseUrl}/api/public/pow/verify`, {
98
+ method: "POST",
99
+ headers: this.headers,
100
+ body: JSON.stringify(req)
101
+ });
102
+ if (!res.ok) throw new Error("PoW verify failed");
103
+ return res.json();
104
+ }
105
+ /* ======================================================
106
+ * POW SOLVER (WORKER)
107
+ * ====================================================== */
108
+ solvePow(challenge) {
109
+ if (!this.canUsePow()) {
110
+ return Promise.reject(
111
+ new Error("LiveAuth: PoW not supported in this environment")
112
+ );
113
+ }
114
+ return new Promise((resolve, reject) => {
115
+ const worker = new Worker(
116
+ new URL("./pow.worker.js", import_meta.url),
117
+ { type: "module" }
118
+ );
119
+ worker.onmessage = (e) => {
120
+ worker.terminate();
121
+ resolve(e.data);
122
+ };
123
+ worker.onerror = (e) => {
124
+ worker.terminate();
125
+ reject(e);
126
+ };
127
+ worker.postMessage({
128
+ projectPublicKey: challenge.projectPublicKey,
129
+ challengeHex: challenge.challengeHex,
130
+ targetHex: challenge.targetHex
131
+ });
132
+ });
133
+ }
134
+ /* ======================================================
135
+ * LIGHTNING FALLBACK
136
+ * ====================================================== */
137
+ async startLightning() {
138
+ const res = await fetch(`${this.baseUrl}/api/public/auth/start`, {
139
+ method: "POST",
140
+ headers: this.headers,
141
+ body: JSON.stringify({ userHint: "browser" })
142
+ });
143
+ if (!res.ok) {
144
+ throw new Error("Lightning auth start failed");
145
+ }
146
+ return res.json();
147
+ }
148
+ canUsePow() {
149
+ try {
150
+ if (typeof window === "undefined") return false;
151
+ if (typeof Worker === "undefined") return false;
152
+ if (typeof URL === "undefined") return false;
153
+ return true;
154
+ } catch {
155
+ return false;
156
+ }
157
+ }
158
+ async pollLightning(sessionId, options) {
159
+ const timeoutMs = options?.timeoutMs ?? 5 * 6e4;
160
+ const intervalMs = options?.intervalMs ?? 2e3;
161
+ const externalSignal = options?.signal;
162
+ const controller = new AbortController();
163
+ const signal = controller.signal;
164
+ if (externalSignal) {
165
+ if (externalSignal.aborted) {
166
+ throw new LiveAuthCancelledError();
167
+ }
168
+ externalSignal.addEventListener("abort", () => {
169
+ controller.abort();
170
+ });
171
+ }
172
+ const timeoutId = setTimeout(() => {
173
+ controller.abort();
174
+ }, timeoutMs);
175
+ try {
176
+ while (true) {
177
+ if (signal.aborted) {
178
+ throw externalSignal?.aborted ? new LiveAuthCancelledError() : new LiveAuthTimeoutError();
179
+ }
180
+ const res = await fetch(
181
+ `${this.baseUrl}/api/public/auth/confirm`,
182
+ {
183
+ method: "POST",
184
+ headers: this.headers,
185
+ body: JSON.stringify({ sessionId }),
186
+ signal
187
+ }
188
+ );
189
+ if (!res.ok) {
190
+ throw new Error("Lightning confirm failed");
191
+ }
192
+ const json = await res.json();
193
+ if (json.verified && json.token) {
194
+ return json.token;
195
+ }
196
+ await sleep(intervalMs);
197
+ }
198
+ } finally {
199
+ clearTimeout(timeoutId);
200
+ }
201
+ }
202
+ };
203
+ var sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
204
+ // Annotate the CommonJS export names for ESM import in node:
205
+ 0 && (module.exports = {
206
+ LiveAuth
207
+ });
208
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +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":[]}
@@ -0,0 +1,47 @@
1
+ interface LiveAuthConfig {
2
+ /** Public project key (browser-safe) */
3
+ publicKey: string;
4
+ /** Optional API base URL (defaults to liveauth.app) */
5
+ baseUrl?: string;
6
+ }
7
+ interface LiveAuthDiagnostics {
8
+ reason?: 'forced_lightning' | 'pow_unsupported' | 'pow_failed' | 'pow_server_fallback' | 'unknown';
9
+ detail?: string;
10
+ }
11
+ interface LightningStart {
12
+ sessionId: string;
13
+ invoice: string | null;
14
+ amountSats: number;
15
+ expiresAtUnix: number;
16
+ mode: 'TEST' | 'LIVE';
17
+ }
18
+ type LiveAuthResult = {
19
+ method: 'pow';
20
+ token: string;
21
+ solveMs: number;
22
+ difficultyBits: number;
23
+ diagnostics?: LiveAuthDiagnostics;
24
+ } | {
25
+ method: 'lightning';
26
+ lightning: LightningStart;
27
+ };
28
+
29
+ declare class LiveAuth {
30
+ private readonly config;
31
+ private readonly baseUrl;
32
+ private readonly headers;
33
+ constructor(config: LiveAuthConfig);
34
+ verify(): Promise<LiveAuthResult>;
35
+ private getPowChallenge;
36
+ private verifyPow;
37
+ private solvePow;
38
+ private startLightning;
39
+ private canUsePow;
40
+ pollLightning(sessionId: string, options?: {
41
+ timeoutMs?: number;
42
+ signal?: AbortSignal;
43
+ intervalMs?: number;
44
+ }): Promise<string>;
45
+ }
46
+
47
+ export { LiveAuth };
@@ -0,0 +1,47 @@
1
+ interface LiveAuthConfig {
2
+ /** Public project key (browser-safe) */
3
+ publicKey: string;
4
+ /** Optional API base URL (defaults to liveauth.app) */
5
+ baseUrl?: string;
6
+ }
7
+ interface LiveAuthDiagnostics {
8
+ reason?: 'forced_lightning' | 'pow_unsupported' | 'pow_failed' | 'pow_server_fallback' | 'unknown';
9
+ detail?: string;
10
+ }
11
+ interface LightningStart {
12
+ sessionId: string;
13
+ invoice: string | null;
14
+ amountSats: number;
15
+ expiresAtUnix: number;
16
+ mode: 'TEST' | 'LIVE';
17
+ }
18
+ type LiveAuthResult = {
19
+ method: 'pow';
20
+ token: string;
21
+ solveMs: number;
22
+ difficultyBits: number;
23
+ diagnostics?: LiveAuthDiagnostics;
24
+ } | {
25
+ method: 'lightning';
26
+ lightning: LightningStart;
27
+ };
28
+
29
+ declare class LiveAuth {
30
+ private readonly config;
31
+ private readonly baseUrl;
32
+ private readonly headers;
33
+ constructor(config: LiveAuthConfig);
34
+ verify(): Promise<LiveAuthResult>;
35
+ private getPowChallenge;
36
+ private verifyPow;
37
+ private solvePow;
38
+ private startLightning;
39
+ private canUsePow;
40
+ pollLightning(sessionId: string, options?: {
41
+ timeoutMs?: number;
42
+ signal?: AbortSignal;
43
+ intervalMs?: number;
44
+ }): Promise<string>;
45
+ }
46
+
47
+ export { LiveAuth };
package/dist/index.js ADDED
@@ -0,0 +1,180 @@
1
+ // src/errors.ts
2
+ var LiveAuthTimeoutError = class extends Error {
3
+ constructor(message = "Lightning verification timed out") {
4
+ super(message);
5
+ this.name = "LiveAuthTimeoutError";
6
+ }
7
+ };
8
+ var LiveAuthCancelledError = class extends Error {
9
+ constructor(message = "Lightning verification cancelled") {
10
+ super(message);
11
+ this.name = "LiveAuthCancelledError";
12
+ }
13
+ };
14
+
15
+ // src/index.ts
16
+ var LiveAuth = class {
17
+ constructor(config) {
18
+ this.config = config;
19
+ if (!config.publicKey) {
20
+ throw new Error("LiveAuth: publicKey is required");
21
+ }
22
+ this.baseUrl = config.baseUrl ?? "https://api.liveauth.app";
23
+ this.headers = {
24
+ "Content-Type": "application/json",
25
+ "X-LW-Public": config.publicKey
26
+ };
27
+ }
28
+ /* ======================================================
29
+ * PUBLIC ENTRYPOINT
30
+ * ====================================================== */
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) {
43
+ return {
44
+ method: "pow",
45
+ token: verifyRes.token,
46
+ solveMs: Math.round(performance.now() - startedAt),
47
+ difficultyBits: challenge.difficultyBits
48
+ };
49
+ }
50
+ if (verifyRes.fallback === "lightning") {
51
+ const lightning = await this.startLightning();
52
+ return {
53
+ method: "lightning",
54
+ lightning
55
+ };
56
+ }
57
+ throw new Error("LiveAuth: verification failed");
58
+ }
59
+ /* ======================================================
60
+ * POW FLOW
61
+ * ====================================================== */
62
+ async getPowChallenge() {
63
+ const res = await fetch(`${this.baseUrl}/api/public/pow/challenge`, {
64
+ headers: this.headers
65
+ });
66
+ if (!res.ok) throw new Error("PoW challenge failed");
67
+ return res.json();
68
+ }
69
+ async verifyPow(req) {
70
+ const res = await fetch(`${this.baseUrl}/api/public/pow/verify`, {
71
+ method: "POST",
72
+ headers: this.headers,
73
+ body: JSON.stringify(req)
74
+ });
75
+ if (!res.ok) throw new Error("PoW verify failed");
76
+ return res.json();
77
+ }
78
+ /* ======================================================
79
+ * POW SOLVER (WORKER)
80
+ * ====================================================== */
81
+ solvePow(challenge) {
82
+ if (!this.canUsePow()) {
83
+ return Promise.reject(
84
+ new Error("LiveAuth: PoW not supported in this environment")
85
+ );
86
+ }
87
+ return new Promise((resolve, reject) => {
88
+ const worker = new Worker(
89
+ new URL("./pow.worker.js", import.meta.url),
90
+ { type: "module" }
91
+ );
92
+ worker.onmessage = (e) => {
93
+ worker.terminate();
94
+ resolve(e.data);
95
+ };
96
+ worker.onerror = (e) => {
97
+ worker.terminate();
98
+ reject(e);
99
+ };
100
+ worker.postMessage({
101
+ projectPublicKey: challenge.projectPublicKey,
102
+ challengeHex: challenge.challengeHex,
103
+ targetHex: challenge.targetHex
104
+ });
105
+ });
106
+ }
107
+ /* ======================================================
108
+ * LIGHTNING FALLBACK
109
+ * ====================================================== */
110
+ async startLightning() {
111
+ const res = await fetch(`${this.baseUrl}/api/public/auth/start`, {
112
+ method: "POST",
113
+ headers: this.headers,
114
+ body: JSON.stringify({ userHint: "browser" })
115
+ });
116
+ if (!res.ok) {
117
+ throw new Error("Lightning auth start failed");
118
+ }
119
+ return res.json();
120
+ }
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
+ async pollLightning(sessionId, options) {
132
+ const timeoutMs = options?.timeoutMs ?? 5 * 6e4;
133
+ const intervalMs = options?.intervalMs ?? 2e3;
134
+ const externalSignal = options?.signal;
135
+ const controller = new AbortController();
136
+ const signal = controller.signal;
137
+ if (externalSignal) {
138
+ if (externalSignal.aborted) {
139
+ throw new LiveAuthCancelledError();
140
+ }
141
+ externalSignal.addEventListener("abort", () => {
142
+ controller.abort();
143
+ });
144
+ }
145
+ const timeoutId = setTimeout(() => {
146
+ controller.abort();
147
+ }, timeoutMs);
148
+ try {
149
+ while (true) {
150
+ if (signal.aborted) {
151
+ throw externalSignal?.aborted ? new LiveAuthCancelledError() : new LiveAuthTimeoutError();
152
+ }
153
+ const res = await fetch(
154
+ `${this.baseUrl}/api/public/auth/confirm`,
155
+ {
156
+ method: "POST",
157
+ headers: this.headers,
158
+ body: JSON.stringify({ sessionId }),
159
+ signal
160
+ }
161
+ );
162
+ if (!res.ok) {
163
+ throw new Error("Lightning confirm failed");
164
+ }
165
+ const json = await res.json();
166
+ if (json.verified && json.token) {
167
+ return json.token;
168
+ }
169
+ await sleep(intervalMs);
170
+ }
171
+ } finally {
172
+ clearTimeout(timeoutId);
173
+ }
174
+ }
175
+ };
176
+ var sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
177
+ export {
178
+ LiveAuth
179
+ };
180
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/errors.ts","../src/index.ts"],"sourcesContent":["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","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"],"mappings":"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","names":[]}
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+
3
+ // src/pow.worker.ts
4
+ self.onmessage = async (e) => {
5
+ const { projectPublicKey, challengeHex, targetHex } = e.data;
6
+ let nonce = 0;
7
+ while (true) {
8
+ const input = `${projectPublicKey}:${challengeHex}:${nonce}`;
9
+ const hash = await sha256Hex(input);
10
+ if (hash <= targetHex) {
11
+ postMessage({ nonce, hashHex: hash });
12
+ return;
13
+ }
14
+ nonce++;
15
+ }
16
+ };
17
+ async function sha256Hex(input) {
18
+ const buf = await crypto.subtle.digest(
19
+ "SHA-256",
20
+ new TextEncoder().encode(input)
21
+ );
22
+ return [...new Uint8Array(buf)].map((b) => b.toString(16).padStart(2, "0")).join("");
23
+ }
24
+ //# sourceMappingURL=pow.worker.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/pow.worker.ts"],"sourcesContent":["self.onmessage = async e => {\n const { projectPublicKey, challengeHex, targetHex } = e.data;\n\n let nonce = 0;\n\n while (true) {\n const input = `${projectPublicKey}:${challengeHex}:${nonce}`;\n const hash = await sha256Hex(input);\n\n if (hash <= targetHex) {\n postMessage({ nonce, hashHex: hash });\n return;\n }\n\n nonce++;\n }\n};\n\nasync function sha256Hex(input: string): Promise<string> {\n const buf = await crypto.subtle.digest(\n 'SHA-256',\n new TextEncoder().encode(input)\n );\n\n return [...new Uint8Array(buf)]\n .map(b => b.toString(16).padStart(2, '0'))\n .join('');\n}\n"],"mappings":";;;AAAA,KAAK,YAAY,OAAM,MAAK;AACxB,QAAM,EAAE,kBAAkB,cAAc,UAAU,IAAI,EAAE;AAExD,MAAI,QAAQ;AAEZ,SAAO,MAAM;AACT,UAAM,QAAQ,GAAG,gBAAgB,IAAI,YAAY,IAAI,KAAK;AAC1D,UAAM,OAAO,MAAM,UAAU,KAAK;AAElC,QAAI,QAAQ,WAAW;AACnB,kBAAY,EAAE,OAAO,SAAS,KAAK,CAAC;AACpC;AAAA,IACJ;AAEA;AAAA,EACJ;AACJ;AAEA,eAAe,UAAU,OAAgC;AACrD,QAAM,MAAM,MAAM,OAAO,OAAO;AAAA,IAC5B;AAAA,IACA,IAAI,YAAY,EAAE,OAAO,KAAK;AAAA,EAClC;AAEA,SAAO,CAAC,GAAG,IAAI,WAAW,GAAG,CAAC,EACzB,IAAI,OAAK,EAAE,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG,CAAC,EACxC,KAAK,EAAE;AAChB;","names":[]}
@@ -0,0 +1,2 @@
1
+
2
+ export { }
@@ -0,0 +1,2 @@
1
+
2
+ export { }
@@ -0,0 +1,22 @@
1
+ // src/pow.worker.ts
2
+ self.onmessage = async (e) => {
3
+ const { projectPublicKey, challengeHex, targetHex } = e.data;
4
+ let nonce = 0;
5
+ while (true) {
6
+ const input = `${projectPublicKey}:${challengeHex}:${nonce}`;
7
+ const hash = await sha256Hex(input);
8
+ if (hash <= targetHex) {
9
+ postMessage({ nonce, hashHex: hash });
10
+ return;
11
+ }
12
+ nonce++;
13
+ }
14
+ };
15
+ async function sha256Hex(input) {
16
+ const buf = await crypto.subtle.digest(
17
+ "SHA-256",
18
+ new TextEncoder().encode(input)
19
+ );
20
+ return [...new Uint8Array(buf)].map((b) => b.toString(16).padStart(2, "0")).join("");
21
+ }
22
+ //# sourceMappingURL=pow.worker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/pow.worker.ts"],"sourcesContent":["self.onmessage = async e => {\n const { projectPublicKey, challengeHex, targetHex } = e.data;\n\n let nonce = 0;\n\n while (true) {\n const input = `${projectPublicKey}:${challengeHex}:${nonce}`;\n const hash = await sha256Hex(input);\n\n if (hash <= targetHex) {\n postMessage({ nonce, hashHex: hash });\n return;\n }\n\n nonce++;\n }\n};\n\nasync function sha256Hex(input: string): Promise<string> {\n const buf = await crypto.subtle.digest(\n 'SHA-256',\n new TextEncoder().encode(input)\n );\n\n return [...new Uint8Array(buf)]\n .map(b => b.toString(16).padStart(2, '0'))\n .join('');\n}\n"],"mappings":";AAAA,KAAK,YAAY,OAAM,MAAK;AACxB,QAAM,EAAE,kBAAkB,cAAc,UAAU,IAAI,EAAE;AAExD,MAAI,QAAQ;AAEZ,SAAO,MAAM;AACT,UAAM,QAAQ,GAAG,gBAAgB,IAAI,YAAY,IAAI,KAAK;AAC1D,UAAM,OAAO,MAAM,UAAU,KAAK;AAElC,QAAI,QAAQ,WAAW;AACnB,kBAAY,EAAE,OAAO,SAAS,KAAK,CAAC;AACpC;AAAA,IACJ;AAEA;AAAA,EACJ;AACJ;AAEA,eAAe,UAAU,OAAgC;AACrD,QAAM,MAAM,MAAM,OAAO,OAAO;AAAA,IAC5B;AAAA,IACA,IAAI,YAAY,EAAE,OAAO,KAAK;AAAA,EAClC;AAEA,SAAO,CAAC,GAAG,IAAI,WAAW,GAAG,CAAC,EACzB,IAAI,OAAK,EAAE,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG,CAAC,EACxC,KAAK,EAAE;AAChB;","names":[]}
package/package.json ADDED
@@ -0,0 +1,29 @@
1
+ {
2
+ "name": "@liveauth-labs/sdk",
3
+ "version": "0.1.0",
4
+ "type": "module",
5
+ "main": "./dist/index.js",
6
+ "module": "./dist/index.mjs",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "import": "./dist/index.mjs",
11
+ "require": "./dist/index.js"
12
+ }
13
+ },
14
+ "files": [
15
+ "dist"
16
+ ],
17
+ "scripts": {
18
+ "build": "tsup",
19
+ "prepublishOnly": "npm run build"
20
+ },
21
+ "keywords": [
22
+ "captcha",
23
+ "proof-of-work",
24
+ "lightning",
25
+ "bitcoin",
26
+ "bot-protection",
27
+ "auth"
28
+ ]
29
+ }