@chain-lens/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.
@@ -0,0 +1,284 @@
1
+ import { WalletClient } from 'viem';
2
+
3
+ interface ChainLensConfig {
4
+ /** Base URL of the Gateway. Default: https://chainlens.pelicanlab.dev */
5
+ gatewayUrl?: string;
6
+ /** Wallet adapter — must be able to sign EIP-3009 typed data. */
7
+ wallet: WalletAdapter;
8
+ /** Off-chain budget enforcement. */
9
+ budget?: {
10
+ perCallMaxUsdc?: number;
11
+ dailyMaxUsdc?: number;
12
+ monthlyMaxUsdc?: number;
13
+ };
14
+ /** Local telemetry config. */
15
+ telemetry?: {
16
+ /** Default: true */
17
+ enabled?: boolean;
18
+ /** Upload to Gateway. Default: false (explicit opt-in). */
19
+ upload?: boolean;
20
+ /** Max entries in local JSONL buffer. Default: 1000. */
21
+ bufferMaxEntries?: number;
22
+ };
23
+ /** Auto-fallback on provider failure. */
24
+ fallback?: {
25
+ enabled: boolean;
26
+ /** Total attempts including primary. Default: 2. */
27
+ maxAttempts?: number;
28
+ };
29
+ /** Chain ID. 84532 = Base Sepolia, 8453 = Base Mainnet. */
30
+ chainId: 84532 | 8453;
31
+ }
32
+ interface WalletAdapter {
33
+ address(): Promise<`0x${string}`>;
34
+ signTypedData(typedData: TypedData): Promise<{
35
+ v: number;
36
+ r: `0x${string}`;
37
+ s: `0x${string}`;
38
+ }>;
39
+ sendTransaction(tx: TxRequest): Promise<`0x${string}`>;
40
+ }
41
+ interface TypedData {
42
+ domain: {
43
+ name: string;
44
+ version: string;
45
+ chainId: number;
46
+ verifyingContract: `0x${string}`;
47
+ };
48
+ types: Record<string, Array<{
49
+ name: string;
50
+ type: string;
51
+ }>>;
52
+ primaryType: string;
53
+ message: Record<string, unknown>;
54
+ }
55
+ interface TxRequest {
56
+ to: `0x${string}`;
57
+ data?: `0x${string}`;
58
+ value?: bigint;
59
+ }
60
+ interface CallOptions {
61
+ fallback?: boolean;
62
+ maxUsdc?: number;
63
+ idempotencyKey?: string;
64
+ signal?: AbortSignal;
65
+ }
66
+ interface CallResult<T = unknown> {
67
+ ok: true;
68
+ data: T;
69
+ listingId: number;
70
+ amountUsdc: number;
71
+ feeUsdc: number;
72
+ netUsdc: number;
73
+ settlement: {
74
+ txHash: `0x${string}`;
75
+ blockNumber: number;
76
+ };
77
+ latencyMs: number;
78
+ attemptIndex: number;
79
+ }
80
+ interface RankedListing {
81
+ listingId: number | null;
82
+ name: string | null;
83
+ score: number;
84
+ reasons: string[];
85
+ source: "chainlens" | "coinbase_bazaar" | "fixture";
86
+ verifiedByChainLens: boolean;
87
+ resource?: string;
88
+ network?: string;
89
+ asset?: string;
90
+ payTo?: string;
91
+ stats: {
92
+ successRate: number;
93
+ p50LatencyMs: number;
94
+ p95LatencyMs: number;
95
+ avgCostUsdc: number;
96
+ sampleSize: number;
97
+ };
98
+ }
99
+ interface FailureMetadata {
100
+ kind: "schema_mismatch" | "http_4xx" | "http_5xx" | "timeout" | "auth" | "rate_limit" | "gateway_error" | "budget" | "sign" | "resolve" | "unknown";
101
+ hint: string;
102
+ providerStatus?: number;
103
+ evaluatorLayer?: 1 | 2 | 3 | 4;
104
+ rawProviderError?: string;
105
+ }
106
+ interface ListingInfo {
107
+ listingId: number;
108
+ name: string | null;
109
+ priceAtomic: string | null;
110
+ maxLatencyMs: number;
111
+ taskCategory: string;
112
+ outputSchema: unknown | null;
113
+ payout: string;
114
+ active: boolean;
115
+ }
116
+ interface BudgetConfig {
117
+ perCallMaxUsdc: number;
118
+ dailyMaxUsdc: number;
119
+ monthlyMaxUsdc: number;
120
+ }
121
+
122
+ interface ClaimableResult {
123
+ totalUsdc: number;
124
+ atomicBalance: string;
125
+ }
126
+ interface ListingDashboard {
127
+ listingId: number;
128
+ name: string | null;
129
+ totalEarnedUsdc: number;
130
+ claimableUsdc: number;
131
+ callCount: number;
132
+ successRate: number;
133
+ p50LatencyMs: number;
134
+ }
135
+ declare class ProviderClient {
136
+ private readonly gatewayUrl;
137
+ private readonly wallet;
138
+ constructor(gatewayUrl: string, wallet: WalletAdapter);
139
+ claimable(): Promise<ClaimableResult>;
140
+ claim(): Promise<{
141
+ txHash: `0x${string}`;
142
+ } | {
143
+ skipped: true;
144
+ }>;
145
+ listingDashboard(listingId: number): Promise<ListingDashboard>;
146
+ }
147
+
148
+ declare class ChainLens {
149
+ private readonly cfg;
150
+ private budget;
151
+ private telemetry;
152
+ private walletAddress;
153
+ readonly provider: ProviderClient;
154
+ constructor(cfg: ChainLensConfig);
155
+ private init;
156
+ call<T = unknown>(listingId: number, params: unknown, options?: CallOptions): Promise<CallResult<T>>;
157
+ recommend(task: string, maxResults?: number): Promise<RankedListing[]>;
158
+ currentSpend(): Promise<{
159
+ dailyUsdc: number;
160
+ monthlyUsdc: number;
161
+ }>;
162
+ }
163
+
164
+ /**
165
+ * WalletAdapter backed by a viem WalletClient.
166
+ *
167
+ * Usage:
168
+ * const walletClient = createWalletClient({ account, chain, transport });
169
+ * const wallet = new ViemWallet(walletClient);
170
+ */
171
+ declare class ViemWallet implements WalletAdapter {
172
+ private readonly client;
173
+ constructor(client: WalletClient);
174
+ address(): Promise<`0x${string}`>;
175
+ signTypedData(typedData: TypedData): Promise<{
176
+ v: number;
177
+ r: `0x${string}`;
178
+ s: `0x${string}`;
179
+ }>;
180
+ sendTransaction(tx: TxRequest): Promise<`0x${string}`>;
181
+ }
182
+
183
+ /**
184
+ * Off-chain rolling-window budget controller.
185
+ *
186
+ * Persists spend records to LevelDB under ~/.chainlens/budget/<wallet>/.
187
+ * Falls back to in-memory when LevelDB is unavailable (browser / ephemeral).
188
+ */
189
+ declare class BudgetController {
190
+ private readonly cfg;
191
+ private db;
192
+ private readonly walletAddress;
193
+ private initPromise;
194
+ constructor(walletAddress: string, cfg?: Partial<BudgetConfig>);
195
+ private getDb;
196
+ private openDb;
197
+ canSpend(amount: number): Promise<{
198
+ ok: true;
199
+ } | {
200
+ ok: false;
201
+ reason: string;
202
+ }>;
203
+ debit(amount: number, idempotencyKey?: string): Promise<void>;
204
+ currentSpend(): Promise<{
205
+ dailyUsdc: number;
206
+ monthlyUsdc: number;
207
+ }>;
208
+ }
209
+
210
+ declare class ChainLensError extends Error {
211
+ readonly code: string;
212
+ readonly cause?: unknown;
213
+ constructor(message: string, code: string, cause?: unknown);
214
+ }
215
+ /** Listing not found or task query produced no match. */
216
+ declare class ChainLensResolveError extends ChainLensError {
217
+ constructor(message: string, cause?: unknown);
218
+ }
219
+ /** Off-chain budget limit exceeded before any signature was produced. */
220
+ declare class BudgetExceededError extends ChainLensError {
221
+ readonly reason: string;
222
+ constructor(reason: string);
223
+ }
224
+ /** EIP-3009 signing failed. */
225
+ declare class ChainLensSignError extends ChainLensError {
226
+ constructor(message: string, cause?: unknown);
227
+ }
228
+ /** Gateway returned a non-200 HTTP status. */
229
+ declare class ChainLensGatewayError extends ChainLensError {
230
+ readonly status: number;
231
+ constructor(message: string, status: number, cause?: unknown);
232
+ }
233
+ /** The call completed but the provider reported failure (no settlement). */
234
+ declare class ChainLensCallError extends ChainLensError {
235
+ readonly failure: FailureMetadata;
236
+ constructor(failure: FailureMetadata);
237
+ }
238
+
239
+ /** Chain-specific USDC contract addresses. */
240
+ declare const USDC_ADDRESSES: Record<number, `0x${string}`>;
241
+ /** ChainLensMarket addresses per chain. */
242
+ declare const CHAIN_LENS_MARKET_ADDRESSES: Record<number, `0x${string}`>;
243
+ interface Eip3009Auth {
244
+ from: `0x${string}`;
245
+ to: `0x${string}`;
246
+ amount: string;
247
+ validAfter: string;
248
+ validBefore: string;
249
+ nonce: `0x${string}`;
250
+ v: number;
251
+ r: `0x${string}`;
252
+ s: `0x${string}`;
253
+ }
254
+ declare function signReceiveWithAuthorization(opts: {
255
+ wallet: WalletAdapter;
256
+ chainId: number;
257
+ amount: bigint;
258
+ to: `0x${string}`;
259
+ signal?: AbortSignal;
260
+ }): Promise<Eip3009Auth>;
261
+ /** Convert USDC display units (e.g. 0.05) to atomic units (50000). */
262
+ declare function usdcToAtomic(usdc: number): bigint;
263
+ /** Convert atomic USDC units to display units. */
264
+ declare function atomicToUsdc(atomic: bigint | string): number;
265
+
266
+ interface TelemetryEntry {
267
+ ts: number;
268
+ listingId: number;
269
+ amountUsdc: number;
270
+ latencyMs: number;
271
+ ok: boolean;
272
+ failure?: FailureMetadata;
273
+ txHash?: string;
274
+ paramsHash?: string;
275
+ }
276
+ interface TelemetryConfig {
277
+ enabled: boolean;
278
+ upload: boolean;
279
+ bufferMaxEntries: number;
280
+ gatewayUrl: string;
281
+ walletAddress: string;
282
+ }
283
+
284
+ export { type BudgetConfig, BudgetController, BudgetExceededError, CHAIN_LENS_MARKET_ADDRESSES, type CallOptions, type CallResult, ChainLens, ChainLensCallError, type ChainLensConfig, ChainLensError, ChainLensGatewayError, ChainLensResolveError, ChainLensSignError, type ClaimableResult, type FailureMetadata, type ListingDashboard, type ListingInfo, ProviderClient, type RankedListing, type TelemetryConfig, type TelemetryEntry, type TxRequest, type TypedData, USDC_ADDRESSES, ViemWallet, type WalletAdapter, atomicToUsdc, signReceiveWithAuthorization, usdcToAtomic };
@@ -0,0 +1,284 @@
1
+ import { WalletClient } from 'viem';
2
+
3
+ interface ChainLensConfig {
4
+ /** Base URL of the Gateway. Default: https://chainlens.pelicanlab.dev */
5
+ gatewayUrl?: string;
6
+ /** Wallet adapter — must be able to sign EIP-3009 typed data. */
7
+ wallet: WalletAdapter;
8
+ /** Off-chain budget enforcement. */
9
+ budget?: {
10
+ perCallMaxUsdc?: number;
11
+ dailyMaxUsdc?: number;
12
+ monthlyMaxUsdc?: number;
13
+ };
14
+ /** Local telemetry config. */
15
+ telemetry?: {
16
+ /** Default: true */
17
+ enabled?: boolean;
18
+ /** Upload to Gateway. Default: false (explicit opt-in). */
19
+ upload?: boolean;
20
+ /** Max entries in local JSONL buffer. Default: 1000. */
21
+ bufferMaxEntries?: number;
22
+ };
23
+ /** Auto-fallback on provider failure. */
24
+ fallback?: {
25
+ enabled: boolean;
26
+ /** Total attempts including primary. Default: 2. */
27
+ maxAttempts?: number;
28
+ };
29
+ /** Chain ID. 84532 = Base Sepolia, 8453 = Base Mainnet. */
30
+ chainId: 84532 | 8453;
31
+ }
32
+ interface WalletAdapter {
33
+ address(): Promise<`0x${string}`>;
34
+ signTypedData(typedData: TypedData): Promise<{
35
+ v: number;
36
+ r: `0x${string}`;
37
+ s: `0x${string}`;
38
+ }>;
39
+ sendTransaction(tx: TxRequest): Promise<`0x${string}`>;
40
+ }
41
+ interface TypedData {
42
+ domain: {
43
+ name: string;
44
+ version: string;
45
+ chainId: number;
46
+ verifyingContract: `0x${string}`;
47
+ };
48
+ types: Record<string, Array<{
49
+ name: string;
50
+ type: string;
51
+ }>>;
52
+ primaryType: string;
53
+ message: Record<string, unknown>;
54
+ }
55
+ interface TxRequest {
56
+ to: `0x${string}`;
57
+ data?: `0x${string}`;
58
+ value?: bigint;
59
+ }
60
+ interface CallOptions {
61
+ fallback?: boolean;
62
+ maxUsdc?: number;
63
+ idempotencyKey?: string;
64
+ signal?: AbortSignal;
65
+ }
66
+ interface CallResult<T = unknown> {
67
+ ok: true;
68
+ data: T;
69
+ listingId: number;
70
+ amountUsdc: number;
71
+ feeUsdc: number;
72
+ netUsdc: number;
73
+ settlement: {
74
+ txHash: `0x${string}`;
75
+ blockNumber: number;
76
+ };
77
+ latencyMs: number;
78
+ attemptIndex: number;
79
+ }
80
+ interface RankedListing {
81
+ listingId: number | null;
82
+ name: string | null;
83
+ score: number;
84
+ reasons: string[];
85
+ source: "chainlens" | "coinbase_bazaar" | "fixture";
86
+ verifiedByChainLens: boolean;
87
+ resource?: string;
88
+ network?: string;
89
+ asset?: string;
90
+ payTo?: string;
91
+ stats: {
92
+ successRate: number;
93
+ p50LatencyMs: number;
94
+ p95LatencyMs: number;
95
+ avgCostUsdc: number;
96
+ sampleSize: number;
97
+ };
98
+ }
99
+ interface FailureMetadata {
100
+ kind: "schema_mismatch" | "http_4xx" | "http_5xx" | "timeout" | "auth" | "rate_limit" | "gateway_error" | "budget" | "sign" | "resolve" | "unknown";
101
+ hint: string;
102
+ providerStatus?: number;
103
+ evaluatorLayer?: 1 | 2 | 3 | 4;
104
+ rawProviderError?: string;
105
+ }
106
+ interface ListingInfo {
107
+ listingId: number;
108
+ name: string | null;
109
+ priceAtomic: string | null;
110
+ maxLatencyMs: number;
111
+ taskCategory: string;
112
+ outputSchema: unknown | null;
113
+ payout: string;
114
+ active: boolean;
115
+ }
116
+ interface BudgetConfig {
117
+ perCallMaxUsdc: number;
118
+ dailyMaxUsdc: number;
119
+ monthlyMaxUsdc: number;
120
+ }
121
+
122
+ interface ClaimableResult {
123
+ totalUsdc: number;
124
+ atomicBalance: string;
125
+ }
126
+ interface ListingDashboard {
127
+ listingId: number;
128
+ name: string | null;
129
+ totalEarnedUsdc: number;
130
+ claimableUsdc: number;
131
+ callCount: number;
132
+ successRate: number;
133
+ p50LatencyMs: number;
134
+ }
135
+ declare class ProviderClient {
136
+ private readonly gatewayUrl;
137
+ private readonly wallet;
138
+ constructor(gatewayUrl: string, wallet: WalletAdapter);
139
+ claimable(): Promise<ClaimableResult>;
140
+ claim(): Promise<{
141
+ txHash: `0x${string}`;
142
+ } | {
143
+ skipped: true;
144
+ }>;
145
+ listingDashboard(listingId: number): Promise<ListingDashboard>;
146
+ }
147
+
148
+ declare class ChainLens {
149
+ private readonly cfg;
150
+ private budget;
151
+ private telemetry;
152
+ private walletAddress;
153
+ readonly provider: ProviderClient;
154
+ constructor(cfg: ChainLensConfig);
155
+ private init;
156
+ call<T = unknown>(listingId: number, params: unknown, options?: CallOptions): Promise<CallResult<T>>;
157
+ recommend(task: string, maxResults?: number): Promise<RankedListing[]>;
158
+ currentSpend(): Promise<{
159
+ dailyUsdc: number;
160
+ monthlyUsdc: number;
161
+ }>;
162
+ }
163
+
164
+ /**
165
+ * WalletAdapter backed by a viem WalletClient.
166
+ *
167
+ * Usage:
168
+ * const walletClient = createWalletClient({ account, chain, transport });
169
+ * const wallet = new ViemWallet(walletClient);
170
+ */
171
+ declare class ViemWallet implements WalletAdapter {
172
+ private readonly client;
173
+ constructor(client: WalletClient);
174
+ address(): Promise<`0x${string}`>;
175
+ signTypedData(typedData: TypedData): Promise<{
176
+ v: number;
177
+ r: `0x${string}`;
178
+ s: `0x${string}`;
179
+ }>;
180
+ sendTransaction(tx: TxRequest): Promise<`0x${string}`>;
181
+ }
182
+
183
+ /**
184
+ * Off-chain rolling-window budget controller.
185
+ *
186
+ * Persists spend records to LevelDB under ~/.chainlens/budget/<wallet>/.
187
+ * Falls back to in-memory when LevelDB is unavailable (browser / ephemeral).
188
+ */
189
+ declare class BudgetController {
190
+ private readonly cfg;
191
+ private db;
192
+ private readonly walletAddress;
193
+ private initPromise;
194
+ constructor(walletAddress: string, cfg?: Partial<BudgetConfig>);
195
+ private getDb;
196
+ private openDb;
197
+ canSpend(amount: number): Promise<{
198
+ ok: true;
199
+ } | {
200
+ ok: false;
201
+ reason: string;
202
+ }>;
203
+ debit(amount: number, idempotencyKey?: string): Promise<void>;
204
+ currentSpend(): Promise<{
205
+ dailyUsdc: number;
206
+ monthlyUsdc: number;
207
+ }>;
208
+ }
209
+
210
+ declare class ChainLensError extends Error {
211
+ readonly code: string;
212
+ readonly cause?: unknown;
213
+ constructor(message: string, code: string, cause?: unknown);
214
+ }
215
+ /** Listing not found or task query produced no match. */
216
+ declare class ChainLensResolveError extends ChainLensError {
217
+ constructor(message: string, cause?: unknown);
218
+ }
219
+ /** Off-chain budget limit exceeded before any signature was produced. */
220
+ declare class BudgetExceededError extends ChainLensError {
221
+ readonly reason: string;
222
+ constructor(reason: string);
223
+ }
224
+ /** EIP-3009 signing failed. */
225
+ declare class ChainLensSignError extends ChainLensError {
226
+ constructor(message: string, cause?: unknown);
227
+ }
228
+ /** Gateway returned a non-200 HTTP status. */
229
+ declare class ChainLensGatewayError extends ChainLensError {
230
+ readonly status: number;
231
+ constructor(message: string, status: number, cause?: unknown);
232
+ }
233
+ /** The call completed but the provider reported failure (no settlement). */
234
+ declare class ChainLensCallError extends ChainLensError {
235
+ readonly failure: FailureMetadata;
236
+ constructor(failure: FailureMetadata);
237
+ }
238
+
239
+ /** Chain-specific USDC contract addresses. */
240
+ declare const USDC_ADDRESSES: Record<number, `0x${string}`>;
241
+ /** ChainLensMarket addresses per chain. */
242
+ declare const CHAIN_LENS_MARKET_ADDRESSES: Record<number, `0x${string}`>;
243
+ interface Eip3009Auth {
244
+ from: `0x${string}`;
245
+ to: `0x${string}`;
246
+ amount: string;
247
+ validAfter: string;
248
+ validBefore: string;
249
+ nonce: `0x${string}`;
250
+ v: number;
251
+ r: `0x${string}`;
252
+ s: `0x${string}`;
253
+ }
254
+ declare function signReceiveWithAuthorization(opts: {
255
+ wallet: WalletAdapter;
256
+ chainId: number;
257
+ amount: bigint;
258
+ to: `0x${string}`;
259
+ signal?: AbortSignal;
260
+ }): Promise<Eip3009Auth>;
261
+ /** Convert USDC display units (e.g. 0.05) to atomic units (50000). */
262
+ declare function usdcToAtomic(usdc: number): bigint;
263
+ /** Convert atomic USDC units to display units. */
264
+ declare function atomicToUsdc(atomic: bigint | string): number;
265
+
266
+ interface TelemetryEntry {
267
+ ts: number;
268
+ listingId: number;
269
+ amountUsdc: number;
270
+ latencyMs: number;
271
+ ok: boolean;
272
+ failure?: FailureMetadata;
273
+ txHash?: string;
274
+ paramsHash?: string;
275
+ }
276
+ interface TelemetryConfig {
277
+ enabled: boolean;
278
+ upload: boolean;
279
+ bufferMaxEntries: number;
280
+ gatewayUrl: string;
281
+ walletAddress: string;
282
+ }
283
+
284
+ export { type BudgetConfig, BudgetController, BudgetExceededError, CHAIN_LENS_MARKET_ADDRESSES, type CallOptions, type CallResult, ChainLens, ChainLensCallError, type ChainLensConfig, ChainLensError, ChainLensGatewayError, ChainLensResolveError, ChainLensSignError, type ClaimableResult, type FailureMetadata, type ListingDashboard, type ListingInfo, ProviderClient, type RankedListing, type TelemetryConfig, type TelemetryEntry, type TxRequest, type TypedData, USDC_ADDRESSES, ViemWallet, type WalletAdapter, atomicToUsdc, signReceiveWithAuthorization, usdcToAtomic };