@blockrun/llm 0.1.1
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 +21 -0
- package/README.md +320 -0
- package/dist/chunk-FCKQTBEP.mjs +90 -0
- package/dist/chunk-HEBXNMVQ.mjs +48 -0
- package/dist/chunk-R7MQBF5Y.mjs +26586 -0
- package/dist/chunk-TYQEUMVI.mjs +206 -0
- package/dist/esm-3BUZROFC.mjs +7964 -0
- package/dist/index.d.mts +295 -0
- package/dist/index.d.ts +295 -0
- package/dist/index.esm-FLTVMT4C.mjs +157 -0
- package/dist/index.js +36968 -0
- package/dist/index.mjs +428 -0
- package/dist/validation-FPOEEOR4.mjs +15 -0
- package/dist/x402-ELHVFRUU.mjs +27 -0
- package/package.json +65 -0
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,428 @@
|
|
|
1
|
+
import {
|
|
2
|
+
BASE_CHAIN_ID,
|
|
3
|
+
USDC_BASE,
|
|
4
|
+
createPaymentPayload,
|
|
5
|
+
extractPaymentDetails,
|
|
6
|
+
parsePaymentRequired
|
|
7
|
+
} from "./chunk-TYQEUMVI.mjs";
|
|
8
|
+
import {
|
|
9
|
+
sanitizeErrorResponse,
|
|
10
|
+
validateApiUrl,
|
|
11
|
+
validatePrivateKey,
|
|
12
|
+
validateResourceUrl
|
|
13
|
+
} from "./chunk-FCKQTBEP.mjs";
|
|
14
|
+
import "./chunk-HEBXNMVQ.mjs";
|
|
15
|
+
|
|
16
|
+
// src/client.ts
|
|
17
|
+
import { privateKeyToAccount } from "viem/accounts";
|
|
18
|
+
|
|
19
|
+
// src/types.ts
|
|
20
|
+
var BlockrunError = class extends Error {
|
|
21
|
+
constructor(message) {
|
|
22
|
+
super(message);
|
|
23
|
+
this.name = "BlockrunError";
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
var PaymentError = class extends BlockrunError {
|
|
27
|
+
constructor(message) {
|
|
28
|
+
super(message);
|
|
29
|
+
this.name = "PaymentError";
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
var APIError = class extends BlockrunError {
|
|
33
|
+
statusCode;
|
|
34
|
+
response;
|
|
35
|
+
constructor(message, statusCode, response) {
|
|
36
|
+
super(message);
|
|
37
|
+
this.name = "APIError";
|
|
38
|
+
this.statusCode = statusCode;
|
|
39
|
+
this.response = response;
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
// src/client.ts
|
|
44
|
+
var DEFAULT_API_URL = "https://blockrun.ai/api";
|
|
45
|
+
var DEFAULT_MAX_TOKENS = 1024;
|
|
46
|
+
var DEFAULT_TIMEOUT = 6e4;
|
|
47
|
+
var LLMClient = class {
|
|
48
|
+
account;
|
|
49
|
+
privateKey;
|
|
50
|
+
apiUrl;
|
|
51
|
+
timeout;
|
|
52
|
+
/**
|
|
53
|
+
* Initialize the BlockRun LLM client.
|
|
54
|
+
*
|
|
55
|
+
* @param options - Client configuration options (optional if BASE_CHAIN_WALLET_KEY env var is set)
|
|
56
|
+
*/
|
|
57
|
+
constructor(options = {}) {
|
|
58
|
+
const envKey = typeof process !== "undefined" && process.env ? process.env.BASE_CHAIN_WALLET_KEY : void 0;
|
|
59
|
+
const privateKey = options.privateKey || envKey;
|
|
60
|
+
if (!privateKey) {
|
|
61
|
+
throw new Error(
|
|
62
|
+
"Private key required. Pass privateKey in options or set BASE_CHAIN_WALLET_KEY environment variable."
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
validatePrivateKey(privateKey);
|
|
66
|
+
this.privateKey = privateKey;
|
|
67
|
+
this.account = privateKeyToAccount(privateKey);
|
|
68
|
+
const apiUrl = options.apiUrl || DEFAULT_API_URL;
|
|
69
|
+
validateApiUrl(apiUrl);
|
|
70
|
+
this.apiUrl = apiUrl.replace(/\/$/, "");
|
|
71
|
+
this.timeout = options.timeout || DEFAULT_TIMEOUT;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Simple 1-line chat interface.
|
|
75
|
+
*
|
|
76
|
+
* @param model - Model ID (e.g., 'openai/gpt-4o', 'anthropic/claude-sonnet-4')
|
|
77
|
+
* @param prompt - User message
|
|
78
|
+
* @param options - Optional chat parameters
|
|
79
|
+
* @returns Assistant's response text
|
|
80
|
+
*
|
|
81
|
+
* @example
|
|
82
|
+
* const response = await client.chat('gpt-4o', 'What is the capital of France?');
|
|
83
|
+
* console.log(response); // 'The capital of France is Paris.'
|
|
84
|
+
*/
|
|
85
|
+
async chat(model, prompt, options) {
|
|
86
|
+
const messages = [];
|
|
87
|
+
if (options?.system) {
|
|
88
|
+
messages.push({ role: "system", content: options.system });
|
|
89
|
+
}
|
|
90
|
+
messages.push({ role: "user", content: prompt });
|
|
91
|
+
const result = await this.chatCompletion(model, messages, {
|
|
92
|
+
maxTokens: options?.maxTokens,
|
|
93
|
+
temperature: options?.temperature,
|
|
94
|
+
topP: options?.topP
|
|
95
|
+
});
|
|
96
|
+
return result.choices[0].message.content;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Full chat completion interface (OpenAI-compatible).
|
|
100
|
+
*
|
|
101
|
+
* @param model - Model ID
|
|
102
|
+
* @param messages - Array of messages with role and content
|
|
103
|
+
* @param options - Optional completion parameters
|
|
104
|
+
* @returns ChatResponse object with choices and usage
|
|
105
|
+
*/
|
|
106
|
+
async chatCompletion(model, messages, options) {
|
|
107
|
+
const body = {
|
|
108
|
+
model,
|
|
109
|
+
messages,
|
|
110
|
+
max_tokens: options?.maxTokens || DEFAULT_MAX_TOKENS
|
|
111
|
+
};
|
|
112
|
+
if (options?.temperature !== void 0) {
|
|
113
|
+
body.temperature = options.temperature;
|
|
114
|
+
}
|
|
115
|
+
if (options?.topP !== void 0) {
|
|
116
|
+
body.top_p = options.topP;
|
|
117
|
+
}
|
|
118
|
+
return this.requestWithPayment("/v1/chat/completions", body);
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Make a request with automatic x402 payment handling.
|
|
122
|
+
*/
|
|
123
|
+
async requestWithPayment(endpoint, body) {
|
|
124
|
+
const url = `${this.apiUrl}${endpoint}`;
|
|
125
|
+
const response = await this.fetchWithTimeout(url, {
|
|
126
|
+
method: "POST",
|
|
127
|
+
headers: { "Content-Type": "application/json" },
|
|
128
|
+
body: JSON.stringify(body)
|
|
129
|
+
});
|
|
130
|
+
if (response.status === 402) {
|
|
131
|
+
return this.handlePaymentAndRetry(url, body, response);
|
|
132
|
+
}
|
|
133
|
+
if (!response.ok) {
|
|
134
|
+
let errorBody;
|
|
135
|
+
try {
|
|
136
|
+
errorBody = await response.json();
|
|
137
|
+
} catch {
|
|
138
|
+
errorBody = { error: "Request failed" };
|
|
139
|
+
}
|
|
140
|
+
throw new APIError(
|
|
141
|
+
`API error: ${response.status}`,
|
|
142
|
+
response.status,
|
|
143
|
+
sanitizeErrorResponse(errorBody)
|
|
144
|
+
);
|
|
145
|
+
}
|
|
146
|
+
return response.json();
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Handle 402 response: parse requirements, sign payment, retry.
|
|
150
|
+
*/
|
|
151
|
+
async handlePaymentAndRetry(url, body, response) {
|
|
152
|
+
let paymentHeader = response.headers.get("payment-required");
|
|
153
|
+
if (!paymentHeader) {
|
|
154
|
+
try {
|
|
155
|
+
const respBody = await response.json();
|
|
156
|
+
if (respBody.x402 || respBody.accepts) {
|
|
157
|
+
paymentHeader = btoa(JSON.stringify(respBody));
|
|
158
|
+
}
|
|
159
|
+
} catch (parseError) {
|
|
160
|
+
console.debug("Failed to parse payment header from response body", parseError);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
if (!paymentHeader) {
|
|
164
|
+
throw new PaymentError("402 response but no payment requirements found");
|
|
165
|
+
}
|
|
166
|
+
const paymentRequired = parsePaymentRequired(paymentHeader);
|
|
167
|
+
const details = extractPaymentDetails(paymentRequired);
|
|
168
|
+
const extensions = paymentRequired.extensions;
|
|
169
|
+
const paymentPayload = await createPaymentPayload(
|
|
170
|
+
this.privateKey,
|
|
171
|
+
this.account.address,
|
|
172
|
+
details.recipient,
|
|
173
|
+
details.amount,
|
|
174
|
+
details.network || "eip155:8453",
|
|
175
|
+
{
|
|
176
|
+
resourceUrl: validateResourceUrl(
|
|
177
|
+
details.resource?.url || `${this.apiUrl}/v1/chat/completions`,
|
|
178
|
+
this.apiUrl
|
|
179
|
+
),
|
|
180
|
+
resourceDescription: details.resource?.description || "BlockRun AI API call",
|
|
181
|
+
maxTimeoutSeconds: details.maxTimeoutSeconds || 300,
|
|
182
|
+
extra: details.extra,
|
|
183
|
+
extensions
|
|
184
|
+
}
|
|
185
|
+
);
|
|
186
|
+
const retryResponse = await this.fetchWithTimeout(url, {
|
|
187
|
+
method: "POST",
|
|
188
|
+
headers: {
|
|
189
|
+
"Content-Type": "application/json",
|
|
190
|
+
"PAYMENT-SIGNATURE": paymentPayload
|
|
191
|
+
},
|
|
192
|
+
body: JSON.stringify(body)
|
|
193
|
+
});
|
|
194
|
+
if (retryResponse.status === 402) {
|
|
195
|
+
throw new PaymentError("Payment was rejected. Check your wallet balance.");
|
|
196
|
+
}
|
|
197
|
+
if (!retryResponse.ok) {
|
|
198
|
+
let errorBody;
|
|
199
|
+
try {
|
|
200
|
+
errorBody = await retryResponse.json();
|
|
201
|
+
} catch {
|
|
202
|
+
errorBody = { error: "Request failed" };
|
|
203
|
+
}
|
|
204
|
+
throw new APIError(
|
|
205
|
+
`API error after payment: ${retryResponse.status}`,
|
|
206
|
+
retryResponse.status,
|
|
207
|
+
sanitizeErrorResponse(errorBody)
|
|
208
|
+
);
|
|
209
|
+
}
|
|
210
|
+
return retryResponse.json();
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Fetch with timeout.
|
|
214
|
+
*/
|
|
215
|
+
async fetchWithTimeout(url, options) {
|
|
216
|
+
const controller = new AbortController();
|
|
217
|
+
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
|
|
218
|
+
try {
|
|
219
|
+
const response = await fetch(url, {
|
|
220
|
+
...options,
|
|
221
|
+
signal: controller.signal
|
|
222
|
+
});
|
|
223
|
+
return response;
|
|
224
|
+
} finally {
|
|
225
|
+
clearTimeout(timeoutId);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* List available models with pricing.
|
|
230
|
+
*/
|
|
231
|
+
async listModels() {
|
|
232
|
+
const response = await this.fetchWithTimeout(`${this.apiUrl}/v1/models`, {
|
|
233
|
+
method: "GET"
|
|
234
|
+
});
|
|
235
|
+
if (!response.ok) {
|
|
236
|
+
throw new APIError(
|
|
237
|
+
`Failed to list models: ${response.status}`,
|
|
238
|
+
response.status
|
|
239
|
+
);
|
|
240
|
+
}
|
|
241
|
+
const data = await response.json();
|
|
242
|
+
return data.data || [];
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* Get the wallet address being used for payments.
|
|
246
|
+
*/
|
|
247
|
+
getWalletAddress() {
|
|
248
|
+
return this.account.address;
|
|
249
|
+
}
|
|
250
|
+
};
|
|
251
|
+
var client_default = LLMClient;
|
|
252
|
+
|
|
253
|
+
// src/openai-compat.ts
|
|
254
|
+
var StreamingResponse = class {
|
|
255
|
+
reader;
|
|
256
|
+
decoder;
|
|
257
|
+
buffer = "";
|
|
258
|
+
model;
|
|
259
|
+
id;
|
|
260
|
+
constructor(response, model) {
|
|
261
|
+
if (!response.body) {
|
|
262
|
+
throw new Error("Response body is null");
|
|
263
|
+
}
|
|
264
|
+
this.reader = response.body.getReader();
|
|
265
|
+
this.decoder = new TextDecoder();
|
|
266
|
+
this.model = model;
|
|
267
|
+
this.id = `chatcmpl-${Date.now()}`;
|
|
268
|
+
}
|
|
269
|
+
async *[Symbol.asyncIterator]() {
|
|
270
|
+
try {
|
|
271
|
+
while (true) {
|
|
272
|
+
const { done, value } = await this.reader.read();
|
|
273
|
+
if (done) break;
|
|
274
|
+
this.buffer += this.decoder.decode(value, { stream: true });
|
|
275
|
+
const lines = this.buffer.split("\n");
|
|
276
|
+
this.buffer = lines.pop() || "";
|
|
277
|
+
for (const line of lines) {
|
|
278
|
+
const trimmed = line.trim();
|
|
279
|
+
if (!trimmed || !trimmed.startsWith("data: ")) continue;
|
|
280
|
+
const data = trimmed.slice(6);
|
|
281
|
+
if (data === "[DONE]") return;
|
|
282
|
+
try {
|
|
283
|
+
const parsed = JSON.parse(data);
|
|
284
|
+
yield this.transformChunk(parsed);
|
|
285
|
+
} catch {
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
} finally {
|
|
290
|
+
this.reader.releaseLock();
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
transformChunk(data) {
|
|
294
|
+
const choices = data.choices || [];
|
|
295
|
+
return {
|
|
296
|
+
id: data.id || this.id,
|
|
297
|
+
object: "chat.completion.chunk",
|
|
298
|
+
created: data.created || Math.floor(Date.now() / 1e3),
|
|
299
|
+
model: data.model || this.model,
|
|
300
|
+
choices: choices.map((choice, index) => ({
|
|
301
|
+
index: choice.index ?? index,
|
|
302
|
+
delta: {
|
|
303
|
+
role: choice.delta?.role,
|
|
304
|
+
content: choice.delta?.content
|
|
305
|
+
},
|
|
306
|
+
finish_reason: choice.finish_reason || null
|
|
307
|
+
}))
|
|
308
|
+
};
|
|
309
|
+
}
|
|
310
|
+
};
|
|
311
|
+
var ChatCompletions = class {
|
|
312
|
+
constructor(client, apiUrl, timeout) {
|
|
313
|
+
this.client = client;
|
|
314
|
+
this.apiUrl = apiUrl;
|
|
315
|
+
this.timeout = timeout;
|
|
316
|
+
}
|
|
317
|
+
async create(params) {
|
|
318
|
+
if (params.stream) {
|
|
319
|
+
return this.createStream(params);
|
|
320
|
+
}
|
|
321
|
+
const response = await this.client.chatCompletion(
|
|
322
|
+
params.model,
|
|
323
|
+
params.messages,
|
|
324
|
+
{
|
|
325
|
+
maxTokens: params.max_tokens,
|
|
326
|
+
temperature: params.temperature,
|
|
327
|
+
topP: params.top_p
|
|
328
|
+
}
|
|
329
|
+
);
|
|
330
|
+
return this.transformResponse(response);
|
|
331
|
+
}
|
|
332
|
+
async createStream(params) {
|
|
333
|
+
const url = `${this.apiUrl}/v1/chat/completions`;
|
|
334
|
+
const body = {
|
|
335
|
+
model: params.model,
|
|
336
|
+
messages: params.messages,
|
|
337
|
+
max_tokens: params.max_tokens || 1024,
|
|
338
|
+
temperature: params.temperature,
|
|
339
|
+
top_p: params.top_p,
|
|
340
|
+
stream: true
|
|
341
|
+
};
|
|
342
|
+
const controller = new AbortController();
|
|
343
|
+
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
|
|
344
|
+
try {
|
|
345
|
+
let response = await fetch(url, {
|
|
346
|
+
method: "POST",
|
|
347
|
+
headers: { "Content-Type": "application/json" },
|
|
348
|
+
body: JSON.stringify(body),
|
|
349
|
+
signal: controller.signal
|
|
350
|
+
});
|
|
351
|
+
if (response.status === 402) {
|
|
352
|
+
const paymentHeader = response.headers.get("payment-required");
|
|
353
|
+
if (!paymentHeader) {
|
|
354
|
+
throw new Error("402 response but no payment requirements found");
|
|
355
|
+
}
|
|
356
|
+
const { createPaymentPayload: createPaymentPayload2, parsePaymentRequired: parsePaymentRequired2, extractPaymentDetails: extractPaymentDetails2 } = await import("./x402-ELHVFRUU.mjs");
|
|
357
|
+
const { validateResourceUrl: validateResourceUrl2 } = await import("./validation-FPOEEOR4.mjs");
|
|
358
|
+
const { privateKeyToAccount: privateKeyToAccount2 } = await import("viem/accounts");
|
|
359
|
+
const paymentRequired = parsePaymentRequired2(paymentHeader);
|
|
360
|
+
const details = extractPaymentDetails2(paymentRequired);
|
|
361
|
+
const walletAddress = this.client.getWalletAddress();
|
|
362
|
+
throw new Error(
|
|
363
|
+
"Streaming with automatic payment requires direct wallet access. Please use non-streaming mode or contact support for streaming setup."
|
|
364
|
+
);
|
|
365
|
+
}
|
|
366
|
+
if (!response.ok) {
|
|
367
|
+
throw new Error(`API error: ${response.status}`);
|
|
368
|
+
}
|
|
369
|
+
return new StreamingResponse(response, params.model);
|
|
370
|
+
} finally {
|
|
371
|
+
clearTimeout(timeoutId);
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
transformResponse(response) {
|
|
375
|
+
return {
|
|
376
|
+
id: response.id || `chatcmpl-${Date.now()}`,
|
|
377
|
+
object: "chat.completion",
|
|
378
|
+
created: response.created || Math.floor(Date.now() / 1e3),
|
|
379
|
+
model: response.model,
|
|
380
|
+
choices: response.choices.map((choice, index) => ({
|
|
381
|
+
index: choice.index ?? index,
|
|
382
|
+
message: {
|
|
383
|
+
role: "assistant",
|
|
384
|
+
content: choice.message.content
|
|
385
|
+
},
|
|
386
|
+
finish_reason: choice.finish_reason || "stop"
|
|
387
|
+
})),
|
|
388
|
+
usage: response.usage
|
|
389
|
+
};
|
|
390
|
+
}
|
|
391
|
+
};
|
|
392
|
+
var Chat = class {
|
|
393
|
+
completions;
|
|
394
|
+
constructor(client, apiUrl, timeout) {
|
|
395
|
+
this.completions = new ChatCompletions(client, apiUrl, timeout);
|
|
396
|
+
}
|
|
397
|
+
};
|
|
398
|
+
var OpenAI = class {
|
|
399
|
+
chat;
|
|
400
|
+
client;
|
|
401
|
+
constructor(options = {}) {
|
|
402
|
+
const privateKey = options.walletKey || options.privateKey;
|
|
403
|
+
const apiUrl = options.baseURL || "https://blockrun.ai/api";
|
|
404
|
+
const timeout = options.timeout || 6e4;
|
|
405
|
+
this.client = new LLMClient({
|
|
406
|
+
privateKey,
|
|
407
|
+
apiUrl,
|
|
408
|
+
timeout
|
|
409
|
+
});
|
|
410
|
+
this.chat = new Chat(this.client, apiUrl, timeout);
|
|
411
|
+
}
|
|
412
|
+
/**
|
|
413
|
+
* Get the wallet address being used for payments.
|
|
414
|
+
*/
|
|
415
|
+
getWalletAddress() {
|
|
416
|
+
return this.client.getWalletAddress();
|
|
417
|
+
}
|
|
418
|
+
};
|
|
419
|
+
export {
|
|
420
|
+
APIError,
|
|
421
|
+
BASE_CHAIN_ID,
|
|
422
|
+
BlockrunError,
|
|
423
|
+
LLMClient,
|
|
424
|
+
OpenAI,
|
|
425
|
+
PaymentError,
|
|
426
|
+
USDC_BASE,
|
|
427
|
+
client_default as default
|
|
428
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import {
|
|
2
|
+
extractPrivateKey,
|
|
3
|
+
sanitizeErrorResponse,
|
|
4
|
+
validateApiUrl,
|
|
5
|
+
validatePrivateKey,
|
|
6
|
+
validateResourceUrl
|
|
7
|
+
} from "./chunk-FCKQTBEP.mjs";
|
|
8
|
+
import "./chunk-HEBXNMVQ.mjs";
|
|
9
|
+
export {
|
|
10
|
+
extractPrivateKey,
|
|
11
|
+
sanitizeErrorResponse,
|
|
12
|
+
validateApiUrl,
|
|
13
|
+
validatePrivateKey,
|
|
14
|
+
validateResourceUrl
|
|
15
|
+
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import {
|
|
2
|
+
BASE_CHAIN_ID,
|
|
3
|
+
SOLANA_NETWORK,
|
|
4
|
+
SOLANA_USDC_DECIMALS,
|
|
5
|
+
USDC_BASE,
|
|
6
|
+
USDC_SOLANA,
|
|
7
|
+
createPaymentPayload,
|
|
8
|
+
createSolanaPaymentPayload,
|
|
9
|
+
extractPaymentDetails,
|
|
10
|
+
getAvailableNetworks,
|
|
11
|
+
isSolanaNetwork,
|
|
12
|
+
parsePaymentRequired
|
|
13
|
+
} from "./chunk-TYQEUMVI.mjs";
|
|
14
|
+
import "./chunk-HEBXNMVQ.mjs";
|
|
15
|
+
export {
|
|
16
|
+
BASE_CHAIN_ID,
|
|
17
|
+
SOLANA_NETWORK,
|
|
18
|
+
SOLANA_USDC_DECIMALS,
|
|
19
|
+
USDC_BASE,
|
|
20
|
+
USDC_SOLANA,
|
|
21
|
+
createPaymentPayload,
|
|
22
|
+
createSolanaPaymentPayload,
|
|
23
|
+
extractPaymentDetails,
|
|
24
|
+
getAvailableNetworks,
|
|
25
|
+
isSolanaNetwork,
|
|
26
|
+
parsePaymentRequired
|
|
27
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@blockrun/llm",
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"description": "BlockRun LLM Gateway SDK - Pay-per-request AI via x402 on Base and Solana",
|
|
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
|
+
"types": "./dist/index.d.ts"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist",
|
|
17
|
+
"README.md"
|
|
18
|
+
],
|
|
19
|
+
"scripts": {
|
|
20
|
+
"build": "tsup src/index.ts --format cjs,esm --dts --clean",
|
|
21
|
+
"dev": "tsup src/index.ts --format cjs,esm --dts --watch",
|
|
22
|
+
"test": "vitest",
|
|
23
|
+
"lint": "eslint src/",
|
|
24
|
+
"typecheck": "tsc --noEmit"
|
|
25
|
+
},
|
|
26
|
+
"keywords": [
|
|
27
|
+
"llm",
|
|
28
|
+
"ai",
|
|
29
|
+
"x402",
|
|
30
|
+
"base",
|
|
31
|
+
"solana",
|
|
32
|
+
"usdc",
|
|
33
|
+
"micropayments",
|
|
34
|
+
"openai",
|
|
35
|
+
"claude",
|
|
36
|
+
"gemini",
|
|
37
|
+
"blockchain"
|
|
38
|
+
],
|
|
39
|
+
"author": "BlockRun <hello@blockrun.ai>",
|
|
40
|
+
"license": "MIT",
|
|
41
|
+
"repository": {
|
|
42
|
+
"type": "git",
|
|
43
|
+
"url": "https://github.com/BlockRunAI/blockrun-llm-ts"
|
|
44
|
+
},
|
|
45
|
+
"homepage": "https://blockrun.ai",
|
|
46
|
+
"bugs": {
|
|
47
|
+
"url": "https://github.com/BlockRunAI/blockrun-llm-ts/issues"
|
|
48
|
+
},
|
|
49
|
+
"dependencies": {
|
|
50
|
+
"viem": "^2.21.0"
|
|
51
|
+
},
|
|
52
|
+
"optionalDependencies": {
|
|
53
|
+
"@solana/web3.js": "^1.98.0",
|
|
54
|
+
"@solana/spl-token": "^0.4.0"
|
|
55
|
+
},
|
|
56
|
+
"devDependencies": {
|
|
57
|
+
"@types/node": "^20.0.0",
|
|
58
|
+
"tsup": "^8.0.0",
|
|
59
|
+
"typescript": "^5.0.0",
|
|
60
|
+
"vitest": "^1.0.0"
|
|
61
|
+
},
|
|
62
|
+
"engines": {
|
|
63
|
+
"node": ">=18"
|
|
64
|
+
}
|
|
65
|
+
}
|