credgate-sdk 1.0.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/README.md ADDED
@@ -0,0 +1,471 @@
1
+ # credgate-sdk
2
+
3
+ On-chain credit scoring for DeFi lending protocols, powered by CreditCoin ZK proofs.
4
+
5
+ Any lending protocol can use this SDK to:
6
+ - Analyze a wallet's on-chain credit score
7
+ - Determine max loan size and interest tier
8
+ - Poll CreditCoin ZK proof status
9
+ - Gate loan disbursement by credit tier
10
+
11
+ ---
12
+
13
+ ## Installation
14
+
15
+ ```bash
16
+ npm install credgate-sdk
17
+ ```
18
+
19
+ ---
20
+
21
+ ## Architecture
22
+
23
+ ```
24
+ Your Lending Protocol
25
+
26
+
27
+ credgate-sdk ──── POST /wallet/analyze/:address
28
+ │ ──── GET /wallet/result/:address
29
+ │ ──── GET /proof/status/address/:address
30
+ │ ──── GET /wallet/onchain/:address
31
+
32
+ CredGate Backend (NestJS)
33
+
34
+ ├── Aave history (Sepolia)
35
+ ├── Stablecoin treasury analysis
36
+ ├── CrossChain maturity
37
+ ├── DEX activity
38
+
39
+
40
+ CreditScoreRegistry (Sepolia)
41
+
42
+ ▼ ZK Proof via CreditCoin SDK
43
+ CreditScoreUSC (CreditCoin USC Testnet)
44
+
45
+
46
+ CreditAggregator (CreditCoin USC Testnet)
47
+
48
+
49
+ CreditVault.getCreditLine(user) → loan amount
50
+ ```
51
+
52
+ ---
53
+
54
+ ## Quick Start
55
+
56
+ ### Vanilla JS / Node.js
57
+
58
+ ```typescript
59
+ import { CredGateClient } from "credgate-sdk";
60
+
61
+ const client = new CredGateClient({
62
+ apiUrl: "https://your-credgate-backend.com",
63
+ apiKey: "optional_api_key",
64
+ });
65
+
66
+ const result = await client.analyzeWallet("0xabc...123");
67
+
68
+ console.log(result.score.creditScore); // 87
69
+ console.log(result.score.tier); // "PRIME"
70
+ console.log(result.score.loanProfile.maxLoanSizeUSD); // 25000
71
+ console.log(result.score.loanProfile.recommendedLTV); // 70
72
+ console.log(result.score.loanProfile.interestTier); // "PRIME"
73
+ console.log(result.proof?.status); // "waiting_attestation"
74
+ ```
75
+
76
+ ### React Hook
77
+
78
+ ```tsx
79
+ import { CredGateClient } from "credgate-sdk";
80
+ import { useCredGate } from "credgate-sdk/react";
81
+ import { useAccount } from "wagmi";
82
+
83
+ // Create once — outside your component, or in a context
84
+ const client = new CredGateClient({ apiUrl: "https://your-credgate-api.com" });
85
+
86
+ export function CreditWidget() {
87
+ const { address } = useAccount();
88
+ const {
89
+ score,
90
+ proof,
91
+ onchain,
92
+ loading,
93
+ analyzing,
94
+ error,
95
+ cooldownRemaining,
96
+ analyze,
97
+ } = useCredGate(client, address);
98
+
99
+ if (loading) return <p>Loading...</p>;
100
+
101
+ return (
102
+ <div>
103
+ <h2>Credit Score: {score?.creditScore ?? "—"}/100</h2>
104
+ <p>Tier: {score?.tier}</p>
105
+ <p>Max Loan: ${score?.loanProfile.maxLoanSizeUSD ?? 0}</p>
106
+ <p>Recommended LTV: {score?.loanProfile.recommendedLTV}%</p>
107
+ <p>Interest Tier: {score?.loanProfile.interestTier}</p>
108
+
109
+ {proof && <p>Proof: {proof.status}</p>}
110
+ {proof?.status === "waiting_attestation" && (
111
+ <p>{proof.blocksRemaining} blocks remaining (~{proof.estimatedWaitSeconds}s)</p>
112
+ )}
113
+ {proof?.status === "success" && <p>✓ Verified on CreditCoin</p>}
114
+
115
+ {onchain?.status === "UPDATED" && <p>✓ Score stored on-chain</p>}
116
+
117
+ <button
118
+ onClick={analyze}
119
+ disabled={analyzing || cooldownRemaining > 0}
120
+ >
121
+ {analyzing
122
+ ? "Analyzing..."
123
+ : cooldownRemaining > 0
124
+ ? `Cooldown: ${cooldownRemaining}s`
125
+ : score
126
+ ? "Re-analyze"
127
+ : "Analyze Wallet"}
128
+ </button>
129
+
130
+ {error && <p style={{ color: "red" }}>{error}</p>}
131
+ </div>
132
+ );
133
+ }
134
+ ```
135
+
136
+ ### Minimal hook (just eligibility)
137
+
138
+ ```tsx
139
+ import { useSimpleScore } from "credgate-sdk/react";
140
+
141
+ function LoanGate({ address }: { address: string }) {
142
+ const { eligible, tier, maxLoan, loading, analyze } = useSimpleScore(client, address);
143
+
144
+ if (loading) return <Spinner />;
145
+ if (!eligible) return <button onClick={analyze}>Check Eligibility</button>;
146
+
147
+ return <p>You can borrow up to ${maxLoan} at {tier} tier</p>;
148
+ }
149
+ ```
150
+
151
+ ---
152
+
153
+ ## Credit Tiers
154
+
155
+ | Tier | Score | LTV | Interest |
156
+ |---|---|---|---|
157
+ | `ELITE` | 95–100 | 70% | Lowest |
158
+ | `PRIME` | 80–94 | 70% | Low |
159
+ | `PREFERRED` | 65–79 | 60% | Standard |
160
+ | `STANDARD` | 50–64 | 50% | Higher |
161
+ | `HIGH_RISK` | 30–49 | 35% | High |
162
+ | `REJECT` | < 30 | 0% | N/A |
163
+
164
+ > **Note:** Loan size is also capped by capital base (stablecoin inflow × retention ratio). A high score does not guarantee a large loan — capital history matters.
165
+
166
+ ---
167
+
168
+ ## Proof Lifecycle
169
+
170
+ ```
171
+ not_found
172
+
173
+
174
+ queued
175
+
176
+
177
+ checking_contract ← verifies aggregator + authorized source set
178
+
179
+
180
+ fetching_tx ← fetches Sepolia tx
181
+
182
+
183
+ waiting_attestation ← polls 0xFD3 precompile on CreditCoin USC
184
+ │ (blocksRemaining, estimatedWaitSeconds available)
185
+
186
+ generating_proof ← calls proof-gen API
187
+
188
+
189
+ submitting ← calls CreditScoreUSC.submitScoreFromQuery()
190
+
191
+ ├── success ← txHash available (CreditCoin USC tx)
192
+ └── failed ← error message available
193
+ ```
194
+
195
+ ---
196
+
197
+ ## API Reference
198
+
199
+ ### `new CredGateClient(config)`
200
+
201
+ ```typescript
202
+ const client = new CredGateClient({
203
+ apiUrl: "https://api.credgate.xyz", // required
204
+ apiKey: "sk_...", // optional
205
+ pollInterval: 3000, // ms between polls (default: 3000)
206
+ timeout: 120_000, // analysis timeout ms (default: 120000)
207
+ });
208
+ ```
209
+
210
+ ---
211
+
212
+ ### `client.analyzeWallet(address, options?)`
213
+
214
+ Triggers analysis and polls until score is ready. Returns full `AnalysisResult`.
215
+
216
+ ```typescript
217
+ const result = await client.analyzeWallet("0x...", {
218
+ waitForProof: true, // also wait for CreditCoin ZK proof
219
+ timeout: 180_000, // override timeout
220
+ pollInterval: 5000, // override poll interval
221
+ });
222
+ ```
223
+
224
+ **Response shape:**
225
+ ```typescript
226
+ {
227
+ score: {
228
+ address: "0x...",
229
+ creditScore: 87, // 0–100
230
+ tier: "PRIME",
231
+ riskScore: 42,
232
+ riskLevel: "MEDIUM",
233
+ loanProfile: {
234
+ recommendedLTV: 70,
235
+ interestTier: "PRIME",
236
+ maxLoanSizeUSD: 25000,
237
+ },
238
+ scoreBreakdown: {
239
+ lending: 28.5,
240
+ stable: 22.0,
241
+ crossChain: 12.0,
242
+ dex: 8.0,
243
+ ageBonus: 5.5,
244
+ riskPenalty: 8.0,
245
+ },
246
+ analyzedAt: 1709123456789,
247
+ },
248
+ onchain: {
249
+ status: "UPDATED", // "NOT_SUBMITTED" | "UPDATED" | "COOLDOWN_ACTIVE" | "FAILED"
250
+ txHash: "0x...",
251
+ reportHash: "0x...",
252
+ remainingSeconds: 0,
253
+ },
254
+ proof: {
255
+ status: "waiting_attestation",
256
+ jobId: "job_0xabc123_1709...",
257
+ currentAttestedBlock: 7450000,
258
+ targetBlock: 7450123,
259
+ blocksRemaining: 123,
260
+ estimatedWaitSeconds: 1476,
261
+ }
262
+ }
263
+ ```
264
+
265
+ ---
266
+
267
+ ### `client.getScore(address)`
268
+
269
+ Returns cached `ScoreResult | null`. Does NOT trigger new analysis.
270
+
271
+ ```typescript
272
+ const score = await client.getScore("0x...");
273
+ if (!score) {
274
+ // Wallet never analyzed — trigger analysis
275
+ await client.analyzeWallet("0x...");
276
+ }
277
+ ```
278
+
279
+ ---
280
+
281
+ ### `client.getProofStatus(address)`
282
+
283
+ Returns current ZK proof status for a wallet.
284
+
285
+ ```typescript
286
+ const proof = await client.getProofStatus("0x...");
287
+ // { status: "waiting_attestation", blocksRemaining: 42, estimatedWaitSeconds: 504 }
288
+ ```
289
+
290
+ ---
291
+
292
+ ### `client.waitForProof(address, options?)`
293
+
294
+ Polls until proof reaches `success` or throws on `failed`.
295
+
296
+ ```typescript
297
+ const proof = await client.waitForProof("0x...", {
298
+ timeout: 1_800_000, // 30 min (matches backend max)
299
+ });
300
+ console.log(proof.txHash); // CreditCoin USC transaction hash
301
+ ```
302
+
303
+ ---
304
+
305
+ ### `client.getOnChainStatus(address)`
306
+
307
+ Returns on-chain credit registry status from Sepolia `CreditScoreRegistry`.
308
+
309
+ ```typescript
310
+ const status = await client.getOnChainStatus("0x...");
311
+ // { status: "UPDATED", txHash: "0x...", reportHash: "0x...", remainingSeconds: 0 }
312
+ ```
313
+
314
+ ---
315
+
316
+ ### `client.isEligible(address)`
317
+
318
+ Quick boolean check. Returns `false` if tier is REJECT or maxLoanSizeUSD is 0.
319
+
320
+ ```typescript
321
+ // Server-side loan gating
322
+ if (!(await client.isEligible(userAddress))) {
323
+ return res.status(403).json({ error: "Insufficient credit score" });
324
+ }
325
+ ```
326
+
327
+ ---
328
+
329
+ ### `client.getMaxLoan(address)`
330
+
331
+ Returns max loan in USD. Returns 0 if wallet is ineligible or unanalyzed.
332
+
333
+ ```typescript
334
+ const max = await client.getMaxLoan(userAddress);
335
+ if (requestedAmount > max) {
336
+ throw new Error(`Requested ${requestedAmount} exceeds credit line of ${max}`);
337
+ }
338
+ ```
339
+
340
+ ---
341
+
342
+ ## Error Handling
343
+
344
+ ```typescript
345
+ import { CredGateClient, CredGateError, ErrorCode } from "credgate-sdk";
346
+
347
+ try {
348
+ await client.analyzeWallet(address);
349
+ } catch (err) {
350
+ if (err instanceof CredGateError) {
351
+ switch (err.code) {
352
+ case ErrorCode.COOLDOWN_ACTIVE:
353
+ // Wallet was analyzed recently — wait for cooldown
354
+ const seconds = err.meta?.remainingSeconds as number;
355
+ console.log(`Try again in ${Math.ceil(seconds / 3600)}h`);
356
+ break;
357
+
358
+ case ErrorCode.ANALYSIS_TIMEOUT:
359
+ // Backend took too long — retry
360
+ console.log("Timed out, retrying...");
361
+ break;
362
+
363
+ case ErrorCode.PROOF_FAILED:
364
+ // CreditCoin proof submission failed
365
+ console.log("Proof failed:", err.meta?.txHash);
366
+ break;
367
+
368
+ case ErrorCode.WALLET_NOT_FOUND:
369
+ console.log("Wallet never analyzed");
370
+ break;
371
+
372
+ case ErrorCode.UNAUTHORIZED:
373
+ console.log("Check your API key");
374
+ break;
375
+
376
+ case ErrorCode.NETWORK_ERROR:
377
+ console.log("Backend unreachable:", err.message);
378
+ break;
379
+ }
380
+ }
381
+ }
382
+ ```
383
+
384
+ ---
385
+
386
+ ## React Hook Reference
387
+
388
+ ### `useCredGate(client, address, options?)`
389
+
390
+ ```typescript
391
+ const {
392
+ score, // ScoreResult | null
393
+ proof, // ProofStatus | null
394
+ onchain, // OnChainStatus | null
395
+ loading, // true while fetching cached data on mount
396
+ analyzing, // true while analysis job is running
397
+ error, // string | null
398
+ cooldownRemaining, // number (seconds, counts down)
399
+ analyze, // () => Promise<void> — trigger new analysis
400
+ refetch, // () => Promise<void> — reload cached data
401
+ } = useCredGate(client, address, {
402
+ autoAnalyze: false, // trigger analysis on mount if no cached score
403
+ proofPollInterval: 5000, // poll proof every 5s (0 = disabled)
404
+ });
405
+ ```
406
+
407
+ ### `useSimpleScore(client, address)`
408
+
409
+ ```typescript
410
+ const {
411
+ creditScore, // number | null
412
+ tier, // CreditTier | null
413
+ maxLoan, // number (USD)
414
+ recommendedLTV, // number (0–70)
415
+ eligible, // boolean
416
+ loading,
417
+ error,
418
+ cooldownRemaining,
419
+ analyze,
420
+ } = useSimpleScore(client, address);
421
+ ```
422
+
423
+ ---
424
+
425
+ ## TypeScript Types
426
+
427
+ ```typescript
428
+ import type {
429
+ AnalysisResult,
430
+ ScoreResult,
431
+ LoanProfile,
432
+ ScoreBreakdown,
433
+ ProofStatus,
434
+ ProofStatusValue,
435
+ OnChainStatus,
436
+ OnChainStatusValue,
437
+ CreditTier,
438
+ RiskLevel,
439
+ } from "credgate-sdk";
440
+ ```
441
+
442
+ ---
443
+
444
+ ## Backend Endpoints Used
445
+
446
+ | Method | Endpoint | Description |
447
+ |---|---|---|
448
+ | `POST` | `/wallet/analyze/:address` | Trigger wallet analysis |
449
+ | `GET` | `/wallet/result/:address` | Poll for score result |
450
+ | `GET` | `/wallet/onchain/:address` | On-chain registry status |
451
+ | `GET` | `/proof/status/address/:address` | ZK proof status by address |
452
+ | `GET` | `/proof/status/:jobId` | ZK proof status by job ID |
453
+
454
+ ---
455
+
456
+ ## Score Breakdown Explained
457
+
458
+ | Component | Max Points | Source |
459
+ |---|---|---|
460
+ | Lending | 30 | Aave borrow/repay history, liquidations |
461
+ | Stable | 35 | Stablecoin treasury inflow/retention/age |
462
+ | CrossChain | 20 | Multi-chain activity maturity |
463
+ | DEX | 15 | DEX swap history and volume |
464
+ | Age Bonus | 10 | Wallet age (log scale) |
465
+ | Risk Penalty | −30 | Combined risk score deduction |
466
+
467
+ ---
468
+
469
+ ## License
470
+
471
+ MIT
@@ -0,0 +1,82 @@
1
+ import { CredGateConfig, AnalysisResult, AnalyzeOptions, ScoreResult, ProofStatus, OnChainStatus } from "./types";
2
+ export declare class CredGateClient {
3
+ private readonly apiUrl;
4
+ private readonly apiKey?;
5
+ private readonly defaultPollInterval;
6
+ private readonly defaultTimeout;
7
+ constructor(config: CredGateConfig);
8
+ private _fetch;
9
+ private _normalizeResult;
10
+ /**
11
+ * Trigger a full wallet analysis and poll until score is ready.
12
+ *
13
+ * Flow: POST /wallet/analyze/:address
14
+ * → poll GET /wallet/result/:address until status === "DONE"
15
+ * → GET /proof/status/address/:address
16
+ *
17
+ * @example
18
+ * const result = await client.analyzeWallet("0xabc...");
19
+ * console.log(result.score.creditScore); // 87
20
+ * console.log(result.score.tier); // "PRIME"
21
+ * console.log(result.score.loanProfile.maxLoanSizeUSD); // 25000
22
+ */
23
+ analyzeWallet(address: string, options?: AnalyzeOptions): Promise<AnalysisResult>;
24
+ /**
25
+ * Get cached score without triggering new analysis.
26
+ * Returns null if wallet was never analyzed.
27
+ *
28
+ * @example
29
+ * const score = await client.getScore("0xabc...");
30
+ * if (!score) await client.analyzeWallet("0xabc...");
31
+ */
32
+ getScore(address: string): Promise<ScoreResult | null>;
33
+ /**
34
+ * Get current CreditCoin ZK proof status.
35
+ *
36
+ * Proof lifecycle:
37
+ * not_found → queued → checking_contract → fetching_tx
38
+ * → waiting_attestation → generating_proof → submitting
39
+ * → success | failed
40
+ *
41
+ * @example
42
+ * const proof = await client.getProofStatus("0xabc...");
43
+ * console.log(proof.status); // "waiting_attestation"
44
+ * console.log(proof.blocksRemaining); // 42
45
+ */
46
+ getProofStatus(address: string): Promise<ProofStatus>;
47
+ /**
48
+ * Poll proof status until success or failure.
49
+ * Throws CredGateError with code PROOF_FAILED on failure.
50
+ *
51
+ * @example
52
+ * const proof = await client.waitForProof("0xabc...");
53
+ * console.log(proof.txHash); // CreditCoin tx hash
54
+ */
55
+ waitForProof(address: string, options?: {
56
+ timeout?: number;
57
+ pollInterval?: number;
58
+ }): Promise<ProofStatus>;
59
+ /**
60
+ * Get on-chain credit registry status from Sepolia.
61
+ */
62
+ getOnChainStatus(address: string): Promise<OnChainStatus>;
63
+ /**
64
+ * Quick eligibility check — returns false if tier is REJECT or maxLoanSizeUSD is 0.
65
+ *
66
+ * @example
67
+ * if (!(await client.isEligible(userAddress))) {
68
+ * return res.status(403).json({ error: "Not eligible for loan" });
69
+ * }
70
+ */
71
+ isEligible(address: string): Promise<boolean>;
72
+ /**
73
+ * Get max loan amount in USD for a wallet.
74
+ * Returns 0 if wallet hasn't been analyzed or is ineligible.
75
+ *
76
+ * @example
77
+ * const max = await client.getMaxLoan(userAddress);
78
+ * if (requestedAmount > max) throw new Error("Exceeds credit line");
79
+ */
80
+ getMaxLoan(address: string): Promise<number>;
81
+ }
82
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,cAAc,EAGd,cAAc,EACd,cAAc,EACd,WAAW,EACX,WAAW,EACX,aAAa,EAEhB,MAAM,SAAS,CAAC;AAcjB,qBAAa,cAAc;IACvB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAS;IAC7C,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;gBAE5B,MAAM,EAAE,cAAc;YAQpB,MAAM;IAmCpB,OAAO,CAAC,gBAAgB;IAmDxB;;;;;;;;;;;;OAYG;IACG,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,cAAc,CAAC;IAyD3F;;;;;;;OAOG;IACG,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;IAW5D;;;;;;;;;;;;OAYG;IACG,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IAI3D;;;;;;;OAOG;IACG,YAAY,CACd,OAAO,EAAE,MAAM,EACf,OAAO,GAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,CAAA;KAAO,GAC1D,OAAO,CAAC,WAAW,CAAC;IA2BvB;;OAEG;IACG,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;IAU/D;;;;;;;OAOG;IACG,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAMnD;;;;;;;OAOG;IACG,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAIrD"}
package/dist/client.js ADDED
@@ -0,0 +1,255 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CredGateClient = void 0;
4
+ const types_1 = require("./types");
5
+ // ── helpers ───────────────────────────────────────────────────────────────────
6
+ const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
7
+ function deriveTier(score) {
8
+ if (score >= 95)
9
+ return "ELITE";
10
+ if (score >= 80)
11
+ return "PRIME";
12
+ if (score >= 65)
13
+ return "PREFERRED";
14
+ if (score >= 50)
15
+ return "STANDARD";
16
+ return "REJECT";
17
+ }
18
+ // ── CredGateClient ────────────────────────────────────────────────────────────
19
+ class CredGateClient {
20
+ constructor(config) {
21
+ this.apiUrl = config.apiUrl.replace(/\/$/, "");
22
+ this.apiKey = config.apiKey;
23
+ this.defaultPollInterval = config.pollInterval ?? 3000;
24
+ this.defaultTimeout = config.timeout ?? 120000;
25
+ }
26
+ // ── Internal fetch ────────────────────────────────────────────────────────
27
+ async _fetch(path, options) {
28
+ const headers = {
29
+ "Content-Type": "application/json",
30
+ ...(this.apiKey ? { "x-api-key": this.apiKey } : {}),
31
+ };
32
+ let res;
33
+ try {
34
+ res = await fetch(`${this.apiUrl}${path}`, {
35
+ ...options,
36
+ headers: { ...headers, ...(options?.headers ?? {}) },
37
+ });
38
+ }
39
+ catch (err) {
40
+ throw new types_1.CredGateError(types_1.ErrorCode.NETWORK_ERROR, `Network request failed: ${err.message}`);
41
+ }
42
+ if (res.status === 401 || res.status === 403) {
43
+ throw new types_1.CredGateError(types_1.ErrorCode.UNAUTHORIZED, "Invalid or missing API key");
44
+ }
45
+ if (res.status === 404) {
46
+ throw new types_1.CredGateError(types_1.ErrorCode.WALLET_NOT_FOUND, "Wallet not found");
47
+ }
48
+ if (!res.ok) {
49
+ const body = await res.text().catch(() => "");
50
+ throw new types_1.CredGateError(types_1.ErrorCode.UNKNOWN, `Request failed (${res.status}): ${body}`);
51
+ }
52
+ return res.json();
53
+ }
54
+ // ── Normalize /wallet/result/:address response ────────────────────────────
55
+ // Backend returns: { status: "DONE", result: { address, intelligence, onchain, meta, ... } }
56
+ _normalizeResult(raw) {
57
+ // result is nested under `result` key when status === "DONE"
58
+ const result = (raw.result ?? raw);
59
+ const intel = (result.intelligence ?? {});
60
+ const loanProfile = (intel.loanProfile ?? {});
61
+ const breakdown = (intel.scoreBreakdown ?? {});
62
+ const risk = (intel.risk ?? {});
63
+ const meta = (result.meta ?? {});
64
+ const onchainRaw = (result.onchain ?? {});
65
+ const creditScore = intel.creditScore ?? 0;
66
+ const score = {
67
+ address: result.address,
68
+ creditScore,
69
+ tier: deriveTier(creditScore),
70
+ riskScore: risk.riskScore ?? 0,
71
+ riskLevel: risk.riskLevel ?? "LOW",
72
+ loanProfile: {
73
+ recommendedLTV: loanProfile.recommendedLTV ?? 0,
74
+ interestTier: loanProfile.interestTier ?? "REJECT",
75
+ maxLoanSizeUSD: loanProfile.maxLoanSizeUSD ?? 0,
76
+ },
77
+ scoreBreakdown: {
78
+ lending: breakdown.lending ?? 0,
79
+ stable: breakdown.stable ?? 0,
80
+ crossChain: breakdown.crossChain ?? 0,
81
+ dex: breakdown.dex ?? 0,
82
+ ageBonus: breakdown.ageBonus ?? 0,
83
+ riskPenalty: breakdown.riskPenalty ?? 0,
84
+ },
85
+ analyzedAt: meta.analyzedAt ?? Date.now(),
86
+ };
87
+ const onchain = {
88
+ status: onchainRaw.status ?? "NOT_SUBMITTED",
89
+ txHash: onchainRaw.txHash,
90
+ reportHash: onchainRaw.reportHash,
91
+ remainingSeconds: onchainRaw.remainingSeconds,
92
+ };
93
+ return { score, onchain };
94
+ }
95
+ // ─────────────────────────────────────────────────────────────────────────
96
+ // PUBLIC API
97
+ // ─────────────────────────────────────────────────────────────────────────
98
+ /**
99
+ * Trigger a full wallet analysis and poll until score is ready.
100
+ *
101
+ * Flow: POST /wallet/analyze/:address
102
+ * → poll GET /wallet/result/:address until status === "DONE"
103
+ * → GET /proof/status/address/:address
104
+ *
105
+ * @example
106
+ * const result = await client.analyzeWallet("0xabc...");
107
+ * console.log(result.score.creditScore); // 87
108
+ * console.log(result.score.tier); // "PRIME"
109
+ * console.log(result.score.loanProfile.maxLoanSizeUSD); // 25000
110
+ */
111
+ async analyzeWallet(address, options = {}) {
112
+ const pollInterval = options.pollInterval ?? this.defaultPollInterval;
113
+ const timeout = options.timeout ?? this.defaultTimeout;
114
+ const deadline = Date.now() + timeout;
115
+ // 1. Trigger analysis
116
+ await this._fetch(`/wallet/analyze/${address}`, { method: "POST" });
117
+ // 2. Poll for DONE
118
+ let raw = null;
119
+ while (Date.now() < deadline) {
120
+ try {
121
+ const res = await this._fetch(`/wallet/result/${address}`);
122
+ // Backend returns { status: "DONE" | "PROCESSING" | "FAILED" | "NOT_FOUND", result: ... }
123
+ if (res.status === "DONE" && res.result) {
124
+ raw = res;
125
+ break;
126
+ }
127
+ if (res.status === "FAILED") {
128
+ throw new types_1.CredGateError(types_1.ErrorCode.UNKNOWN, "Wallet analysis job failed on server");
129
+ }
130
+ }
131
+ catch (err) {
132
+ if (err instanceof types_1.CredGateError && err.code !== types_1.ErrorCode.WALLET_NOT_FOUND)
133
+ throw err;
134
+ }
135
+ await sleep(pollInterval);
136
+ }
137
+ if (!raw) {
138
+ throw new types_1.CredGateError(types_1.ErrorCode.ANALYSIS_TIMEOUT, `Analysis timed out after ${timeout / 1000}s for ${address}`);
139
+ }
140
+ const { score, onchain } = this._normalizeResult(raw);
141
+ // 3. Handle cooldown
142
+ if (onchain.status === "COOLDOWN_ACTIVE") {
143
+ throw new types_1.CredGateError(types_1.ErrorCode.COOLDOWN_ACTIVE, `Wallet is in cooldown. Retry in ${onchain.remainingSeconds ?? "?"}s`, { remainingSeconds: onchain.remainingSeconds });
144
+ }
145
+ // 4. Optionally wait for ZK proof
146
+ let proof;
147
+ if (options.waitForProof) {
148
+ proof = await this.waitForProof(address, { timeout: Math.max(0, deadline - Date.now()) });
149
+ }
150
+ else {
151
+ proof = await this.getProofStatus(address).catch(() => undefined);
152
+ }
153
+ return { score, onchain, proof };
154
+ }
155
+ /**
156
+ * Get cached score without triggering new analysis.
157
+ * Returns null if wallet was never analyzed.
158
+ *
159
+ * @example
160
+ * const score = await client.getScore("0xabc...");
161
+ * if (!score) await client.analyzeWallet("0xabc...");
162
+ */
163
+ async getScore(address) {
164
+ try {
165
+ const res = await this._fetch(`/wallet/result/${address}`);
166
+ if (!res || res.status !== "DONE" || !res.result)
167
+ return null;
168
+ return this._normalizeResult(res).score;
169
+ }
170
+ catch (err) {
171
+ if (err instanceof types_1.CredGateError && err.code === types_1.ErrorCode.WALLET_NOT_FOUND)
172
+ return null;
173
+ throw err;
174
+ }
175
+ }
176
+ /**
177
+ * Get current CreditCoin ZK proof status.
178
+ *
179
+ * Proof lifecycle:
180
+ * not_found → queued → checking_contract → fetching_tx
181
+ * → waiting_attestation → generating_proof → submitting
182
+ * → success | failed
183
+ *
184
+ * @example
185
+ * const proof = await client.getProofStatus("0xabc...");
186
+ * console.log(proof.status); // "waiting_attestation"
187
+ * console.log(proof.blocksRemaining); // 42
188
+ */
189
+ async getProofStatus(address) {
190
+ return this._fetch(`/proof/status/address/${address}`);
191
+ }
192
+ /**
193
+ * Poll proof status until success or failure.
194
+ * Throws CredGateError with code PROOF_FAILED on failure.
195
+ *
196
+ * @example
197
+ * const proof = await client.waitForProof("0xabc...");
198
+ * console.log(proof.txHash); // CreditCoin tx hash
199
+ */
200
+ async waitForProof(address, options = {}) {
201
+ const pollInterval = options.pollInterval ?? this.defaultPollInterval;
202
+ const timeout = options.timeout ?? this.defaultTimeout;
203
+ const deadline = Date.now() + timeout;
204
+ while (Date.now() < deadline) {
205
+ const proof = await this.getProofStatus(address);
206
+ if (proof.status === "success")
207
+ return proof;
208
+ if (proof.status === "failed") {
209
+ throw new types_1.CredGateError(types_1.ErrorCode.PROOF_FAILED, `CreditCoin proof failed: ${proof.error ?? "unknown"}`, { txHash: proof.txHash });
210
+ }
211
+ await sleep(pollInterval);
212
+ }
213
+ throw new types_1.CredGateError(types_1.ErrorCode.ANALYSIS_TIMEOUT, `Proof timed out after ${timeout / 1000}s`);
214
+ }
215
+ /**
216
+ * Get on-chain credit registry status from Sepolia.
217
+ */
218
+ async getOnChainStatus(address) {
219
+ const raw = await this._fetch(`/wallet/onchain/${address}`);
220
+ return {
221
+ status: raw.status ?? "NOT_SUBMITTED",
222
+ txHash: raw.txHash,
223
+ reportHash: raw.reportHash,
224
+ remainingSeconds: raw.remainingSeconds,
225
+ };
226
+ }
227
+ /**
228
+ * Quick eligibility check — returns false if tier is REJECT or maxLoanSizeUSD is 0.
229
+ *
230
+ * @example
231
+ * if (!(await client.isEligible(userAddress))) {
232
+ * return res.status(403).json({ error: "Not eligible for loan" });
233
+ * }
234
+ */
235
+ async isEligible(address) {
236
+ const score = await this.getScore(address);
237
+ if (!score)
238
+ return false;
239
+ return score.tier !== "REJECT" && score.loanProfile.maxLoanSizeUSD > 0;
240
+ }
241
+ /**
242
+ * Get max loan amount in USD for a wallet.
243
+ * Returns 0 if wallet hasn't been analyzed or is ineligible.
244
+ *
245
+ * @example
246
+ * const max = await client.getMaxLoan(userAddress);
247
+ * if (requestedAmount > max) throw new Error("Exceeds credit line");
248
+ */
249
+ async getMaxLoan(address) {
250
+ const score = await this.getScore(address);
251
+ return score?.loanProfile.maxLoanSizeUSD ?? 0;
252
+ }
253
+ }
254
+ exports.CredGateClient = CredGateClient;
255
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export { CredGateClient } from "./client";
2
+ export type { CredGateConfig, AnalyzeOptions, AnalysisResult, ScoreResult, ScoreBreakdown, LoanProfile, ProofStatus, ProofStatusValue, OnChainStatus, OnChainStatusValue, CreditTier, RiskLevel, StableLevel, } from "./types";
3
+ export { CredGateError, ErrorCode } from "./types";
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAG1C,YAAY,EACR,cAAc,EACd,cAAc,EACd,cAAc,EACd,WAAW,EACX,cAAc,EACd,WAAW,EACX,WAAW,EACX,gBAAgB,EAChB,aAAa,EACb,kBAAkB,EAClB,UAAU,EACV,SAAS,EACT,WAAW,GACd,MAAM,SAAS,CAAC;AAGjB,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ErrorCode = exports.CredGateError = exports.CredGateClient = void 0;
4
+ // Core
5
+ var client_1 = require("./client");
6
+ Object.defineProperty(exports, "CredGateClient", { enumerable: true, get: function () { return client_1.CredGateClient; } });
7
+ // Errors
8
+ var types_1 = require("./types");
9
+ Object.defineProperty(exports, "CredGateError", { enumerable: true, get: function () { return types_1.CredGateError; } });
10
+ Object.defineProperty(exports, "ErrorCode", { enumerable: true, get: function () { return types_1.ErrorCode; } });
11
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,OAAO;AACP,mCAA0C;AAAjC,wGAAA,cAAc,OAAA;AAmBvB,SAAS;AACT,iCAAmD;AAA1C,sGAAA,aAAa,OAAA;AAAE,kGAAA,SAAS,OAAA"}
@@ -0,0 +1,71 @@
1
+ import { CredGateClient } from "../client";
2
+ import { ScoreResult, ProofStatus, OnChainStatus } from "../types";
3
+ export interface UseCredGateOptions {
4
+ /** Auto-trigger analysis on mount if no score cached (default: false) */
5
+ autoAnalyze?: boolean;
6
+ /** Proof poll interval in ms. 0 = disabled (default: 5000) */
7
+ proofPollInterval?: number;
8
+ }
9
+ export interface UseCredGateReturn {
10
+ /** Latest credit score result */
11
+ score: ScoreResult | null;
12
+ /** Latest CreditCoin ZK proof status */
13
+ proof: ProofStatus | null;
14
+ /** On-chain credit registry status */
15
+ onchain: OnChainStatus | null;
16
+ /** True while loading cached score on mount */
17
+ loading: boolean;
18
+ /** True while analysis POST + polling is in progress */
19
+ analyzing: boolean;
20
+ /** Human-readable error string */
21
+ error: string | null;
22
+ /** Seconds remaining in cooldown (0 = no cooldown) */
23
+ cooldownRemaining: number;
24
+ /** Trigger a new wallet analysis */
25
+ analyze: () => Promise<void>;
26
+ /** Re-fetch cached data without triggering new analysis */
27
+ refetch: () => Promise<void>;
28
+ }
29
+ /**
30
+ * Full React hook for CredGate credit scoring.
31
+ *
32
+ * @example
33
+ * const client = new CredGateClient({ apiUrl: "https://api.credgate.xyz" });
34
+ *
35
+ * function CreditWidget() {
36
+ * const { address } = useAccount();
37
+ * const { score, proof, analyzing, cooldownRemaining, analyze } = useCredGate(client, address);
38
+ *
39
+ * return (
40
+ * <div>
41
+ * <p>Score: {score?.creditScore ?? "—"}/100 Tier: {score?.tier}</p>
42
+ * <p>Max loan: ${score?.loanProfile.maxLoanSizeUSD ?? 0}</p>
43
+ * <p>Proof: {proof?.status}</p>
44
+ * <button onClick={analyze} disabled={analyzing || cooldownRemaining > 0}>
45
+ * {cooldownRemaining > 0 ? `Cooldown: ${cooldownRemaining}s` : "Analyze"}
46
+ * </button>
47
+ * </div>
48
+ * );
49
+ * }
50
+ */
51
+ export declare function useCredGate(client: CredGateClient, address: string | undefined, options?: UseCredGateOptions): UseCredGateReturn;
52
+ /**
53
+ * Minimal hook — just score, tier, eligibility.
54
+ * Perfect for simple loan-gating use cases.
55
+ *
56
+ * @example
57
+ * const { eligible, maxLoan, tier, analyze } = useSimpleScore(client, address);
58
+ * if (!eligible) return <div>Not eligible to borrow</div>;
59
+ */
60
+ export declare function useSimpleScore(client: CredGateClient, address: string | undefined): {
61
+ creditScore: number | null;
62
+ tier: import("../types").CreditTier | null;
63
+ maxLoan: number;
64
+ recommendedLTV: number;
65
+ eligible: boolean;
66
+ loading: boolean;
67
+ error: string | null;
68
+ cooldownRemaining: number;
69
+ analyze: () => Promise<void>;
70
+ };
71
+ //# sourceMappingURL=hooks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../src/react/hooks.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EACH,WAAW,EACX,WAAW,EACX,aAAa,EAGhB,MAAM,UAAU,CAAC;AAGlB,MAAM,WAAW,kBAAkB;IAC/B,yEAAyE;IACzE,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,8DAA8D;IAC9D,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED,MAAM,WAAW,iBAAiB;IAC9B,iCAAiC;IACjC,KAAK,EAAE,WAAW,GAAG,IAAI,CAAC;IAC1B,wCAAwC;IACxC,KAAK,EAAE,WAAW,GAAG,IAAI,CAAC;IAC1B,sCAAsC;IACtC,OAAO,EAAE,aAAa,GAAG,IAAI,CAAC;IAC9B,+CAA+C;IAC/C,OAAO,EAAE,OAAO,CAAC;IACjB,wDAAwD;IACxD,SAAS,EAAE,OAAO,CAAC;IACnB,kCAAkC;IAClC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,sDAAsD;IACtD,iBAAiB,EAAE,MAAM,CAAC;IAC1B,oCAAoC;IACpC,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7B,2DAA2D;IAC3D,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAChC;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,WAAW,CACvB,MAAM,EAAE,cAAc,EACtB,OAAO,EAAE,MAAM,GAAG,SAAS,EAC3B,OAAO,GAAE,kBAAuB,GACjC,iBAAiB,CAuInB;AAGD;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,GAAG,SAAS;;;;;;;;;mBAjL/D,OAAO,CAAC,IAAI,CAAC;EA8L/B"}
@@ -0,0 +1,183 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.useCredGate = useCredGate;
4
+ exports.useSimpleScore = useSimpleScore;
5
+ const react_1 = require("react");
6
+ const types_1 = require("../types");
7
+ /**
8
+ * Full React hook for CredGate credit scoring.
9
+ *
10
+ * @example
11
+ * const client = new CredGateClient({ apiUrl: "https://api.credgate.xyz" });
12
+ *
13
+ * function CreditWidget() {
14
+ * const { address } = useAccount();
15
+ * const { score, proof, analyzing, cooldownRemaining, analyze } = useCredGate(client, address);
16
+ *
17
+ * return (
18
+ * <div>
19
+ * <p>Score: {score?.creditScore ?? "—"}/100 Tier: {score?.tier}</p>
20
+ * <p>Max loan: ${score?.loanProfile.maxLoanSizeUSD ?? 0}</p>
21
+ * <p>Proof: {proof?.status}</p>
22
+ * <button onClick={analyze} disabled={analyzing || cooldownRemaining > 0}>
23
+ * {cooldownRemaining > 0 ? `Cooldown: ${cooldownRemaining}s` : "Analyze"}
24
+ * </button>
25
+ * </div>
26
+ * );
27
+ * }
28
+ */
29
+ function useCredGate(client, address, options = {}) {
30
+ const { autoAnalyze = false, proofPollInterval = 5000 } = options;
31
+ const [score, setScore] = (0, react_1.useState)(null);
32
+ const [proof, setProof] = (0, react_1.useState)(null);
33
+ const [onchain, setOnchain] = (0, react_1.useState)(null);
34
+ const [loading, setLoading] = (0, react_1.useState)(false);
35
+ const [analyzing, setAnalyzing] = (0, react_1.useState)(false);
36
+ const [error, setError] = (0, react_1.useState)(null);
37
+ const [cooldownRemaining, setCooldownRemaining] = (0, react_1.useState)(0);
38
+ const proofPollRef = (0, react_1.useRef)(null);
39
+ const cooldownRef = (0, react_1.useRef)(null);
40
+ const stopProofPolling = (0, react_1.useCallback)(() => {
41
+ if (proofPollRef.current) {
42
+ clearInterval(proofPollRef.current);
43
+ proofPollRef.current = null;
44
+ }
45
+ }, []);
46
+ const startProofPolling = (0, react_1.useCallback)((addr) => {
47
+ if (!proofPollInterval || proofPollRef.current)
48
+ return;
49
+ proofPollRef.current = setInterval(async () => {
50
+ try {
51
+ const p = await client.getProofStatus(addr);
52
+ setProof(p);
53
+ if (p.status === "success" || p.status === "failed" || p.status === "not_found") {
54
+ stopProofPolling();
55
+ }
56
+ }
57
+ catch {
58
+ }
59
+ }, proofPollInterval);
60
+ }, [client, proofPollInterval, stopProofPolling]);
61
+ const startCooldown = (0, react_1.useCallback)((seconds) => {
62
+ setCooldownRemaining(seconds);
63
+ if (cooldownRef.current)
64
+ clearInterval(cooldownRef.current);
65
+ cooldownRef.current = setInterval(() => {
66
+ setCooldownRemaining((prev) => {
67
+ if (prev <= 1) {
68
+ clearInterval(cooldownRef.current);
69
+ return 0;
70
+ }
71
+ return prev - 1;
72
+ });
73
+ }, 1000);
74
+ }, []);
75
+ const refetch = (0, react_1.useCallback)(async () => {
76
+ if (!address)
77
+ return;
78
+ setLoading(true);
79
+ setError(null);
80
+ try {
81
+ const [scoreRes, proofRes, onchainRes] = await Promise.allSettled([
82
+ client.getScore(address),
83
+ client.getProofStatus(address),
84
+ client.getOnChainStatus(address),
85
+ ]);
86
+ if (scoreRes.status === "fulfilled")
87
+ setScore(scoreRes.value);
88
+ if (proofRes.status === "fulfilled")
89
+ setProof(proofRes.value);
90
+ if (onchainRes.status === "fulfilled")
91
+ setOnchain(onchainRes.value);
92
+ if (proofRes.status === "fulfilled" &&
93
+ proofRes.value.status !== "success" &&
94
+ proofRes.value.status !== "failed" &&
95
+ proofRes.value.status !== "not_found") {
96
+ startProofPolling(address);
97
+ }
98
+ }
99
+ finally {
100
+ setLoading(false);
101
+ }
102
+ }, [address, client, startProofPolling]);
103
+ const analyze = (0, react_1.useCallback)(async () => {
104
+ if (!address)
105
+ return;
106
+ setAnalyzing(true);
107
+ setError(null);
108
+ setProof(null);
109
+ stopProofPolling();
110
+ try {
111
+ const result = await client.analyzeWallet(address);
112
+ setScore(result.score);
113
+ setOnchain(result.onchain);
114
+ if (result.proof)
115
+ setProof(result.proof);
116
+ startProofPolling(address);
117
+ }
118
+ catch (err) {
119
+ if (err instanceof types_1.CredGateError) {
120
+ if (err.code === types_1.ErrorCode.COOLDOWN_ACTIVE) {
121
+ const secs = err.meta?.remainingSeconds ?? 86400;
122
+ startCooldown(secs);
123
+ setError(`Cooldown active — ${Math.ceil(secs / 3600)}h remaining`);
124
+ }
125
+ else {
126
+ setError(err.message);
127
+ }
128
+ }
129
+ else {
130
+ setError("Analysis failed. Please try again.");
131
+ }
132
+ }
133
+ finally {
134
+ setAnalyzing(false);
135
+ }
136
+ }, [address, client, startProofPolling, stopProofPolling, startCooldown]);
137
+ (0, react_1.useEffect)(() => {
138
+ if (!address) {
139
+ setScore(null);
140
+ setProof(null);
141
+ setOnchain(null);
142
+ setError(null);
143
+ setCooldownRemaining(0);
144
+ stopProofPolling();
145
+ return;
146
+ }
147
+ if (autoAnalyze) {
148
+ analyze();
149
+ }
150
+ else {
151
+ refetch();
152
+ }
153
+ return () => {
154
+ stopProofPolling();
155
+ if (cooldownRef.current)
156
+ clearInterval(cooldownRef.current);
157
+ };
158
+ }, [address]);
159
+ return { score, proof, onchain, loading, analyzing, error, cooldownRemaining, analyze, refetch };
160
+ }
161
+ /**
162
+ * Minimal hook — just score, tier, eligibility.
163
+ * Perfect for simple loan-gating use cases.
164
+ *
165
+ * @example
166
+ * const { eligible, maxLoan, tier, analyze } = useSimpleScore(client, address);
167
+ * if (!eligible) return <div>Not eligible to borrow</div>;
168
+ */
169
+ function useSimpleScore(client, address) {
170
+ const { score, loading, error, analyze, cooldownRemaining } = useCredGate(client, address);
171
+ return {
172
+ creditScore: score?.creditScore ?? null,
173
+ tier: score?.tier ?? null,
174
+ maxLoan: score?.loanProfile.maxLoanSizeUSD ?? 0,
175
+ recommendedLTV: score?.loanProfile.recommendedLTV ?? 0,
176
+ eligible: score ? score.tier !== "REJECT" && score.loanProfile.maxLoanSizeUSD > 0 : false,
177
+ loading,
178
+ error,
179
+ cooldownRemaining,
180
+ analyze,
181
+ };
182
+ }
183
+ //# sourceMappingURL=hooks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hooks.js","sourceRoot":"","sources":["../../src/react/hooks.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export { useCredGate, useSimpleScore } from "./hooks";
2
+ export type { UseCredGateOptions, UseCredGateReturn } from "./hooks";
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AACtD,YAAY,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC"}
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.useSimpleScore = exports.useCredGate = void 0;
4
+ var hooks_1 = require("./hooks");
5
+ Object.defineProperty(exports, "useCredGate", { enumerable: true, get: function () { return hooks_1.useCredGate; } });
6
+ Object.defineProperty(exports, "useSimpleScore", { enumerable: true, get: function () { return hooks_1.useSimpleScore; } });
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":";;;AAAA,iCAAsD;AAA7C,oGAAA,WAAW,OAAA;AAAE,uGAAA,cAAc,OAAA"}
@@ -0,0 +1,90 @@
1
+ export type CreditTier = "ELITE" | "PRIME" | "PREFERRED" | "STANDARD" | "REJECT";
2
+ export type RiskLevel = "LOW" | "MEDIUM" | "HIGH";
3
+ export type StableLevel = "STRONG" | "MODERATE" | "WEAK";
4
+ export type ProofStatusValue = "not_found" | "queued" | "checking_contract" | "fetching_tx" | "waiting_attestation" | "generating_proof" | "submitting" | "success" | "failed";
5
+ export interface ProofStatus {
6
+ status: ProofStatusValue;
7
+ jobId?: string;
8
+ txHash?: string;
9
+ error?: string;
10
+ currentAttestedBlock?: number;
11
+ targetBlock?: number;
12
+ blocksRemaining?: number;
13
+ estimatedWaitSeconds?: number;
14
+ }
15
+ export type OnChainStatusValue = "NOT_SUBMITTED" | "UPDATED" | "COOLDOWN_ACTIVE" | "FAILED";
16
+ export interface OnChainStatus {
17
+ status: OnChainStatusValue;
18
+ txHash?: string;
19
+ reportHash?: string;
20
+ remainingSeconds?: number;
21
+ }
22
+ export interface ScoreBreakdown {
23
+ lending: number;
24
+ stable: number;
25
+ crossChain: number;
26
+ dex: number;
27
+ ageBonus: number;
28
+ riskPenalty: number;
29
+ }
30
+ export interface LoanProfile {
31
+ recommendedLTV: number;
32
+ interestTier: string;
33
+ maxLoanSizeUSD: number;
34
+ }
35
+ export interface ScoreResult {
36
+ address: string;
37
+ creditScore: number;
38
+ tier: CreditTier;
39
+ riskScore: number;
40
+ riskLevel: RiskLevel;
41
+ loanProfile: LoanProfile;
42
+ scoreBreakdown: ScoreBreakdown;
43
+ analyzedAt: number;
44
+ }
45
+ export interface AnalysisResult {
46
+ score: ScoreResult;
47
+ onchain: OnChainStatus;
48
+ proof?: ProofStatus;
49
+ }
50
+ export interface CreditLineResult {
51
+ creditLine: bigint;
52
+ available: bigint;
53
+ outstanding: {
54
+ principal: bigint;
55
+ interest: bigint;
56
+ total: bigint;
57
+ };
58
+ utilizationPct: number;
59
+ }
60
+ export interface CredGateConfig {
61
+ /** Your CredGate backend URL, e.g. https://api.credgate.xyz */
62
+ apiUrl: string;
63
+ /** Optional API key forwarded as x-api-key header */
64
+ apiKey?: string;
65
+ /** Poll interval in ms (default: 3000) */
66
+ pollInterval?: number;
67
+ /** Analysis timeout in ms (default: 120000) */
68
+ timeout?: number;
69
+ }
70
+ export interface AnalyzeOptions {
71
+ pollInterval?: number;
72
+ timeout?: number;
73
+ /** If true, also waits for CreditCoin ZK proof to reach success/failed */
74
+ waitForProof?: boolean;
75
+ }
76
+ export declare enum ErrorCode {
77
+ COOLDOWN_ACTIVE = "COOLDOWN_ACTIVE",
78
+ ANALYSIS_TIMEOUT = "ANALYSIS_TIMEOUT",
79
+ WALLET_NOT_FOUND = "WALLET_NOT_FOUND",
80
+ PROOF_FAILED = "PROOF_FAILED",
81
+ UNAUTHORIZED = "UNAUTHORIZED",
82
+ NETWORK_ERROR = "NETWORK_ERROR",
83
+ UNKNOWN = "UNKNOWN"
84
+ }
85
+ export declare class CredGateError extends Error {
86
+ readonly code: ErrorCode;
87
+ readonly meta?: Record<string, unknown> | undefined;
88
+ constructor(code: ErrorCode, message: string, meta?: Record<string, unknown> | undefined);
89
+ }
90
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js ADDED
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CredGateError = exports.ErrorCode = void 0;
4
+ // ─────────────────────────────────────────────────────────────────────────────
5
+ // Error handling
6
+ // ─────────────────────────────────────────────────────────────────────────────
7
+ var ErrorCode;
8
+ (function (ErrorCode) {
9
+ ErrorCode["COOLDOWN_ACTIVE"] = "COOLDOWN_ACTIVE";
10
+ ErrorCode["ANALYSIS_TIMEOUT"] = "ANALYSIS_TIMEOUT";
11
+ ErrorCode["WALLET_NOT_FOUND"] = "WALLET_NOT_FOUND";
12
+ ErrorCode["PROOF_FAILED"] = "PROOF_FAILED";
13
+ ErrorCode["UNAUTHORIZED"] = "UNAUTHORIZED";
14
+ ErrorCode["NETWORK_ERROR"] = "NETWORK_ERROR";
15
+ ErrorCode["UNKNOWN"] = "UNKNOWN";
16
+ })(ErrorCode || (exports.ErrorCode = ErrorCode = {}));
17
+ class CredGateError extends Error {
18
+ constructor(code, message, meta) {
19
+ super(message);
20
+ this.code = code;
21
+ this.meta = meta;
22
+ this.name = "CredGateError";
23
+ }
24
+ }
25
+ exports.CredGateError = CredGateError;
26
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":";;;AA+HA,gFAAgF;AAChF,iBAAiB;AACjB,gFAAgF;AAChF,IAAY,SAQX;AARD,WAAY,SAAS;IACjB,gDAAuC,CAAA;IACvC,kDAAwC,CAAA;IACxC,kDAAwC,CAAA;IACxC,0CAAoC,CAAA;IACpC,0CAAoC,CAAA;IACpC,4CAAqC,CAAA;IACrC,gCAA+B,CAAA;AACnC,CAAC,EARW,SAAS,yBAAT,SAAS,QAQpB;AAED,MAAa,aAAc,SAAQ,KAAK;IACpC,YACoB,IAAe,EAC/B,OAAe,EACC,IAA8B;QAE9C,KAAK,CAAC,OAAO,CAAC,CAAC;QAJC,SAAI,GAAJ,IAAI,CAAW;QAEf,SAAI,GAAJ,IAAI,CAA0B;QAG9C,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC;IAChC,CAAC;CACJ;AATD,sCASC"}
package/package.json ADDED
@@ -0,0 +1,51 @@
1
+ {
2
+ "name": "credgate-sdk",
3
+ "version": "1.0.0",
4
+ "description": "On-chain credit scoring SDK — integrate undercollateralized lending into any DeFi protocol",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "exports": {
8
+ ".": {
9
+ "require": "./dist/index.js",
10
+ "import": "./dist/index.js",
11
+ "types": "./dist/index.d.ts"
12
+ },
13
+ "./react": {
14
+ "require": "./dist/react/index.js",
15
+ "import": "./dist/react/index.js",
16
+ "types": "./dist/react/index.d.ts"
17
+ }
18
+ },
19
+ "scripts": {
20
+ "build": "tsc",
21
+ "dev": "tsc --watch",
22
+ "prepublishOnly": "npm run build"
23
+ },
24
+ "files": [
25
+ "dist",
26
+ "README.md"
27
+ ],
28
+ "keywords": [
29
+ "credit-score",
30
+ "defi",
31
+ "undercollateralized",
32
+ "lending",
33
+ "creditcoin",
34
+ "zk-proof",
35
+ "web3",
36
+ "on-chain"
37
+ ],
38
+ "license": "MIT",
39
+ "peerDependencies": {
40
+ "react": ">=18.0.0"
41
+ },
42
+ "peerDependenciesMeta": {
43
+ "react": {
44
+ "optional": true
45
+ }
46
+ },
47
+ "devDependencies": {
48
+ "@types/react": "^18.3.28",
49
+ "typescript": "^5.9.3"
50
+ }
51
+ }