@blockrun/llm 1.1.0 → 1.3.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 +162 -2
- package/dist/index.cjs +1251 -109
- package/dist/index.d.cts +472 -4
- package/dist/index.d.ts +472 -4
- package/dist/index.js +1134 -4
- package/package.json +10 -9
package/dist/index.cjs
CHANGED
|
@@ -8185,15 +8185,15 @@ function toFailure(result, context, struct59, value) {
|
|
|
8185
8185
|
} else if (typeof result === "string") {
|
|
8186
8186
|
result = { message: result };
|
|
8187
8187
|
}
|
|
8188
|
-
const { path:
|
|
8188
|
+
const { path: path5, branch } = context;
|
|
8189
8189
|
const { type: type2 } = struct59;
|
|
8190
8190
|
const { refinement, message = `Expected a value of type \`${type2}\`${refinement ? ` with refinement \`${refinement}\`` : ""}, but received: \`${print(value)}\`` } = result;
|
|
8191
8191
|
return {
|
|
8192
8192
|
value,
|
|
8193
8193
|
type: type2,
|
|
8194
8194
|
refinement,
|
|
8195
|
-
key:
|
|
8196
|
-
path:
|
|
8195
|
+
key: path5[path5.length - 1],
|
|
8196
|
+
path: path5,
|
|
8197
8197
|
branch,
|
|
8198
8198
|
...result,
|
|
8199
8199
|
message
|
|
@@ -8211,20 +8211,20 @@ function* toFailures(result, context, struct59, value) {
|
|
|
8211
8211
|
}
|
|
8212
8212
|
}
|
|
8213
8213
|
function* run(value, struct59, options = {}) {
|
|
8214
|
-
const { path:
|
|
8215
|
-
const ctx = { path:
|
|
8214
|
+
const { path: path5 = [], branch = [value], coerce: coerce2 = false, mask: mask2 = false } = options;
|
|
8215
|
+
const ctx = { path: path5, branch, mask: mask2 };
|
|
8216
8216
|
if (coerce2) {
|
|
8217
8217
|
value = struct59.coercer(value, ctx);
|
|
8218
8218
|
}
|
|
8219
|
-
let
|
|
8219
|
+
let status2 = "valid";
|
|
8220
8220
|
for (const failure of struct59.validator(value, ctx)) {
|
|
8221
8221
|
failure.explanation = options.message;
|
|
8222
|
-
|
|
8222
|
+
status2 = "not_valid";
|
|
8223
8223
|
yield [failure, void 0];
|
|
8224
8224
|
}
|
|
8225
8225
|
for (let [k, v, s] of struct59.entries(value, ctx)) {
|
|
8226
8226
|
const ts = run(v, s, {
|
|
8227
|
-
path: k === void 0 ?
|
|
8227
|
+
path: k === void 0 ? path5 : [...path5, k],
|
|
8228
8228
|
branch: k === void 0 ? branch : [...branch, v],
|
|
8229
8229
|
coerce: coerce2,
|
|
8230
8230
|
mask: mask2,
|
|
@@ -8232,7 +8232,7 @@ function* run(value, struct59, options = {}) {
|
|
|
8232
8232
|
});
|
|
8233
8233
|
for (const t of ts) {
|
|
8234
8234
|
if (t[0]) {
|
|
8235
|
-
|
|
8235
|
+
status2 = t[0].refinement != null ? "not_refined" : "not_valid";
|
|
8236
8236
|
yield [t[0], void 0];
|
|
8237
8237
|
} else if (coerce2) {
|
|
8238
8238
|
v = t[1];
|
|
@@ -8249,14 +8249,14 @@ function* run(value, struct59, options = {}) {
|
|
|
8249
8249
|
}
|
|
8250
8250
|
}
|
|
8251
8251
|
}
|
|
8252
|
-
if (
|
|
8252
|
+
if (status2 !== "not_valid") {
|
|
8253
8253
|
for (const failure of struct59.refiner(value, ctx)) {
|
|
8254
8254
|
failure.explanation = options.message;
|
|
8255
|
-
|
|
8255
|
+
status2 = "not_refined";
|
|
8256
8256
|
yield [failure, void 0];
|
|
8257
8257
|
}
|
|
8258
8258
|
}
|
|
8259
|
-
if (
|
|
8259
|
+
if (status2 === "valid") {
|
|
8260
8260
|
yield [void 0, value];
|
|
8261
8261
|
}
|
|
8262
8262
|
}
|
|
@@ -8496,8 +8496,8 @@ var init_dist = __esm({
|
|
|
8496
8496
|
constructor(failure, failures) {
|
|
8497
8497
|
let cached;
|
|
8498
8498
|
const { message, explanation, ...rest } = failure;
|
|
8499
|
-
const { path:
|
|
8500
|
-
const msg =
|
|
8499
|
+
const { path: path5 } = failure;
|
|
8500
|
+
const msg = path5.length === 0 ? message : `At path: ${path5.join(".")} -- ${message}`;
|
|
8501
8501
|
super(explanation ?? msg);
|
|
8502
8502
|
if (explanation != null)
|
|
8503
8503
|
this.cause = msg;
|
|
@@ -9296,8 +9296,8 @@ var require_tr46 = __commonJS({
|
|
|
9296
9296
|
var len = countSymbols(domain_name);
|
|
9297
9297
|
for (var i = 0; i < len; ++i) {
|
|
9298
9298
|
var codePoint = domain_name.codePointAt(i);
|
|
9299
|
-
var
|
|
9300
|
-
switch (
|
|
9299
|
+
var status2 = findStatus(codePoint);
|
|
9300
|
+
switch (status2[1]) {
|
|
9301
9301
|
case "disallowed":
|
|
9302
9302
|
hasError = true;
|
|
9303
9303
|
processed += String.fromCodePoint(codePoint);
|
|
@@ -9305,11 +9305,11 @@ var require_tr46 = __commonJS({
|
|
|
9305
9305
|
case "ignored":
|
|
9306
9306
|
break;
|
|
9307
9307
|
case "mapped":
|
|
9308
|
-
processed += String.fromCodePoint.apply(String,
|
|
9308
|
+
processed += String.fromCodePoint.apply(String, status2[2]);
|
|
9309
9309
|
break;
|
|
9310
9310
|
case "deviation":
|
|
9311
9311
|
if (processing_option === PROCESSING_OPTIONS.TRANSITIONAL) {
|
|
9312
|
-
processed += String.fromCodePoint.apply(String,
|
|
9312
|
+
processed += String.fromCodePoint.apply(String, status2[2]);
|
|
9313
9313
|
} else {
|
|
9314
9314
|
processed += String.fromCodePoint(codePoint);
|
|
9315
9315
|
}
|
|
@@ -9322,7 +9322,7 @@ var require_tr46 = __commonJS({
|
|
|
9322
9322
|
hasError = true;
|
|
9323
9323
|
processed += String.fromCodePoint(codePoint);
|
|
9324
9324
|
} else {
|
|
9325
|
-
processed += String.fromCodePoint.apply(String,
|
|
9325
|
+
processed += String.fromCodePoint.apply(String, status2[2]);
|
|
9326
9326
|
}
|
|
9327
9327
|
break;
|
|
9328
9328
|
case "disallowed_STD3_valid":
|
|
@@ -9350,8 +9350,8 @@ var require_tr46 = __commonJS({
|
|
|
9350
9350
|
}
|
|
9351
9351
|
var len = countSymbols(label);
|
|
9352
9352
|
for (var i = 0; i < len; ++i) {
|
|
9353
|
-
var
|
|
9354
|
-
if (processing === PROCESSING_OPTIONS.TRANSITIONAL &&
|
|
9353
|
+
var status2 = findStatus(label.codePointAt(i));
|
|
9354
|
+
if (processing === PROCESSING_OPTIONS.TRANSITIONAL && status2[1] !== "valid" || processing === PROCESSING_OPTIONS.NONTRANSITIONAL && status2[1] !== "valid" && status2[1] !== "deviation") {
|
|
9355
9355
|
error = true;
|
|
9356
9356
|
break;
|
|
9357
9357
|
}
|
|
@@ -9806,14 +9806,14 @@ var require_url_state_machine = __commonJS({
|
|
|
9806
9806
|
return url2.replace(/\u0009|\u000A|\u000D/g, "");
|
|
9807
9807
|
}
|
|
9808
9808
|
function shortenPath(url2) {
|
|
9809
|
-
const
|
|
9810
|
-
if (
|
|
9809
|
+
const path5 = url2.path;
|
|
9810
|
+
if (path5.length === 0) {
|
|
9811
9811
|
return;
|
|
9812
9812
|
}
|
|
9813
|
-
if (url2.scheme === "file" &&
|
|
9813
|
+
if (url2.scheme === "file" && path5.length === 1 && isNormalizedWindowsDriveLetter(path5[0])) {
|
|
9814
9814
|
return;
|
|
9815
9815
|
}
|
|
9816
|
-
|
|
9816
|
+
path5.pop();
|
|
9817
9817
|
}
|
|
9818
9818
|
function includesCredentials(url2) {
|
|
9819
9819
|
return url2.username !== "" || url2.password !== "";
|
|
@@ -11887,7 +11887,7 @@ var init_lib = __esm({
|
|
|
11887
11887
|
let body = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : null;
|
|
11888
11888
|
let opts = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {};
|
|
11889
11889
|
Body.call(this, body, opts);
|
|
11890
|
-
const
|
|
11890
|
+
const status2 = opts.status || 200;
|
|
11891
11891
|
const headers = new Headers(opts.headers);
|
|
11892
11892
|
if (body != null && !headers.has("Content-Type")) {
|
|
11893
11893
|
const contentType = extractContentType(body);
|
|
@@ -11897,8 +11897,8 @@ var init_lib = __esm({
|
|
|
11897
11897
|
}
|
|
11898
11898
|
this[INTERNALS$1] = {
|
|
11899
11899
|
url: opts.url,
|
|
11900
|
-
status,
|
|
11901
|
-
statusText: opts.statusText || STATUS_CODES[
|
|
11900
|
+
status: status2,
|
|
11901
|
+
statusText: opts.statusText || STATUS_CODES[status2],
|
|
11902
11902
|
headers,
|
|
11903
11903
|
counter: opts.counter
|
|
11904
11904
|
};
|
|
@@ -12098,16 +12098,16 @@ var require_constants = __commonJS({
|
|
|
12098
12098
|
var require_node_gyp_build = __commonJS({
|
|
12099
12099
|
"node_modules/.pnpm/node-gyp-build@4.8.4/node_modules/node-gyp-build/node-gyp-build.js"(exports2, module2) {
|
|
12100
12100
|
"use strict";
|
|
12101
|
-
var
|
|
12102
|
-
var
|
|
12103
|
-
var
|
|
12101
|
+
var fs5 = require("fs");
|
|
12102
|
+
var path5 = require("path");
|
|
12103
|
+
var os5 = require("os");
|
|
12104
12104
|
var runtimeRequire = typeof __webpack_require__ === "function" ? __non_webpack_require__ : require;
|
|
12105
12105
|
var vars = process.config && process.config.variables || {};
|
|
12106
12106
|
var prebuildsOnly = !!process.env.PREBUILDS_ONLY;
|
|
12107
12107
|
var abi = process.versions.modules;
|
|
12108
12108
|
var runtime = isElectron() ? "electron" : isNwjs() ? "node-webkit" : "node";
|
|
12109
|
-
var arch = process.env.npm_config_arch ||
|
|
12110
|
-
var platform = process.env.npm_config_platform ||
|
|
12109
|
+
var arch = process.env.npm_config_arch || os5.arch();
|
|
12110
|
+
var platform = process.env.npm_config_platform || os5.platform();
|
|
12111
12111
|
var libc = process.env.LIBC || (isAlpine(platform) ? "musl" : "glibc");
|
|
12112
12112
|
var armv = process.env.ARM_VERSION || (arch === "arm64" ? "8" : vars.arm_version) || "";
|
|
12113
12113
|
var uv = (process.versions.uv || "").split(".")[0];
|
|
@@ -12116,21 +12116,21 @@ var require_node_gyp_build = __commonJS({
|
|
|
12116
12116
|
return runtimeRequire(load.resolve(dir));
|
|
12117
12117
|
}
|
|
12118
12118
|
load.resolve = load.path = function(dir) {
|
|
12119
|
-
dir =
|
|
12119
|
+
dir = path5.resolve(dir || ".");
|
|
12120
12120
|
try {
|
|
12121
|
-
var name = runtimeRequire(
|
|
12121
|
+
var name = runtimeRequire(path5.join(dir, "package.json")).name.toUpperCase().replace(/-/g, "_");
|
|
12122
12122
|
if (process.env[name + "_PREBUILD"]) dir = process.env[name + "_PREBUILD"];
|
|
12123
12123
|
} catch (err) {
|
|
12124
12124
|
}
|
|
12125
12125
|
if (!prebuildsOnly) {
|
|
12126
|
-
var release = getFirst(
|
|
12126
|
+
var release = getFirst(path5.join(dir, "build/Release"), matchBuild);
|
|
12127
12127
|
if (release) return release;
|
|
12128
|
-
var debug = getFirst(
|
|
12128
|
+
var debug = getFirst(path5.join(dir, "build/Debug"), matchBuild);
|
|
12129
12129
|
if (debug) return debug;
|
|
12130
12130
|
}
|
|
12131
12131
|
var prebuild = resolve(dir);
|
|
12132
12132
|
if (prebuild) return prebuild;
|
|
12133
|
-
var nearby = resolve(
|
|
12133
|
+
var nearby = resolve(path5.dirname(process.execPath));
|
|
12134
12134
|
if (nearby) return nearby;
|
|
12135
12135
|
var target = [
|
|
12136
12136
|
"platform=" + platform,
|
|
@@ -12147,26 +12147,26 @@ var require_node_gyp_build = __commonJS({
|
|
|
12147
12147
|
].filter(Boolean).join(" ");
|
|
12148
12148
|
throw new Error("No native build was found for " + target + "\n loaded from: " + dir + "\n");
|
|
12149
12149
|
function resolve(dir2) {
|
|
12150
|
-
var tuples =
|
|
12150
|
+
var tuples = readdirSync4(path5.join(dir2, "prebuilds")).map(parseTuple);
|
|
12151
12151
|
var tuple2 = tuples.filter(matchTuple(platform, arch)).sort(compareTuples)[0];
|
|
12152
12152
|
if (!tuple2) return;
|
|
12153
|
-
var prebuilds =
|
|
12154
|
-
var parsed =
|
|
12153
|
+
var prebuilds = path5.join(dir2, "prebuilds", tuple2.name);
|
|
12154
|
+
var parsed = readdirSync4(prebuilds).map(parseTags);
|
|
12155
12155
|
var candidates = parsed.filter(matchTags(runtime, abi));
|
|
12156
12156
|
var winner = candidates.sort(compareTags(runtime))[0];
|
|
12157
|
-
if (winner) return
|
|
12157
|
+
if (winner) return path5.join(prebuilds, winner.file);
|
|
12158
12158
|
}
|
|
12159
12159
|
};
|
|
12160
|
-
function
|
|
12160
|
+
function readdirSync4(dir) {
|
|
12161
12161
|
try {
|
|
12162
|
-
return
|
|
12162
|
+
return fs5.readdirSync(dir);
|
|
12163
12163
|
} catch (err) {
|
|
12164
12164
|
return [];
|
|
12165
12165
|
}
|
|
12166
12166
|
}
|
|
12167
12167
|
function getFirst(dir, filter) {
|
|
12168
|
-
var files =
|
|
12169
|
-
return files[0] &&
|
|
12168
|
+
var files = readdirSync4(dir).filter(filter);
|
|
12169
|
+
return files[0] && path5.join(dir, files[0]);
|
|
12170
12170
|
}
|
|
12171
12171
|
function matchBuild(name) {
|
|
12172
12172
|
return /\.node$/.test(name);
|
|
@@ -12253,7 +12253,7 @@ var require_node_gyp_build = __commonJS({
|
|
|
12253
12253
|
return typeof window !== "undefined" && window.process && window.process.type === "renderer";
|
|
12254
12254
|
}
|
|
12255
12255
|
function isAlpine(platform2) {
|
|
12256
|
-
return platform2 === "linux" &&
|
|
12256
|
+
return platform2 === "linux" && fs5.existsSync("/etc/alpine-release");
|
|
12257
12257
|
}
|
|
12258
12258
|
load.parseTags = parseTags;
|
|
12259
12259
|
load.matchTags = matchTags;
|
|
@@ -14537,7 +14537,7 @@ var require_websocket = __commonJS({
|
|
|
14537
14537
|
var http2 = require("http");
|
|
14538
14538
|
var net = require("net");
|
|
14539
14539
|
var tls = require("tls");
|
|
14540
|
-
var { randomBytes: randomBytes2, createHash } = require("crypto");
|
|
14540
|
+
var { randomBytes: randomBytes2, createHash: createHash2 } = require("crypto");
|
|
14541
14541
|
var { Duplex, Readable: Readable2 } = require("stream");
|
|
14542
14542
|
var { URL: URL4 } = require("url");
|
|
14543
14543
|
var PerMessageDeflate = require_permessage_deflate();
|
|
@@ -15197,7 +15197,7 @@ var require_websocket = __commonJS({
|
|
|
15197
15197
|
abortHandshake(websocket, socket, "Invalid Upgrade header");
|
|
15198
15198
|
return;
|
|
15199
15199
|
}
|
|
15200
|
-
const digest =
|
|
15200
|
+
const digest = createHash2("sha1").update(key + GUID).digest("base64");
|
|
15201
15201
|
if (res.headers["sec-websocket-accept"] !== digest) {
|
|
15202
15202
|
abortHandshake(websocket, socket, "Invalid Sec-WebSocket-Accept header");
|
|
15203
15203
|
return;
|
|
@@ -15564,7 +15564,7 @@ var require_websocket_server = __commonJS({
|
|
|
15564
15564
|
var EventEmitter2 = require("events");
|
|
15565
15565
|
var http2 = require("http");
|
|
15566
15566
|
var { Duplex } = require("stream");
|
|
15567
|
-
var { createHash } = require("crypto");
|
|
15567
|
+
var { createHash: createHash2 } = require("crypto");
|
|
15568
15568
|
var extension = require_extension();
|
|
15569
15569
|
var PerMessageDeflate = require_permessage_deflate();
|
|
15570
15570
|
var subprotocol = require_subprotocol();
|
|
@@ -15865,7 +15865,7 @@ var require_websocket_server = __commonJS({
|
|
|
15865
15865
|
);
|
|
15866
15866
|
}
|
|
15867
15867
|
if (this._state > RUNNING) return abortHandshake(socket, 503);
|
|
15868
|
-
const digest =
|
|
15868
|
+
const digest = createHash2("sha1").update(key + GUID).digest("base64");
|
|
15869
15869
|
const headers = [
|
|
15870
15870
|
"HTTP/1.1 101 Switching Protocols",
|
|
15871
15871
|
"Upgrade: websocket",
|
|
@@ -18001,9 +18001,9 @@ async function sendAndConfirmTransaction(connection, transaction, signers, optio
|
|
|
18001
18001
|
minContextSlot: options.minContextSlot
|
|
18002
18002
|
};
|
|
18003
18003
|
const signature2 = await connection.sendTransaction(transaction, signers, sendOptions);
|
|
18004
|
-
let
|
|
18004
|
+
let status2;
|
|
18005
18005
|
if (transaction.recentBlockhash != null && transaction.lastValidBlockHeight != null) {
|
|
18006
|
-
|
|
18006
|
+
status2 = (await connection.confirmTransaction({
|
|
18007
18007
|
abortSignal: options?.abortSignal,
|
|
18008
18008
|
signature: signature2,
|
|
18009
18009
|
blockhash: transaction.recentBlockhash,
|
|
@@ -18014,7 +18014,7 @@ async function sendAndConfirmTransaction(connection, transaction, signers, optio
|
|
|
18014
18014
|
nonceInstruction
|
|
18015
18015
|
} = transaction.nonceInfo;
|
|
18016
18016
|
const nonceAccountPubkey = nonceInstruction.keys[0].pubkey;
|
|
18017
|
-
|
|
18017
|
+
status2 = (await connection.confirmTransaction({
|
|
18018
18018
|
abortSignal: options?.abortSignal,
|
|
18019
18019
|
minContextSlot: transaction.minNonceContextSlot,
|
|
18020
18020
|
nonceAccountPubkey,
|
|
@@ -18025,17 +18025,17 @@ async function sendAndConfirmTransaction(connection, transaction, signers, optio
|
|
|
18025
18025
|
if (options?.abortSignal != null) {
|
|
18026
18026
|
console.warn("sendAndConfirmTransaction(): A transaction with a deprecated confirmation strategy was supplied along with an `abortSignal`. Only transactions having `lastValidBlockHeight` or a combination of `nonceInfo` and `minNonceContextSlot` are abortable.");
|
|
18027
18027
|
}
|
|
18028
|
-
|
|
18028
|
+
status2 = (await connection.confirmTransaction(signature2, options && options.commitment)).value;
|
|
18029
18029
|
}
|
|
18030
|
-
if (
|
|
18030
|
+
if (status2.err) {
|
|
18031
18031
|
if (signature2 != null) {
|
|
18032
18032
|
throw new SendTransactionError({
|
|
18033
18033
|
action: "send",
|
|
18034
18034
|
signature: signature2,
|
|
18035
|
-
transactionMessage: `Status: (${JSON.stringify(
|
|
18035
|
+
transactionMessage: `Status: (${JSON.stringify(status2)})`
|
|
18036
18036
|
});
|
|
18037
18037
|
}
|
|
18038
|
-
throw new Error(`Transaction ${signature2} failed (${JSON.stringify(
|
|
18038
|
+
throw new Error(`Transaction ${signature2} failed (${JSON.stringify(status2)})`);
|
|
18039
18039
|
}
|
|
18040
18040
|
return signature2;
|
|
18041
18041
|
}
|
|
@@ -19011,16 +19011,16 @@ async function sendAndConfirmRawTransaction(connection, rawTransaction, confirma
|
|
|
19011
19011
|
const signature2 = await connection.sendRawTransaction(rawTransaction, sendOptions);
|
|
19012
19012
|
const commitment = options && options.commitment;
|
|
19013
19013
|
const confirmationPromise = confirmationStrategy ? connection.confirmTransaction(confirmationStrategy, commitment) : connection.confirmTransaction(signature2, commitment);
|
|
19014
|
-
const
|
|
19015
|
-
if (
|
|
19014
|
+
const status2 = (await confirmationPromise).value;
|
|
19015
|
+
if (status2.err) {
|
|
19016
19016
|
if (signature2 != null) {
|
|
19017
19017
|
throw new SendTransactionError({
|
|
19018
19018
|
action: sendOptions?.skipPreflight ? "send" : "simulate",
|
|
19019
19019
|
signature: signature2,
|
|
19020
|
-
transactionMessage: `Status: (${JSON.stringify(
|
|
19020
|
+
transactionMessage: `Status: (${JSON.stringify(status2)})`
|
|
19021
19021
|
});
|
|
19022
19022
|
}
|
|
19023
|
-
throw new Error(`Raw transaction ${signature2} failed (${JSON.stringify(
|
|
19023
|
+
throw new Error(`Raw transaction ${signature2} failed (${JSON.stringify(status2)})`);
|
|
19024
19024
|
}
|
|
19025
19025
|
return signature2;
|
|
19026
19026
|
}
|
|
@@ -23087,15 +23087,15 @@ Message: ${transactionMessage}.
|
|
|
23087
23087
|
} else {
|
|
23088
23088
|
let signatureStatus;
|
|
23089
23089
|
while (true) {
|
|
23090
|
-
const
|
|
23091
|
-
if (
|
|
23090
|
+
const status2 = await this.getSignatureStatus(signature2);
|
|
23091
|
+
if (status2 == null) {
|
|
23092
23092
|
break;
|
|
23093
23093
|
}
|
|
23094
|
-
if (
|
|
23094
|
+
if (status2.context.slot < (outcome.slotInWhichNonceDidAdvance ?? minContextSlot)) {
|
|
23095
23095
|
await sleep(400);
|
|
23096
23096
|
continue;
|
|
23097
23097
|
}
|
|
23098
|
-
signatureStatus =
|
|
23098
|
+
signatureStatus = status2;
|
|
23099
23099
|
break;
|
|
23100
23100
|
}
|
|
23101
23101
|
if (signatureStatus?.value) {
|
|
@@ -27011,20 +27011,20 @@ var require_file_uri_to_path = __commonJS({
|
|
|
27011
27011
|
var rest = decodeURI(uri.substring(7));
|
|
27012
27012
|
var firstSlash = rest.indexOf("/");
|
|
27013
27013
|
var host = rest.substring(0, firstSlash);
|
|
27014
|
-
var
|
|
27014
|
+
var path5 = rest.substring(firstSlash + 1);
|
|
27015
27015
|
if ("localhost" == host) host = "";
|
|
27016
27016
|
if (host) {
|
|
27017
27017
|
host = sep + sep + host;
|
|
27018
27018
|
}
|
|
27019
|
-
|
|
27019
|
+
path5 = path5.replace(/^(.+)\|/, "$1:");
|
|
27020
27020
|
if (sep == "\\") {
|
|
27021
|
-
|
|
27021
|
+
path5 = path5.replace(/\//g, "\\");
|
|
27022
27022
|
}
|
|
27023
|
-
if (/^.+\:/.test(
|
|
27023
|
+
if (/^.+\:/.test(path5)) {
|
|
27024
27024
|
} else {
|
|
27025
|
-
|
|
27025
|
+
path5 = sep + path5;
|
|
27026
27026
|
}
|
|
27027
|
-
return host +
|
|
27027
|
+
return host + path5;
|
|
27028
27028
|
}
|
|
27029
27029
|
}
|
|
27030
27030
|
});
|
|
@@ -27033,19 +27033,19 @@ var require_file_uri_to_path = __commonJS({
|
|
|
27033
27033
|
var require_bindings = __commonJS({
|
|
27034
27034
|
"node_modules/.pnpm/bindings@1.5.0/node_modules/bindings/bindings.js"(exports2, module2) {
|
|
27035
27035
|
"use strict";
|
|
27036
|
-
var
|
|
27037
|
-
var
|
|
27036
|
+
var fs5 = require("fs");
|
|
27037
|
+
var path5 = require("path");
|
|
27038
27038
|
var fileURLToPath = require_file_uri_to_path();
|
|
27039
|
-
var
|
|
27040
|
-
var dirname =
|
|
27041
|
-
var exists =
|
|
27039
|
+
var join5 = path5.join;
|
|
27040
|
+
var dirname = path5.dirname;
|
|
27041
|
+
var exists = fs5.accessSync && function(path6) {
|
|
27042
27042
|
try {
|
|
27043
|
-
|
|
27043
|
+
fs5.accessSync(path6);
|
|
27044
27044
|
} catch (e2) {
|
|
27045
27045
|
return false;
|
|
27046
27046
|
}
|
|
27047
27047
|
return true;
|
|
27048
|
-
} ||
|
|
27048
|
+
} || fs5.existsSync || path5.existsSync;
|
|
27049
27049
|
var defaults = {
|
|
27050
27050
|
arrow: process.env.NODE_BINDINGS_ARROW || " \u2192 ",
|
|
27051
27051
|
compiled: process.env.NODE_BINDINGS_COMPILED_DIR || "compiled",
|
|
@@ -27090,13 +27090,13 @@ var require_bindings = __commonJS({
|
|
|
27090
27090
|
if (!opts.module_root) {
|
|
27091
27091
|
opts.module_root = exports2.getRoot(exports2.getFileName());
|
|
27092
27092
|
}
|
|
27093
|
-
if (
|
|
27093
|
+
if (path5.extname(opts.bindings) != ".node") {
|
|
27094
27094
|
opts.bindings += ".node";
|
|
27095
27095
|
}
|
|
27096
27096
|
var requireFunc = typeof __webpack_require__ === "function" ? __non_webpack_require__ : require;
|
|
27097
27097
|
var tries = [], i = 0, l = opts.try.length, n, b, err;
|
|
27098
27098
|
for (; i < l; i++) {
|
|
27099
|
-
n =
|
|
27099
|
+
n = join5.apply(
|
|
27100
27100
|
null,
|
|
27101
27101
|
opts.try[i].map(function(p) {
|
|
27102
27102
|
return opts[p] || p;
|
|
@@ -27157,7 +27157,7 @@ var require_bindings = __commonJS({
|
|
|
27157
27157
|
if (dir === ".") {
|
|
27158
27158
|
dir = process.cwd();
|
|
27159
27159
|
}
|
|
27160
|
-
if (exists(
|
|
27160
|
+
if (exists(join5(dir, "package.json")) || exists(join5(dir, "node_modules"))) {
|
|
27161
27161
|
return dir;
|
|
27162
27162
|
}
|
|
27163
27163
|
if (prev === dir) {
|
|
@@ -27166,7 +27166,7 @@ var require_bindings = __commonJS({
|
|
|
27166
27166
|
);
|
|
27167
27167
|
}
|
|
27168
27168
|
prev = dir;
|
|
27169
|
-
dir =
|
|
27169
|
+
dir = join5(dir, "..");
|
|
27170
27170
|
}
|
|
27171
27171
|
};
|
|
27172
27172
|
}
|
|
@@ -36434,6 +36434,7 @@ __export(index_exports, {
|
|
|
36434
36434
|
USDC_SOLANA: () => USDC_SOLANA,
|
|
36435
36435
|
WALLET_DIR_PATH: () => WALLET_DIR_PATH,
|
|
36436
36436
|
WALLET_FILE_PATH: () => WALLET_FILE_PATH,
|
|
36437
|
+
clearCache: () => clearCache,
|
|
36437
36438
|
createSolanaPaymentPayload: () => createSolanaPaymentPayload,
|
|
36438
36439
|
createSolanaWallet: () => createSolanaWallet,
|
|
36439
36440
|
createWallet: () => createWallet,
|
|
@@ -36441,6 +36442,9 @@ __export(index_exports, {
|
|
|
36441
36442
|
formatFundingMessageCompact: () => formatFundingMessageCompact,
|
|
36442
36443
|
formatNeedsFundingMessage: () => formatNeedsFundingMessage,
|
|
36443
36444
|
formatWalletCreatedMessage: () => formatWalletCreatedMessage,
|
|
36445
|
+
getCached: () => getCached,
|
|
36446
|
+
getCachedByRequest: () => getCachedByRequest,
|
|
36447
|
+
getCostSummary: () => getCostSummary,
|
|
36444
36448
|
getEip681Uri: () => getEip681Uri,
|
|
36445
36449
|
getOrCreateSolanaWallet: () => getOrCreateSolanaWallet,
|
|
36446
36450
|
getOrCreateWallet: () => getOrCreateWallet,
|
|
@@ -36448,11 +36452,19 @@ __export(index_exports, {
|
|
|
36448
36452
|
getWalletAddress: () => getWalletAddress,
|
|
36449
36453
|
loadSolanaWallet: () => loadSolanaWallet,
|
|
36450
36454
|
loadWallet: () => loadWallet,
|
|
36455
|
+
logCost: () => logCost,
|
|
36451
36456
|
saveSolanaWallet: () => saveSolanaWallet,
|
|
36457
|
+
saveToCache: () => saveToCache,
|
|
36452
36458
|
saveWallet: () => saveWallet,
|
|
36459
|
+
scanSolanaWallets: () => scanSolanaWallets,
|
|
36460
|
+
scanWallets: () => scanWallets,
|
|
36461
|
+
setCache: () => setCache,
|
|
36462
|
+
setupAgentSolanaWallet: () => setupAgentSolanaWallet,
|
|
36463
|
+
setupAgentWallet: () => setupAgentWallet,
|
|
36453
36464
|
solanaClient: () => solanaClient,
|
|
36454
36465
|
solanaKeyToBytes: () => solanaKeyToBytes,
|
|
36455
36466
|
solanaPublicKey: () => solanaPublicKey,
|
|
36467
|
+
status: () => status,
|
|
36456
36468
|
testnetClient: () => testnetClient
|
|
36457
36469
|
});
|
|
36458
36470
|
module.exports = __toCommonJS(index_exports);
|
|
@@ -37025,6 +37037,200 @@ var LLMClient = class {
|
|
|
37025
37037
|
this.sessionTotalUsd += costUsd;
|
|
37026
37038
|
return retryResponse.json();
|
|
37027
37039
|
}
|
|
37040
|
+
/**
|
|
37041
|
+
* Make a request with automatic x402 payment handling, returning raw JSON.
|
|
37042
|
+
* Used for non-ChatResponse endpoints (X/Twitter, search, image edit, etc.).
|
|
37043
|
+
*/
|
|
37044
|
+
async requestWithPaymentRaw(endpoint2, body) {
|
|
37045
|
+
const url2 = `${this.apiUrl}${endpoint2}`;
|
|
37046
|
+
const response = await this.fetchWithTimeout(url2, {
|
|
37047
|
+
method: "POST",
|
|
37048
|
+
headers: { "Content-Type": "application/json", "User-Agent": USER_AGENT },
|
|
37049
|
+
body: JSON.stringify(body)
|
|
37050
|
+
});
|
|
37051
|
+
if (response.status === 402) {
|
|
37052
|
+
return this.handlePaymentAndRetryRaw(url2, body, response);
|
|
37053
|
+
}
|
|
37054
|
+
if (!response.ok) {
|
|
37055
|
+
let errorBody;
|
|
37056
|
+
try {
|
|
37057
|
+
errorBody = await response.json();
|
|
37058
|
+
} catch {
|
|
37059
|
+
errorBody = { error: "Request failed" };
|
|
37060
|
+
}
|
|
37061
|
+
throw new APIError(
|
|
37062
|
+
`API error: ${response.status}`,
|
|
37063
|
+
response.status,
|
|
37064
|
+
sanitizeErrorResponse(errorBody)
|
|
37065
|
+
);
|
|
37066
|
+
}
|
|
37067
|
+
return response.json();
|
|
37068
|
+
}
|
|
37069
|
+
/**
|
|
37070
|
+
* Handle 402 response for raw endpoints: parse requirements, sign payment, retry.
|
|
37071
|
+
*/
|
|
37072
|
+
async handlePaymentAndRetryRaw(url2, body, response) {
|
|
37073
|
+
let paymentHeader = response.headers.get("payment-required");
|
|
37074
|
+
if (!paymentHeader) {
|
|
37075
|
+
try {
|
|
37076
|
+
const respBody = await response.json();
|
|
37077
|
+
if (respBody.x402 || respBody.accepts) {
|
|
37078
|
+
paymentHeader = btoa(JSON.stringify(respBody));
|
|
37079
|
+
}
|
|
37080
|
+
} catch {
|
|
37081
|
+
console.debug("Failed to parse payment header from response body");
|
|
37082
|
+
}
|
|
37083
|
+
}
|
|
37084
|
+
if (!paymentHeader) {
|
|
37085
|
+
throw new PaymentError("402 response but no payment requirements found");
|
|
37086
|
+
}
|
|
37087
|
+
const paymentRequired = parsePaymentRequired(paymentHeader);
|
|
37088
|
+
const details = extractPaymentDetails(paymentRequired);
|
|
37089
|
+
const extensions = paymentRequired.extensions;
|
|
37090
|
+
const paymentPayload = await createPaymentPayload(
|
|
37091
|
+
this.privateKey,
|
|
37092
|
+
this.account.address,
|
|
37093
|
+
details.recipient,
|
|
37094
|
+
details.amount,
|
|
37095
|
+
details.network || "eip155:8453",
|
|
37096
|
+
{
|
|
37097
|
+
resourceUrl: validateResourceUrl(
|
|
37098
|
+
details.resource?.url || url2,
|
|
37099
|
+
this.apiUrl
|
|
37100
|
+
),
|
|
37101
|
+
resourceDescription: details.resource?.description || "BlockRun AI API call",
|
|
37102
|
+
maxTimeoutSeconds: details.maxTimeoutSeconds || 300,
|
|
37103
|
+
extra: details.extra,
|
|
37104
|
+
extensions
|
|
37105
|
+
}
|
|
37106
|
+
);
|
|
37107
|
+
const retryResponse = await this.fetchWithTimeout(url2, {
|
|
37108
|
+
method: "POST",
|
|
37109
|
+
headers: {
|
|
37110
|
+
"Content-Type": "application/json",
|
|
37111
|
+
"User-Agent": USER_AGENT,
|
|
37112
|
+
"PAYMENT-SIGNATURE": paymentPayload
|
|
37113
|
+
},
|
|
37114
|
+
body: JSON.stringify(body)
|
|
37115
|
+
});
|
|
37116
|
+
if (retryResponse.status === 402) {
|
|
37117
|
+
throw new PaymentError("Payment was rejected. Check your wallet balance.");
|
|
37118
|
+
}
|
|
37119
|
+
if (!retryResponse.ok) {
|
|
37120
|
+
let errorBody;
|
|
37121
|
+
try {
|
|
37122
|
+
errorBody = await retryResponse.json();
|
|
37123
|
+
} catch {
|
|
37124
|
+
errorBody = { error: "Request failed" };
|
|
37125
|
+
}
|
|
37126
|
+
throw new APIError(
|
|
37127
|
+
`API error after payment: ${retryResponse.status}`,
|
|
37128
|
+
retryResponse.status,
|
|
37129
|
+
sanitizeErrorResponse(errorBody)
|
|
37130
|
+
);
|
|
37131
|
+
}
|
|
37132
|
+
const costUsd = parseFloat(details.amount) / 1e6;
|
|
37133
|
+
this.sessionCalls += 1;
|
|
37134
|
+
this.sessionTotalUsd += costUsd;
|
|
37135
|
+
return retryResponse.json();
|
|
37136
|
+
}
|
|
37137
|
+
/**
|
|
37138
|
+
* GET with automatic x402 payment handling, returning raw JSON.
|
|
37139
|
+
* Used for Predexon prediction market endpoints that use GET + query params.
|
|
37140
|
+
*/
|
|
37141
|
+
async getWithPaymentRaw(endpoint2, params) {
|
|
37142
|
+
const query = params ? "?" + new URLSearchParams(params).toString() : "";
|
|
37143
|
+
const url2 = `${this.apiUrl}${endpoint2}${query}`;
|
|
37144
|
+
const response = await this.fetchWithTimeout(url2, {
|
|
37145
|
+
method: "GET",
|
|
37146
|
+
headers: { "User-Agent": USER_AGENT }
|
|
37147
|
+
});
|
|
37148
|
+
if (response.status === 402) {
|
|
37149
|
+
return this.handleGetPaymentAndRetryRaw(url2, endpoint2, params, response);
|
|
37150
|
+
}
|
|
37151
|
+
if (!response.ok) {
|
|
37152
|
+
let errorBody;
|
|
37153
|
+
try {
|
|
37154
|
+
errorBody = await response.json();
|
|
37155
|
+
} catch {
|
|
37156
|
+
errorBody = { error: "Request failed" };
|
|
37157
|
+
}
|
|
37158
|
+
throw new APIError(
|
|
37159
|
+
`API error: ${response.status}`,
|
|
37160
|
+
response.status,
|
|
37161
|
+
sanitizeErrorResponse(errorBody)
|
|
37162
|
+
);
|
|
37163
|
+
}
|
|
37164
|
+
return response.json();
|
|
37165
|
+
}
|
|
37166
|
+
/**
|
|
37167
|
+
* Handle 402 response for GET endpoints: parse requirements, sign payment, retry with GET.
|
|
37168
|
+
*/
|
|
37169
|
+
async handleGetPaymentAndRetryRaw(url2, endpoint2, params, response) {
|
|
37170
|
+
let paymentHeader = response.headers.get("payment-required");
|
|
37171
|
+
if (!paymentHeader) {
|
|
37172
|
+
try {
|
|
37173
|
+
const respBody = await response.json();
|
|
37174
|
+
if (respBody.x402 || respBody.accepts) {
|
|
37175
|
+
paymentHeader = btoa(JSON.stringify(respBody));
|
|
37176
|
+
}
|
|
37177
|
+
} catch {
|
|
37178
|
+
console.debug("Failed to parse payment header from response body");
|
|
37179
|
+
}
|
|
37180
|
+
}
|
|
37181
|
+
if (!paymentHeader) {
|
|
37182
|
+
throw new PaymentError("402 response but no payment requirements found");
|
|
37183
|
+
}
|
|
37184
|
+
const paymentRequired = parsePaymentRequired(paymentHeader);
|
|
37185
|
+
const details = extractPaymentDetails(paymentRequired);
|
|
37186
|
+
const extensions = paymentRequired.extensions;
|
|
37187
|
+
const paymentPayload = await createPaymentPayload(
|
|
37188
|
+
this.privateKey,
|
|
37189
|
+
this.account.address,
|
|
37190
|
+
details.recipient,
|
|
37191
|
+
details.amount,
|
|
37192
|
+
details.network || "eip155:8453",
|
|
37193
|
+
{
|
|
37194
|
+
resourceUrl: validateResourceUrl(
|
|
37195
|
+
details.resource?.url || url2,
|
|
37196
|
+
this.apiUrl
|
|
37197
|
+
),
|
|
37198
|
+
resourceDescription: details.resource?.description || "BlockRun AI API call",
|
|
37199
|
+
maxTimeoutSeconds: details.maxTimeoutSeconds || 300,
|
|
37200
|
+
extra: details.extra,
|
|
37201
|
+
extensions
|
|
37202
|
+
}
|
|
37203
|
+
);
|
|
37204
|
+
const query = params ? "?" + new URLSearchParams(params).toString() : "";
|
|
37205
|
+
const retryUrl = `${this.apiUrl}${endpoint2}${query}`;
|
|
37206
|
+
const retryResponse = await this.fetchWithTimeout(retryUrl, {
|
|
37207
|
+
method: "GET",
|
|
37208
|
+
headers: {
|
|
37209
|
+
"User-Agent": USER_AGENT,
|
|
37210
|
+
"PAYMENT-SIGNATURE": paymentPayload
|
|
37211
|
+
}
|
|
37212
|
+
});
|
|
37213
|
+
if (retryResponse.status === 402) {
|
|
37214
|
+
throw new PaymentError("Payment was rejected. Check your wallet balance.");
|
|
37215
|
+
}
|
|
37216
|
+
if (!retryResponse.ok) {
|
|
37217
|
+
let errorBody;
|
|
37218
|
+
try {
|
|
37219
|
+
errorBody = await retryResponse.json();
|
|
37220
|
+
} catch {
|
|
37221
|
+
errorBody = { error: "Request failed" };
|
|
37222
|
+
}
|
|
37223
|
+
throw new APIError(
|
|
37224
|
+
`API error after payment: ${retryResponse.status}`,
|
|
37225
|
+
retryResponse.status,
|
|
37226
|
+
sanitizeErrorResponse(errorBody)
|
|
37227
|
+
);
|
|
37228
|
+
}
|
|
37229
|
+
const costUsd = parseFloat(details.amount) / 1e6;
|
|
37230
|
+
this.sessionCalls += 1;
|
|
37231
|
+
this.sessionTotalUsd += costUsd;
|
|
37232
|
+
return retryResponse.json();
|
|
37233
|
+
}
|
|
37028
37234
|
/**
|
|
37029
37235
|
* Fetch with timeout.
|
|
37030
37236
|
*/
|
|
@@ -37107,6 +37313,317 @@ var LLMClient = class {
|
|
|
37107
37313
|
}
|
|
37108
37314
|
return [...llmModels, ...imageModels];
|
|
37109
37315
|
}
|
|
37316
|
+
/**
|
|
37317
|
+
* Edit an image using img2img.
|
|
37318
|
+
*
|
|
37319
|
+
* @param prompt - Text description of the desired edit
|
|
37320
|
+
* @param image - Base64-encoded image or URL of the source image
|
|
37321
|
+
* @param options - Optional edit parameters
|
|
37322
|
+
* @returns ImageResponse with edited image URLs
|
|
37323
|
+
*/
|
|
37324
|
+
async imageEdit(prompt, image, options) {
|
|
37325
|
+
const body = {
|
|
37326
|
+
model: options?.model || "openai/gpt-image-1",
|
|
37327
|
+
prompt,
|
|
37328
|
+
image,
|
|
37329
|
+
size: options?.size || "1024x1024",
|
|
37330
|
+
n: options?.n || 1
|
|
37331
|
+
};
|
|
37332
|
+
if (options?.mask !== void 0) {
|
|
37333
|
+
body.mask = options.mask;
|
|
37334
|
+
}
|
|
37335
|
+
const data = await this.requestWithPaymentRaw("/v1/images/image2image", body);
|
|
37336
|
+
return data;
|
|
37337
|
+
}
|
|
37338
|
+
/**
|
|
37339
|
+
* Standalone search (web, X/Twitter, news).
|
|
37340
|
+
*
|
|
37341
|
+
* @param query - Search query
|
|
37342
|
+
* @param options - Optional search parameters
|
|
37343
|
+
* @returns SearchResult with summary and citations
|
|
37344
|
+
*/
|
|
37345
|
+
async search(query, options) {
|
|
37346
|
+
const body = {
|
|
37347
|
+
query,
|
|
37348
|
+
max_results: options?.maxResults || 10
|
|
37349
|
+
};
|
|
37350
|
+
if (options?.sources !== void 0) body.sources = options.sources;
|
|
37351
|
+
if (options?.fromDate !== void 0) body.from_date = options.fromDate;
|
|
37352
|
+
if (options?.toDate !== void 0) body.to_date = options.toDate;
|
|
37353
|
+
const data = await this.requestWithPaymentRaw("/v1/search", body);
|
|
37354
|
+
return data;
|
|
37355
|
+
}
|
|
37356
|
+
/**
|
|
37357
|
+
* Get USDC balance on Base network.
|
|
37358
|
+
*
|
|
37359
|
+
* Automatically detects mainnet vs testnet based on API URL.
|
|
37360
|
+
*
|
|
37361
|
+
* @returns USDC balance as a float (6 decimal places normalized)
|
|
37362
|
+
*
|
|
37363
|
+
* @example
|
|
37364
|
+
* const balance = await client.getBalance();
|
|
37365
|
+
* console.log(`Balance: $${balance.toFixed(2)} USDC`);
|
|
37366
|
+
*/
|
|
37367
|
+
async getBalance() {
|
|
37368
|
+
const isTestnet = this.isTestnet();
|
|
37369
|
+
const usdcContract = isTestnet ? "0x036CbD53842c5426634e7929541eC2318f3dCF7e" : "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913";
|
|
37370
|
+
const rpcs = isTestnet ? ["https://sepolia.base.org", "https://base-sepolia-rpc.publicnode.com"] : ["https://base.publicnode.com", "https://mainnet.base.org", "https://base.meowrpc.com"];
|
|
37371
|
+
const selector = "0x70a08231";
|
|
37372
|
+
const paddedAddress = this.account.address.slice(2).toLowerCase().padStart(64, "0");
|
|
37373
|
+
const data = selector + paddedAddress;
|
|
37374
|
+
const payload = {
|
|
37375
|
+
jsonrpc: "2.0",
|
|
37376
|
+
method: "eth_call",
|
|
37377
|
+
params: [{ to: usdcContract, data }, "latest"],
|
|
37378
|
+
id: 1
|
|
37379
|
+
};
|
|
37380
|
+
let lastError;
|
|
37381
|
+
for (const rpc of rpcs) {
|
|
37382
|
+
try {
|
|
37383
|
+
const response = await fetch(rpc, {
|
|
37384
|
+
method: "POST",
|
|
37385
|
+
headers: { "Content-Type": "application/json" },
|
|
37386
|
+
body: JSON.stringify(payload)
|
|
37387
|
+
});
|
|
37388
|
+
const result = await response.json();
|
|
37389
|
+
const balanceRaw = parseInt(result.result || "0x0", 16);
|
|
37390
|
+
return balanceRaw / 1e6;
|
|
37391
|
+
} catch (e2) {
|
|
37392
|
+
lastError = e2;
|
|
37393
|
+
}
|
|
37394
|
+
}
|
|
37395
|
+
throw lastError || new Error("All RPCs failed");
|
|
37396
|
+
}
|
|
37397
|
+
// ============================================================
|
|
37398
|
+
// X/Twitter endpoints (powered by AttentionVC)
|
|
37399
|
+
// ============================================================
|
|
37400
|
+
/**
|
|
37401
|
+
* Look up X/Twitter user profiles by username.
|
|
37402
|
+
*
|
|
37403
|
+
* Powered by AttentionVC. $0.002 per user (min $0.02, max $0.20).
|
|
37404
|
+
*
|
|
37405
|
+
* @param usernames - Single username or array of usernames (without @)
|
|
37406
|
+
*/
|
|
37407
|
+
async xUserLookup(usernames) {
|
|
37408
|
+
const names = Array.isArray(usernames) ? usernames : [usernames];
|
|
37409
|
+
const data = await this.requestWithPaymentRaw("/v1/x/users/lookup", { usernames: names });
|
|
37410
|
+
return data;
|
|
37411
|
+
}
|
|
37412
|
+
/**
|
|
37413
|
+
* Get followers of an X/Twitter user.
|
|
37414
|
+
*
|
|
37415
|
+
* Powered by AttentionVC. $0.05 per page (~200 accounts).
|
|
37416
|
+
*
|
|
37417
|
+
* @param username - X/Twitter username (without @)
|
|
37418
|
+
* @param cursor - Pagination cursor from previous response
|
|
37419
|
+
*/
|
|
37420
|
+
async xFollowers(username, cursor) {
|
|
37421
|
+
const body = { username };
|
|
37422
|
+
if (cursor !== void 0) body.cursor = cursor;
|
|
37423
|
+
const data = await this.requestWithPaymentRaw("/v1/x/users/followers", body);
|
|
37424
|
+
return data;
|
|
37425
|
+
}
|
|
37426
|
+
/**
|
|
37427
|
+
* Get accounts an X/Twitter user is following.
|
|
37428
|
+
*
|
|
37429
|
+
* Powered by AttentionVC. $0.05 per page (~200 accounts).
|
|
37430
|
+
*
|
|
37431
|
+
* @param username - X/Twitter username (without @)
|
|
37432
|
+
* @param cursor - Pagination cursor from previous response
|
|
37433
|
+
*/
|
|
37434
|
+
async xFollowings(username, cursor) {
|
|
37435
|
+
const body = { username };
|
|
37436
|
+
if (cursor !== void 0) body.cursor = cursor;
|
|
37437
|
+
const data = await this.requestWithPaymentRaw("/v1/x/users/followings", body);
|
|
37438
|
+
return data;
|
|
37439
|
+
}
|
|
37440
|
+
/**
|
|
37441
|
+
* Get detailed profile info for a single X/Twitter user.
|
|
37442
|
+
*
|
|
37443
|
+
* Powered by AttentionVC. $0.002 per request.
|
|
37444
|
+
*
|
|
37445
|
+
* @param username - X/Twitter username (without @)
|
|
37446
|
+
*/
|
|
37447
|
+
async xUserInfo(username) {
|
|
37448
|
+
const data = await this.requestWithPaymentRaw("/v1/x/users/info", { username });
|
|
37449
|
+
return data;
|
|
37450
|
+
}
|
|
37451
|
+
/**
|
|
37452
|
+
* Get verified (blue-check) followers of an X/Twitter user.
|
|
37453
|
+
*
|
|
37454
|
+
* Powered by AttentionVC. $0.048 per page.
|
|
37455
|
+
*
|
|
37456
|
+
* @param userId - X/Twitter user ID (not username)
|
|
37457
|
+
* @param cursor - Pagination cursor from previous response
|
|
37458
|
+
*/
|
|
37459
|
+
async xVerifiedFollowers(userId, cursor) {
|
|
37460
|
+
const body = { userId };
|
|
37461
|
+
if (cursor !== void 0) body.cursor = cursor;
|
|
37462
|
+
const data = await this.requestWithPaymentRaw("/v1/x/users/verified-followers", body);
|
|
37463
|
+
return data;
|
|
37464
|
+
}
|
|
37465
|
+
/**
|
|
37466
|
+
* Get tweets posted by an X/Twitter user.
|
|
37467
|
+
*
|
|
37468
|
+
* Powered by AttentionVC. $0.032 per page.
|
|
37469
|
+
*
|
|
37470
|
+
* @param username - X/Twitter username (without @)
|
|
37471
|
+
* @param includeReplies - Include reply tweets (default: false)
|
|
37472
|
+
* @param cursor - Pagination cursor from previous response
|
|
37473
|
+
*/
|
|
37474
|
+
async xUserTweets(username, includeReplies = false, cursor) {
|
|
37475
|
+
const body = { username, includeReplies };
|
|
37476
|
+
if (cursor !== void 0) body.cursor = cursor;
|
|
37477
|
+
const data = await this.requestWithPaymentRaw("/v1/x/users/tweets", body);
|
|
37478
|
+
return data;
|
|
37479
|
+
}
|
|
37480
|
+
/**
|
|
37481
|
+
* Get tweets that mention an X/Twitter user.
|
|
37482
|
+
*
|
|
37483
|
+
* Powered by AttentionVC. $0.032 per page.
|
|
37484
|
+
*
|
|
37485
|
+
* @param username - X/Twitter username (without @)
|
|
37486
|
+
* @param sinceTime - Start time filter (ISO8601 or Unix timestamp)
|
|
37487
|
+
* @param untilTime - End time filter (ISO8601 or Unix timestamp)
|
|
37488
|
+
* @param cursor - Pagination cursor from previous response
|
|
37489
|
+
*/
|
|
37490
|
+
async xUserMentions(username, sinceTime, untilTime, cursor) {
|
|
37491
|
+
const body = { username };
|
|
37492
|
+
if (sinceTime !== void 0) body.sinceTime = sinceTime;
|
|
37493
|
+
if (untilTime !== void 0) body.untilTime = untilTime;
|
|
37494
|
+
if (cursor !== void 0) body.cursor = cursor;
|
|
37495
|
+
const data = await this.requestWithPaymentRaw("/v1/x/users/mentions", body);
|
|
37496
|
+
return data;
|
|
37497
|
+
}
|
|
37498
|
+
/**
|
|
37499
|
+
* Fetch full tweet data for up to 200 tweet IDs.
|
|
37500
|
+
*
|
|
37501
|
+
* Powered by AttentionVC. $0.16 per batch.
|
|
37502
|
+
*
|
|
37503
|
+
* @param tweetIds - Single tweet ID or array of tweet IDs (max 200)
|
|
37504
|
+
*/
|
|
37505
|
+
async xTweetLookup(tweetIds) {
|
|
37506
|
+
const ids = Array.isArray(tweetIds) ? tweetIds : [tweetIds];
|
|
37507
|
+
const data = await this.requestWithPaymentRaw("/v1/x/tweets/lookup", { tweet_ids: ids });
|
|
37508
|
+
return data;
|
|
37509
|
+
}
|
|
37510
|
+
/**
|
|
37511
|
+
* Get replies to a specific tweet.
|
|
37512
|
+
*
|
|
37513
|
+
* Powered by AttentionVC. $0.032 per page.
|
|
37514
|
+
*
|
|
37515
|
+
* @param tweetId - The tweet ID to get replies for
|
|
37516
|
+
* @param queryType - Sort order: 'Latest' or 'Default'
|
|
37517
|
+
* @param cursor - Pagination cursor from previous response
|
|
37518
|
+
*/
|
|
37519
|
+
async xTweetReplies(tweetId, queryType = "Latest", cursor) {
|
|
37520
|
+
const body = { tweetId, queryType };
|
|
37521
|
+
if (cursor !== void 0) body.cursor = cursor;
|
|
37522
|
+
const data = await this.requestWithPaymentRaw("/v1/x/tweets/replies", body);
|
|
37523
|
+
return data;
|
|
37524
|
+
}
|
|
37525
|
+
/**
|
|
37526
|
+
* Get the full thread context for a tweet.
|
|
37527
|
+
*
|
|
37528
|
+
* Powered by AttentionVC. $0.032 per page.
|
|
37529
|
+
*
|
|
37530
|
+
* @param tweetId - The tweet ID to get thread for
|
|
37531
|
+
* @param cursor - Pagination cursor from previous response
|
|
37532
|
+
*/
|
|
37533
|
+
async xTweetThread(tweetId, cursor) {
|
|
37534
|
+
const body = { tweetId };
|
|
37535
|
+
if (cursor !== void 0) body.cursor = cursor;
|
|
37536
|
+
const data = await this.requestWithPaymentRaw("/v1/x/tweets/thread", body);
|
|
37537
|
+
return data;
|
|
37538
|
+
}
|
|
37539
|
+
/**
|
|
37540
|
+
* Search X/Twitter with advanced query operators.
|
|
37541
|
+
*
|
|
37542
|
+
* Powered by AttentionVC. $0.032 per page.
|
|
37543
|
+
*
|
|
37544
|
+
* @param query - Search query (supports Twitter search operators)
|
|
37545
|
+
* @param queryType - Sort order: 'Latest', 'Top', or 'Default'
|
|
37546
|
+
* @param cursor - Pagination cursor from previous response
|
|
37547
|
+
*/
|
|
37548
|
+
async xSearch(query, queryType = "Latest", cursor) {
|
|
37549
|
+
const body = { query, queryType };
|
|
37550
|
+
if (cursor !== void 0) body.cursor = cursor;
|
|
37551
|
+
const data = await this.requestWithPaymentRaw("/v1/x/search", body);
|
|
37552
|
+
return data;
|
|
37553
|
+
}
|
|
37554
|
+
/**
|
|
37555
|
+
* Get current trending topics on X/Twitter.
|
|
37556
|
+
*
|
|
37557
|
+
* Powered by AttentionVC. $0.002 per request.
|
|
37558
|
+
*/
|
|
37559
|
+
async xTrending() {
|
|
37560
|
+
const data = await this.requestWithPaymentRaw("/v1/x/trending", {});
|
|
37561
|
+
return data;
|
|
37562
|
+
}
|
|
37563
|
+
/**
|
|
37564
|
+
* Get rising/viral articles from X/Twitter.
|
|
37565
|
+
*
|
|
37566
|
+
* Powered by AttentionVC intelligence layer. $0.05 per request.
|
|
37567
|
+
*/
|
|
37568
|
+
async xArticlesRising() {
|
|
37569
|
+
const data = await this.requestWithPaymentRaw("/v1/x/articles/rising", {});
|
|
37570
|
+
return data;
|
|
37571
|
+
}
|
|
37572
|
+
/**
|
|
37573
|
+
* Get author analytics and intelligence metrics for an X/Twitter user.
|
|
37574
|
+
*
|
|
37575
|
+
* Powered by AttentionVC intelligence layer. $0.02 per request.
|
|
37576
|
+
*
|
|
37577
|
+
* @param handle - X/Twitter handle (without @)
|
|
37578
|
+
*/
|
|
37579
|
+
async xAuthorAnalytics(handle) {
|
|
37580
|
+
const data = await this.requestWithPaymentRaw("/v1/x/authors", { handle });
|
|
37581
|
+
return data;
|
|
37582
|
+
}
|
|
37583
|
+
/**
|
|
37584
|
+
* Compare two X/Twitter authors side-by-side with intelligence metrics.
|
|
37585
|
+
*
|
|
37586
|
+
* Powered by AttentionVC intelligence layer. $0.05 per request.
|
|
37587
|
+
*
|
|
37588
|
+
* @param handle1 - First X/Twitter handle (without @)
|
|
37589
|
+
* @param handle2 - Second X/Twitter handle (without @)
|
|
37590
|
+
*/
|
|
37591
|
+
async xCompareAuthors(handle1, handle2) {
|
|
37592
|
+
const data = await this.requestWithPaymentRaw("/v1/x/compare", { handle1, handle2 });
|
|
37593
|
+
return data;
|
|
37594
|
+
}
|
|
37595
|
+
// ── Prediction Markets (Powered by Predexon) ────────────────────────────
|
|
37596
|
+
/**
|
|
37597
|
+
* Query Predexon prediction market data (GET endpoints).
|
|
37598
|
+
*
|
|
37599
|
+
* Access real-time data from Polymarket, Kalshi, dFlow, and Binance Futures.
|
|
37600
|
+
* Powered by Predexon. $0.001 per request.
|
|
37601
|
+
*
|
|
37602
|
+
* @param path - Endpoint path, e.g. "polymarket/events", "kalshi/markets/12345"
|
|
37603
|
+
* @param params - Query parameters passed to the endpoint
|
|
37604
|
+
*
|
|
37605
|
+
* @example
|
|
37606
|
+
* const events = await client.pm("polymarket/events");
|
|
37607
|
+
* const market = await client.pm("kalshi/markets/KXBTC-25MAR14");
|
|
37608
|
+
* const results = await client.pm("polymarket/search", { q: "bitcoin" });
|
|
37609
|
+
*/
|
|
37610
|
+
async pm(path5, params) {
|
|
37611
|
+
return this.getWithPaymentRaw(`/v1/pm/${path5}`, params);
|
|
37612
|
+
}
|
|
37613
|
+
/**
|
|
37614
|
+
* Structured query for Predexon prediction market data (POST endpoints).
|
|
37615
|
+
*
|
|
37616
|
+
* For complex queries that require a JSON body. $0.005 per request.
|
|
37617
|
+
*
|
|
37618
|
+
* @param path - Endpoint path, e.g. "polymarket/query", "kalshi/query"
|
|
37619
|
+
* @param query - JSON body for the structured query
|
|
37620
|
+
*
|
|
37621
|
+
* @example
|
|
37622
|
+
* const data = await client.pmQuery("polymarket/query", { filter: "active", limit: 10 });
|
|
37623
|
+
*/
|
|
37624
|
+
async pmQuery(path5, query) {
|
|
37625
|
+
return this.requestWithPaymentRaw(`/v1/pm/${path5}`, query);
|
|
37626
|
+
}
|
|
37110
37627
|
/**
|
|
37111
37628
|
* Get current session spending.
|
|
37112
37629
|
*
|
|
@@ -37200,6 +37717,31 @@ var ImageClient = class {
|
|
|
37200
37717
|
}
|
|
37201
37718
|
return this.requestWithPayment("/v1/images/generations", body);
|
|
37202
37719
|
}
|
|
37720
|
+
/**
|
|
37721
|
+
* Edit an image using img2img.
|
|
37722
|
+
*
|
|
37723
|
+
* @param prompt - Text description of the desired edit
|
|
37724
|
+
* @param image - Base64-encoded image or URL of the source image
|
|
37725
|
+
* @param options - Optional edit parameters
|
|
37726
|
+
* @returns ImageResponse with edited image URLs
|
|
37727
|
+
*
|
|
37728
|
+
* @example
|
|
37729
|
+
* const result = await client.edit('Make it a painting', imageBase64);
|
|
37730
|
+
* console.log(result.data[0].url);
|
|
37731
|
+
*/
|
|
37732
|
+
async edit(prompt, image, options) {
|
|
37733
|
+
const body = {
|
|
37734
|
+
model: options?.model || "openai/gpt-image-1",
|
|
37735
|
+
prompt,
|
|
37736
|
+
image,
|
|
37737
|
+
size: options?.size || "1024x1024",
|
|
37738
|
+
n: options?.n || 1
|
|
37739
|
+
};
|
|
37740
|
+
if (options?.mask !== void 0) {
|
|
37741
|
+
body.mask = options.mask;
|
|
37742
|
+
}
|
|
37743
|
+
return this.requestWithPayment("/v1/images/image2image", body);
|
|
37744
|
+
}
|
|
37203
37745
|
/**
|
|
37204
37746
|
* List available image generation models with pricing.
|
|
37205
37747
|
*/
|
|
@@ -37367,7 +37909,35 @@ function saveWallet(privateKey) {
|
|
|
37367
37909
|
fs.writeFileSync(WALLET_FILE, privateKey, { mode: 384 });
|
|
37368
37910
|
return WALLET_FILE;
|
|
37369
37911
|
}
|
|
37912
|
+
function scanWallets() {
|
|
37913
|
+
const home = os.homedir();
|
|
37914
|
+
const results = [];
|
|
37915
|
+
try {
|
|
37916
|
+
const entries = fs.readdirSync(home, { withFileTypes: true });
|
|
37917
|
+
for (const entry of entries) {
|
|
37918
|
+
if (!entry.name.startsWith(".") || !entry.isDirectory()) continue;
|
|
37919
|
+
const walletFile = path.join(home, entry.name, "wallet.json");
|
|
37920
|
+
if (!fs.existsSync(walletFile)) continue;
|
|
37921
|
+
try {
|
|
37922
|
+
const data = JSON.parse(fs.readFileSync(walletFile, "utf-8"));
|
|
37923
|
+
const pk = data.privateKey || "";
|
|
37924
|
+
const addr = data.address || "";
|
|
37925
|
+
if (pk && addr) {
|
|
37926
|
+
const mtime = fs.statSync(walletFile).mtimeMs;
|
|
37927
|
+
results.push({ mtime, privateKey: pk, address: addr });
|
|
37928
|
+
}
|
|
37929
|
+
} catch {
|
|
37930
|
+
continue;
|
|
37931
|
+
}
|
|
37932
|
+
}
|
|
37933
|
+
} catch {
|
|
37934
|
+
}
|
|
37935
|
+
results.sort((a, b) => b.mtime - a.mtime);
|
|
37936
|
+
return results.map(({ privateKey, address }) => ({ privateKey, address }));
|
|
37937
|
+
}
|
|
37370
37938
|
function loadWallet() {
|
|
37939
|
+
const wallets = scanWallets();
|
|
37940
|
+
if (wallets.length > 0) return wallets[0].privateKey;
|
|
37371
37941
|
if (fs.existsSync(WALLET_FILE)) {
|
|
37372
37942
|
const key = fs.readFileSync(WALLET_FILE, "utf-8").trim();
|
|
37373
37943
|
if (key) return key;
|
|
@@ -37506,7 +38076,50 @@ function saveSolanaWallet(privateKey) {
|
|
|
37506
38076
|
fs2.writeFileSync(SOLANA_WALLET_FILE, privateKey, { mode: 384 });
|
|
37507
38077
|
return SOLANA_WALLET_FILE;
|
|
37508
38078
|
}
|
|
38079
|
+
function scanSolanaWallets() {
|
|
38080
|
+
const home = os2.homedir();
|
|
38081
|
+
const results = [];
|
|
38082
|
+
try {
|
|
38083
|
+
const entries = fs2.readdirSync(home, { withFileTypes: true });
|
|
38084
|
+
for (const entry of entries) {
|
|
38085
|
+
if (!entry.name.startsWith(".") || !entry.isDirectory()) continue;
|
|
38086
|
+
const solanaWalletFile = path2.join(home, entry.name, "solana-wallet.json");
|
|
38087
|
+
if (fs2.existsSync(solanaWalletFile)) {
|
|
38088
|
+
try {
|
|
38089
|
+
const data = JSON.parse(fs2.readFileSync(solanaWalletFile, "utf-8"));
|
|
38090
|
+
const pk = data.privateKey || "";
|
|
38091
|
+
const addr = data.address || "";
|
|
38092
|
+
if (pk && addr) {
|
|
38093
|
+
const mtime = fs2.statSync(solanaWalletFile).mtimeMs;
|
|
38094
|
+
results.push({ mtime, secretKey: pk, publicKey: addr });
|
|
38095
|
+
}
|
|
38096
|
+
} catch {
|
|
38097
|
+
}
|
|
38098
|
+
}
|
|
38099
|
+
if (entry.name === ".brcc") {
|
|
38100
|
+
const brccWalletFile = path2.join(home, entry.name, "wallet.json");
|
|
38101
|
+
if (fs2.existsSync(brccWalletFile)) {
|
|
38102
|
+
try {
|
|
38103
|
+
const data = JSON.parse(fs2.readFileSync(brccWalletFile, "utf-8"));
|
|
38104
|
+
const pk = data.privateKey || "";
|
|
38105
|
+
const addr = data.address || "";
|
|
38106
|
+
if (pk && addr) {
|
|
38107
|
+
const mtime = fs2.statSync(brccWalletFile).mtimeMs;
|
|
38108
|
+
results.push({ mtime, secretKey: pk, publicKey: addr });
|
|
38109
|
+
}
|
|
38110
|
+
} catch {
|
|
38111
|
+
}
|
|
38112
|
+
}
|
|
38113
|
+
}
|
|
38114
|
+
}
|
|
38115
|
+
} catch {
|
|
38116
|
+
}
|
|
38117
|
+
results.sort((a, b) => b.mtime - a.mtime);
|
|
38118
|
+
return results.map(({ secretKey, publicKey: publicKey3 }) => ({ secretKey, publicKey: publicKey3 }));
|
|
38119
|
+
}
|
|
37509
38120
|
function loadSolanaWallet() {
|
|
38121
|
+
const wallets = scanSolanaWallets();
|
|
38122
|
+
if (wallets.length > 0) return wallets[0].secretKey;
|
|
37510
38123
|
if (fs2.existsSync(SOLANA_WALLET_FILE)) {
|
|
37511
38124
|
const key = fs2.readFileSync(SOLANA_WALLET_FILE, "utf-8").trim();
|
|
37512
38125
|
if (key) return key;
|
|
@@ -37519,10 +38132,16 @@ async function getOrCreateSolanaWallet() {
|
|
|
37519
38132
|
const address2 = await solanaPublicKey(envKey);
|
|
37520
38133
|
return { privateKey: envKey, address: address2, isNew: false };
|
|
37521
38134
|
}
|
|
37522
|
-
const
|
|
37523
|
-
if (
|
|
37524
|
-
|
|
37525
|
-
|
|
38135
|
+
const wallets = scanSolanaWallets();
|
|
38136
|
+
if (wallets.length > 0) {
|
|
38137
|
+
return { privateKey: wallets[0].secretKey, address: wallets[0].publicKey, isNew: false };
|
|
38138
|
+
}
|
|
38139
|
+
if (fs2.existsSync(SOLANA_WALLET_FILE)) {
|
|
38140
|
+
const fileKey = fs2.readFileSync(SOLANA_WALLET_FILE, "utf-8").trim();
|
|
38141
|
+
if (fileKey) {
|
|
38142
|
+
const address2 = await solanaPublicKey(fileKey);
|
|
38143
|
+
return { privateKey: fileKey, address: address2, isNew: false };
|
|
38144
|
+
}
|
|
37526
38145
|
}
|
|
37527
38146
|
const { address, privateKey } = createSolanaWallet();
|
|
37528
38147
|
saveSolanaWallet(privateKey);
|
|
@@ -37580,29 +38199,172 @@ var SolanaLLMClient = class {
|
|
|
37580
38199
|
});
|
|
37581
38200
|
return result.choices[0].message.content || "";
|
|
37582
38201
|
}
|
|
37583
|
-
/** Full chat completion (OpenAI-compatible). */
|
|
37584
|
-
async chatCompletion(model, messages, options) {
|
|
37585
|
-
const body = {
|
|
37586
|
-
model,
|
|
37587
|
-
messages,
|
|
37588
|
-
max_tokens: options?.maxTokens || DEFAULT_MAX_TOKENS2
|
|
37589
|
-
};
|
|
37590
|
-
if (options?.temperature !== void 0) body.temperature = options.temperature;
|
|
37591
|
-
if (options?.topP !== void 0) body.top_p = options.topP;
|
|
37592
|
-
if (options?.searchParameters !== void 0) body.search_parameters = options.searchParameters;
|
|
37593
|
-
else if (options?.search === true) body.search_parameters = { mode: "on" };
|
|
37594
|
-
if (options?.tools !== void 0) body.tools = options.tools;
|
|
37595
|
-
if (options?.toolChoice !== void 0) body.tool_choice = options.toolChoice;
|
|
37596
|
-
return this.requestWithPayment("/v1/chat/completions", body);
|
|
38202
|
+
/** Full chat completion (OpenAI-compatible). */
|
|
38203
|
+
async chatCompletion(model, messages, options) {
|
|
38204
|
+
const body = {
|
|
38205
|
+
model,
|
|
38206
|
+
messages,
|
|
38207
|
+
max_tokens: options?.maxTokens || DEFAULT_MAX_TOKENS2
|
|
38208
|
+
};
|
|
38209
|
+
if (options?.temperature !== void 0) body.temperature = options.temperature;
|
|
38210
|
+
if (options?.topP !== void 0) body.top_p = options.topP;
|
|
38211
|
+
if (options?.searchParameters !== void 0) body.search_parameters = options.searchParameters;
|
|
38212
|
+
else if (options?.search === true) body.search_parameters = { mode: "on" };
|
|
38213
|
+
if (options?.tools !== void 0) body.tools = options.tools;
|
|
38214
|
+
if (options?.toolChoice !== void 0) body.tool_choice = options.toolChoice;
|
|
38215
|
+
return this.requestWithPayment("/v1/chat/completions", body);
|
|
38216
|
+
}
|
|
38217
|
+
/** List available models. */
|
|
38218
|
+
async listModels() {
|
|
38219
|
+
const response = await this.fetchWithTimeout(`${this.apiUrl}/v1/models`, { method: "GET" });
|
|
38220
|
+
if (!response.ok) {
|
|
38221
|
+
throw new APIError(`Failed to list models: ${response.status}`, response.status);
|
|
38222
|
+
}
|
|
38223
|
+
const data = await response.json();
|
|
38224
|
+
return data.data || [];
|
|
38225
|
+
}
|
|
38226
|
+
/**
|
|
38227
|
+
* Get Solana USDC balance.
|
|
38228
|
+
*
|
|
38229
|
+
* @returns USDC balance as a float
|
|
38230
|
+
*/
|
|
38231
|
+
async getBalance() {
|
|
38232
|
+
const usdc_mint = "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v";
|
|
38233
|
+
const address = await this.getWalletAddress();
|
|
38234
|
+
try {
|
|
38235
|
+
const response = await fetch(this.rpcUrl, {
|
|
38236
|
+
method: "POST",
|
|
38237
|
+
headers: { "Content-Type": "application/json" },
|
|
38238
|
+
body: JSON.stringify({
|
|
38239
|
+
jsonrpc: "2.0",
|
|
38240
|
+
id: 1,
|
|
38241
|
+
method: "getTokenAccountsByOwner",
|
|
38242
|
+
params: [address, { mint: usdc_mint }, { encoding: "jsonParsed" }]
|
|
38243
|
+
})
|
|
38244
|
+
});
|
|
38245
|
+
const data = await response.json();
|
|
38246
|
+
const accounts = data.result?.value || [];
|
|
38247
|
+
if (!accounts.length) return 0;
|
|
38248
|
+
let total = 0;
|
|
38249
|
+
for (const acct of accounts) {
|
|
38250
|
+
total += acct.account?.data?.parsed?.info?.tokenAmount?.uiAmount || 0;
|
|
38251
|
+
}
|
|
38252
|
+
return total;
|
|
38253
|
+
} catch {
|
|
38254
|
+
return 0;
|
|
38255
|
+
}
|
|
38256
|
+
}
|
|
38257
|
+
/** Edit an image using img2img (Solana payment). */
|
|
38258
|
+
async imageEdit(prompt, image, options) {
|
|
38259
|
+
const body = {
|
|
38260
|
+
model: options?.model || "openai/gpt-image-1",
|
|
38261
|
+
prompt,
|
|
38262
|
+
image,
|
|
38263
|
+
size: options?.size || "1024x1024",
|
|
38264
|
+
n: options?.n || 1
|
|
38265
|
+
};
|
|
38266
|
+
if (options?.mask !== void 0) body.mask = options.mask;
|
|
38267
|
+
const data = await this.requestWithPaymentRaw("/v1/images/image2image", body);
|
|
38268
|
+
return data;
|
|
38269
|
+
}
|
|
38270
|
+
/** Standalone search (Solana payment). */
|
|
38271
|
+
async search(query, options) {
|
|
38272
|
+
const body = { query, max_results: options?.maxResults || 10 };
|
|
38273
|
+
if (options?.sources !== void 0) body.sources = options.sources;
|
|
38274
|
+
if (options?.fromDate !== void 0) body.from_date = options.fromDate;
|
|
38275
|
+
if (options?.toDate !== void 0) body.to_date = options.toDate;
|
|
38276
|
+
const data = await this.requestWithPaymentRaw("/v1/search", body);
|
|
38277
|
+
return data;
|
|
38278
|
+
}
|
|
38279
|
+
// ============================================================
|
|
38280
|
+
// X/Twitter endpoints (powered by AttentionVC)
|
|
38281
|
+
// ============================================================
|
|
38282
|
+
async xUserLookup(usernames) {
|
|
38283
|
+
const names = Array.isArray(usernames) ? usernames : [usernames];
|
|
38284
|
+
const data = await this.requestWithPaymentRaw("/v1/x/users/lookup", { usernames: names });
|
|
38285
|
+
return data;
|
|
38286
|
+
}
|
|
38287
|
+
async xFollowers(username, cursor) {
|
|
38288
|
+
const body = { username };
|
|
38289
|
+
if (cursor !== void 0) body.cursor = cursor;
|
|
38290
|
+
const data = await this.requestWithPaymentRaw("/v1/x/users/followers", body);
|
|
38291
|
+
return data;
|
|
38292
|
+
}
|
|
38293
|
+
async xFollowings(username, cursor) {
|
|
38294
|
+
const body = { username };
|
|
38295
|
+
if (cursor !== void 0) body.cursor = cursor;
|
|
38296
|
+
const data = await this.requestWithPaymentRaw("/v1/x/users/followings", body);
|
|
38297
|
+
return data;
|
|
38298
|
+
}
|
|
38299
|
+
async xUserInfo(username) {
|
|
38300
|
+
const data = await this.requestWithPaymentRaw("/v1/x/users/info", { username });
|
|
38301
|
+
return data;
|
|
38302
|
+
}
|
|
38303
|
+
async xVerifiedFollowers(userId, cursor) {
|
|
38304
|
+
const body = { userId };
|
|
38305
|
+
if (cursor !== void 0) body.cursor = cursor;
|
|
38306
|
+
const data = await this.requestWithPaymentRaw("/v1/x/users/verified-followers", body);
|
|
38307
|
+
return data;
|
|
38308
|
+
}
|
|
38309
|
+
async xUserTweets(username, includeReplies = false, cursor) {
|
|
38310
|
+
const body = { username, includeReplies };
|
|
38311
|
+
if (cursor !== void 0) body.cursor = cursor;
|
|
38312
|
+
const data = await this.requestWithPaymentRaw("/v1/x/users/tweets", body);
|
|
38313
|
+
return data;
|
|
38314
|
+
}
|
|
38315
|
+
async xUserMentions(username, sinceTime, untilTime, cursor) {
|
|
38316
|
+
const body = { username };
|
|
38317
|
+
if (sinceTime !== void 0) body.sinceTime = sinceTime;
|
|
38318
|
+
if (untilTime !== void 0) body.untilTime = untilTime;
|
|
38319
|
+
if (cursor !== void 0) body.cursor = cursor;
|
|
38320
|
+
const data = await this.requestWithPaymentRaw("/v1/x/users/mentions", body);
|
|
38321
|
+
return data;
|
|
38322
|
+
}
|
|
38323
|
+
async xTweetLookup(tweetIds) {
|
|
38324
|
+
const ids = Array.isArray(tweetIds) ? tweetIds : [tweetIds];
|
|
38325
|
+
const data = await this.requestWithPaymentRaw("/v1/x/tweets/lookup", { tweet_ids: ids });
|
|
38326
|
+
return data;
|
|
38327
|
+
}
|
|
38328
|
+
async xTweetReplies(tweetId, queryType = "Latest", cursor) {
|
|
38329
|
+
const body = { tweetId, queryType };
|
|
38330
|
+
if (cursor !== void 0) body.cursor = cursor;
|
|
38331
|
+
const data = await this.requestWithPaymentRaw("/v1/x/tweets/replies", body);
|
|
38332
|
+
return data;
|
|
38333
|
+
}
|
|
38334
|
+
async xTweetThread(tweetId, cursor) {
|
|
38335
|
+
const body = { tweetId };
|
|
38336
|
+
if (cursor !== void 0) body.cursor = cursor;
|
|
38337
|
+
const data = await this.requestWithPaymentRaw("/v1/x/tweets/thread", body);
|
|
38338
|
+
return data;
|
|
38339
|
+
}
|
|
38340
|
+
async xSearch(query, queryType = "Latest", cursor) {
|
|
38341
|
+
const body = { query, queryType };
|
|
38342
|
+
if (cursor !== void 0) body.cursor = cursor;
|
|
38343
|
+
const data = await this.requestWithPaymentRaw("/v1/x/search", body);
|
|
38344
|
+
return data;
|
|
38345
|
+
}
|
|
38346
|
+
async xTrending() {
|
|
38347
|
+
const data = await this.requestWithPaymentRaw("/v1/x/trending", {});
|
|
38348
|
+
return data;
|
|
38349
|
+
}
|
|
38350
|
+
async xArticlesRising() {
|
|
38351
|
+
const data = await this.requestWithPaymentRaw("/v1/x/articles/rising", {});
|
|
38352
|
+
return data;
|
|
38353
|
+
}
|
|
38354
|
+
async xAuthorAnalytics(handle) {
|
|
38355
|
+
const data = await this.requestWithPaymentRaw("/v1/x/authors", { handle });
|
|
38356
|
+
return data;
|
|
38357
|
+
}
|
|
38358
|
+
async xCompareAuthors(handle1, handle2) {
|
|
38359
|
+
const data = await this.requestWithPaymentRaw("/v1/x/compare", { handle1, handle2 });
|
|
38360
|
+
return data;
|
|
37597
38361
|
}
|
|
37598
|
-
|
|
37599
|
-
async
|
|
37600
|
-
|
|
37601
|
-
|
|
37602
|
-
|
|
37603
|
-
}
|
|
37604
|
-
const data = await response.json();
|
|
37605
|
-
return data.data || [];
|
|
38362
|
+
// ── Prediction Markets (Powered by Predexon) ────────────────────────────
|
|
38363
|
+
async pm(path5, params) {
|
|
38364
|
+
return this.getWithPaymentRaw(`/v1/pm/${path5}`, params);
|
|
38365
|
+
}
|
|
38366
|
+
async pmQuery(path5, query) {
|
|
38367
|
+
return this.requestWithPaymentRaw(`/v1/pm/${path5}`, query);
|
|
37606
38368
|
}
|
|
37607
38369
|
/** Get session spending. */
|
|
37608
38370
|
getSpending() {
|
|
@@ -37703,6 +38465,188 @@ var SolanaLLMClient = class {
|
|
|
37703
38465
|
this.sessionTotalUsd += costUsd;
|
|
37704
38466
|
return retryResponse.json();
|
|
37705
38467
|
}
|
|
38468
|
+
async requestWithPaymentRaw(endpoint2, body) {
|
|
38469
|
+
const url2 = `${this.apiUrl}${endpoint2}`;
|
|
38470
|
+
const response = await this.fetchWithTimeout(url2, {
|
|
38471
|
+
method: "POST",
|
|
38472
|
+
headers: { "Content-Type": "application/json", "User-Agent": USER_AGENT2 },
|
|
38473
|
+
body: JSON.stringify(body)
|
|
38474
|
+
});
|
|
38475
|
+
if (response.status === 402) {
|
|
38476
|
+
return this.handlePaymentAndRetryRaw(url2, body, response);
|
|
38477
|
+
}
|
|
38478
|
+
if (!response.ok) {
|
|
38479
|
+
let errorBody;
|
|
38480
|
+
try {
|
|
38481
|
+
errorBody = await response.json();
|
|
38482
|
+
} catch {
|
|
38483
|
+
errorBody = { error: "Request failed" };
|
|
38484
|
+
}
|
|
38485
|
+
throw new APIError(`API error: ${response.status}`, response.status, sanitizeErrorResponse(errorBody));
|
|
38486
|
+
}
|
|
38487
|
+
return response.json();
|
|
38488
|
+
}
|
|
38489
|
+
async handlePaymentAndRetryRaw(url2, body, response) {
|
|
38490
|
+
let paymentHeader = response.headers.get("payment-required");
|
|
38491
|
+
if (!paymentHeader) {
|
|
38492
|
+
try {
|
|
38493
|
+
const respBody = await response.json();
|
|
38494
|
+
if (respBody.accepts || respBody.x402Version) {
|
|
38495
|
+
paymentHeader = btoa(JSON.stringify(respBody));
|
|
38496
|
+
}
|
|
38497
|
+
} catch {
|
|
38498
|
+
}
|
|
38499
|
+
}
|
|
38500
|
+
if (!paymentHeader) {
|
|
38501
|
+
throw new PaymentError("402 response but no payment requirements found");
|
|
38502
|
+
}
|
|
38503
|
+
const paymentRequired = parsePaymentRequired(paymentHeader);
|
|
38504
|
+
const details = extractPaymentDetails(paymentRequired, SOLANA_NETWORK);
|
|
38505
|
+
if (!details.network?.startsWith("solana:")) {
|
|
38506
|
+
throw new PaymentError(
|
|
38507
|
+
`Expected Solana payment network, got: ${details.network}. Use LLMClient for Base payments.`
|
|
38508
|
+
);
|
|
38509
|
+
}
|
|
38510
|
+
const feePayer = details.extra?.feePayer;
|
|
38511
|
+
if (!feePayer) throw new PaymentError("Missing feePayer in 402 extra field");
|
|
38512
|
+
const fromAddress = await this.getWalletAddress();
|
|
38513
|
+
const secretKey = await solanaKeyToBytes(this.privateKey);
|
|
38514
|
+
const extensions = paymentRequired.extensions;
|
|
38515
|
+
const paymentPayload = await createSolanaPaymentPayload(
|
|
38516
|
+
secretKey,
|
|
38517
|
+
fromAddress,
|
|
38518
|
+
details.recipient,
|
|
38519
|
+
details.amount,
|
|
38520
|
+
feePayer,
|
|
38521
|
+
{
|
|
38522
|
+
resourceUrl: validateResourceUrl(
|
|
38523
|
+
details.resource?.url || url2,
|
|
38524
|
+
this.apiUrl
|
|
38525
|
+
),
|
|
38526
|
+
resourceDescription: details.resource?.description || "BlockRun Solana AI API call",
|
|
38527
|
+
maxTimeoutSeconds: details.maxTimeoutSeconds || 300,
|
|
38528
|
+
extra: details.extra,
|
|
38529
|
+
extensions,
|
|
38530
|
+
rpcUrl: this.rpcUrl
|
|
38531
|
+
}
|
|
38532
|
+
);
|
|
38533
|
+
const retryResponse = await this.fetchWithTimeout(url2, {
|
|
38534
|
+
method: "POST",
|
|
38535
|
+
headers: {
|
|
38536
|
+
"Content-Type": "application/json",
|
|
38537
|
+
"User-Agent": USER_AGENT2,
|
|
38538
|
+
"PAYMENT-SIGNATURE": paymentPayload
|
|
38539
|
+
},
|
|
38540
|
+
body: JSON.stringify(body)
|
|
38541
|
+
});
|
|
38542
|
+
if (retryResponse.status === 402) {
|
|
38543
|
+
throw new PaymentError("Payment was rejected. Check your Solana USDC balance.");
|
|
38544
|
+
}
|
|
38545
|
+
if (!retryResponse.ok) {
|
|
38546
|
+
let errorBody;
|
|
38547
|
+
try {
|
|
38548
|
+
errorBody = await retryResponse.json();
|
|
38549
|
+
} catch {
|
|
38550
|
+
errorBody = { error: "Request failed" };
|
|
38551
|
+
}
|
|
38552
|
+
throw new APIError(`API error after payment: ${retryResponse.status}`, retryResponse.status, sanitizeErrorResponse(errorBody));
|
|
38553
|
+
}
|
|
38554
|
+
const costUsd = parseFloat(details.amount) / 1e6;
|
|
38555
|
+
this.sessionCalls += 1;
|
|
38556
|
+
this.sessionTotalUsd += costUsd;
|
|
38557
|
+
return retryResponse.json();
|
|
38558
|
+
}
|
|
38559
|
+
async getWithPaymentRaw(endpoint2, params) {
|
|
38560
|
+
const query = params ? "?" + new URLSearchParams(params).toString() : "";
|
|
38561
|
+
const url2 = `${this.apiUrl}${endpoint2}${query}`;
|
|
38562
|
+
const response = await this.fetchWithTimeout(url2, {
|
|
38563
|
+
method: "GET",
|
|
38564
|
+
headers: { "User-Agent": USER_AGENT2 }
|
|
38565
|
+
});
|
|
38566
|
+
if (response.status === 402) {
|
|
38567
|
+
return this.handleGetPaymentAndRetryRaw(url2, endpoint2, params, response);
|
|
38568
|
+
}
|
|
38569
|
+
if (!response.ok) {
|
|
38570
|
+
let errorBody;
|
|
38571
|
+
try {
|
|
38572
|
+
errorBody = await response.json();
|
|
38573
|
+
} catch {
|
|
38574
|
+
errorBody = { error: "Request failed" };
|
|
38575
|
+
}
|
|
38576
|
+
throw new APIError(`API error: ${response.status}`, response.status, sanitizeErrorResponse(errorBody));
|
|
38577
|
+
}
|
|
38578
|
+
return response.json();
|
|
38579
|
+
}
|
|
38580
|
+
async handleGetPaymentAndRetryRaw(url2, endpoint2, params, response) {
|
|
38581
|
+
let paymentHeader = response.headers.get("payment-required");
|
|
38582
|
+
if (!paymentHeader) {
|
|
38583
|
+
try {
|
|
38584
|
+
const respBody = await response.json();
|
|
38585
|
+
if (respBody.accepts || respBody.x402Version) {
|
|
38586
|
+
paymentHeader = btoa(JSON.stringify(respBody));
|
|
38587
|
+
}
|
|
38588
|
+
} catch {
|
|
38589
|
+
}
|
|
38590
|
+
}
|
|
38591
|
+
if (!paymentHeader) {
|
|
38592
|
+
throw new PaymentError("402 response but no payment requirements found");
|
|
38593
|
+
}
|
|
38594
|
+
const paymentRequired = parsePaymentRequired(paymentHeader);
|
|
38595
|
+
const details = extractPaymentDetails(paymentRequired, SOLANA_NETWORK);
|
|
38596
|
+
if (!details.network?.startsWith("solana:")) {
|
|
38597
|
+
throw new PaymentError(
|
|
38598
|
+
`Expected Solana payment network, got: ${details.network}. Use LLMClient for Base payments.`
|
|
38599
|
+
);
|
|
38600
|
+
}
|
|
38601
|
+
const feePayer = details.extra?.feePayer;
|
|
38602
|
+
if (!feePayer) throw new PaymentError("Missing feePayer in 402 extra field");
|
|
38603
|
+
const fromAddress = await this.getWalletAddress();
|
|
38604
|
+
const secretKey = await solanaKeyToBytes(this.privateKey);
|
|
38605
|
+
const extensions = paymentRequired.extensions;
|
|
38606
|
+
const paymentPayload = await createSolanaPaymentPayload(
|
|
38607
|
+
secretKey,
|
|
38608
|
+
fromAddress,
|
|
38609
|
+
details.recipient,
|
|
38610
|
+
details.amount,
|
|
38611
|
+
feePayer,
|
|
38612
|
+
{
|
|
38613
|
+
resourceUrl: validateResourceUrl(
|
|
38614
|
+
details.resource?.url || url2,
|
|
38615
|
+
this.apiUrl
|
|
38616
|
+
),
|
|
38617
|
+
resourceDescription: details.resource?.description || "BlockRun Solana AI API call",
|
|
38618
|
+
maxTimeoutSeconds: details.maxTimeoutSeconds || 300,
|
|
38619
|
+
extra: details.extra,
|
|
38620
|
+
extensions,
|
|
38621
|
+
rpcUrl: this.rpcUrl
|
|
38622
|
+
}
|
|
38623
|
+
);
|
|
38624
|
+
const query = params ? "?" + new URLSearchParams(params).toString() : "";
|
|
38625
|
+
const retryUrl = `${this.apiUrl}${endpoint2}${query}`;
|
|
38626
|
+
const retryResponse = await this.fetchWithTimeout(retryUrl, {
|
|
38627
|
+
method: "GET",
|
|
38628
|
+
headers: {
|
|
38629
|
+
"User-Agent": USER_AGENT2,
|
|
38630
|
+
"PAYMENT-SIGNATURE": paymentPayload
|
|
38631
|
+
}
|
|
38632
|
+
});
|
|
38633
|
+
if (retryResponse.status === 402) {
|
|
38634
|
+
throw new PaymentError("Payment was rejected. Check your Solana USDC balance.");
|
|
38635
|
+
}
|
|
38636
|
+
if (!retryResponse.ok) {
|
|
38637
|
+
let errorBody;
|
|
38638
|
+
try {
|
|
38639
|
+
errorBody = await retryResponse.json();
|
|
38640
|
+
} catch {
|
|
38641
|
+
errorBody = { error: "Request failed" };
|
|
38642
|
+
}
|
|
38643
|
+
throw new APIError(`API error after payment: ${retryResponse.status}`, retryResponse.status, sanitizeErrorResponse(errorBody));
|
|
38644
|
+
}
|
|
38645
|
+
const costUsd = parseFloat(details.amount) / 1e6;
|
|
38646
|
+
this.sessionCalls += 1;
|
|
38647
|
+
this.sessionTotalUsd += costUsd;
|
|
38648
|
+
return retryResponse.json();
|
|
38649
|
+
}
|
|
37706
38650
|
async fetchWithTimeout(url2, options) {
|
|
37707
38651
|
const controller = new AbortController();
|
|
37708
38652
|
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
|
|
@@ -37717,6 +38661,192 @@ function solanaClient(options = {}) {
|
|
|
37717
38661
|
return new SolanaLLMClient({ ...options, apiUrl: SOLANA_API_URL });
|
|
37718
38662
|
}
|
|
37719
38663
|
|
|
38664
|
+
// src/cache.ts
|
|
38665
|
+
var fs3 = __toESM(require("fs"), 1);
|
|
38666
|
+
var path3 = __toESM(require("path"), 1);
|
|
38667
|
+
var os3 = __toESM(require("os"), 1);
|
|
38668
|
+
var crypto6 = __toESM(require("crypto"), 1);
|
|
38669
|
+
var CACHE_DIR = path3.join(os3.homedir(), ".blockrun", "cache");
|
|
38670
|
+
var DEFAULT_TTL = {
|
|
38671
|
+
"/v1/x/": 3600 * 1e3,
|
|
38672
|
+
"/v1/partner/": 3600 * 1e3,
|
|
38673
|
+
"/v1/pm/": 1800 * 1e3,
|
|
38674
|
+
"/v1/chat/": 0,
|
|
38675
|
+
"/v1/search": 900 * 1e3,
|
|
38676
|
+
"/v1/image": 0,
|
|
38677
|
+
"/v1/models": 86400 * 1e3
|
|
38678
|
+
};
|
|
38679
|
+
function getTtl(endpoint2) {
|
|
38680
|
+
for (const [pattern, ttl] of Object.entries(DEFAULT_TTL)) {
|
|
38681
|
+
if (endpoint2.includes(pattern)) return ttl;
|
|
38682
|
+
}
|
|
38683
|
+
return 3600 * 1e3;
|
|
38684
|
+
}
|
|
38685
|
+
function cacheKey(endpoint2, body) {
|
|
38686
|
+
const keyData = JSON.stringify({ endpoint: endpoint2, body }, Object.keys({ endpoint: endpoint2, body }).sort());
|
|
38687
|
+
return crypto6.createHash("sha256").update(keyData).digest("hex").slice(0, 16);
|
|
38688
|
+
}
|
|
38689
|
+
function cachePath(key) {
|
|
38690
|
+
return path3.join(CACHE_DIR, `${key}.json`);
|
|
38691
|
+
}
|
|
38692
|
+
function getCached(key) {
|
|
38693
|
+
const filePath = cachePath(key);
|
|
38694
|
+
if (!fs3.existsSync(filePath)) return null;
|
|
38695
|
+
try {
|
|
38696
|
+
const raw = fs3.readFileSync(filePath, "utf-8");
|
|
38697
|
+
const entry = JSON.parse(raw);
|
|
38698
|
+
const ttl = entry.ttlMs ?? getTtl(entry.endpoint ?? "");
|
|
38699
|
+
if (ttl <= 0) return null;
|
|
38700
|
+
if (Date.now() - entry.cachedAt > ttl) {
|
|
38701
|
+
try {
|
|
38702
|
+
fs3.unlinkSync(filePath);
|
|
38703
|
+
} catch {
|
|
38704
|
+
}
|
|
38705
|
+
return null;
|
|
38706
|
+
}
|
|
38707
|
+
return entry.response;
|
|
38708
|
+
} catch {
|
|
38709
|
+
return null;
|
|
38710
|
+
}
|
|
38711
|
+
}
|
|
38712
|
+
function getCachedByRequest(endpoint2, body) {
|
|
38713
|
+
const ttl = getTtl(endpoint2);
|
|
38714
|
+
if (ttl <= 0) return null;
|
|
38715
|
+
const key = cacheKey(endpoint2, body);
|
|
38716
|
+
return getCached(key);
|
|
38717
|
+
}
|
|
38718
|
+
function setCache(key, data, ttlMs) {
|
|
38719
|
+
if (ttlMs <= 0) return;
|
|
38720
|
+
try {
|
|
38721
|
+
fs3.mkdirSync(CACHE_DIR, { recursive: true });
|
|
38722
|
+
} catch {
|
|
38723
|
+
}
|
|
38724
|
+
const entry = {
|
|
38725
|
+
cachedAt: Date.now(),
|
|
38726
|
+
response: data,
|
|
38727
|
+
ttlMs
|
|
38728
|
+
};
|
|
38729
|
+
try {
|
|
38730
|
+
fs3.writeFileSync(cachePath(key), JSON.stringify(entry));
|
|
38731
|
+
} catch {
|
|
38732
|
+
}
|
|
38733
|
+
}
|
|
38734
|
+
function saveToCache(endpoint2, body, response, costUsd = 0) {
|
|
38735
|
+
const ttl = getTtl(endpoint2);
|
|
38736
|
+
if (ttl <= 0) return;
|
|
38737
|
+
try {
|
|
38738
|
+
fs3.mkdirSync(CACHE_DIR, { recursive: true });
|
|
38739
|
+
} catch {
|
|
38740
|
+
}
|
|
38741
|
+
const key = cacheKey(endpoint2, body);
|
|
38742
|
+
const entry = {
|
|
38743
|
+
cachedAt: Date.now(),
|
|
38744
|
+
endpoint: endpoint2,
|
|
38745
|
+
body,
|
|
38746
|
+
response,
|
|
38747
|
+
costUsd
|
|
38748
|
+
};
|
|
38749
|
+
try {
|
|
38750
|
+
fs3.writeFileSync(cachePath(key), JSON.stringify(entry));
|
|
38751
|
+
} catch {
|
|
38752
|
+
}
|
|
38753
|
+
}
|
|
38754
|
+
function clearCache() {
|
|
38755
|
+
if (!fs3.existsSync(CACHE_DIR)) return 0;
|
|
38756
|
+
let count = 0;
|
|
38757
|
+
try {
|
|
38758
|
+
const files = fs3.readdirSync(CACHE_DIR);
|
|
38759
|
+
for (const file of files) {
|
|
38760
|
+
if (file.endsWith(".json")) {
|
|
38761
|
+
try {
|
|
38762
|
+
fs3.unlinkSync(path3.join(CACHE_DIR, file));
|
|
38763
|
+
count++;
|
|
38764
|
+
} catch {
|
|
38765
|
+
}
|
|
38766
|
+
}
|
|
38767
|
+
}
|
|
38768
|
+
} catch {
|
|
38769
|
+
}
|
|
38770
|
+
return count;
|
|
38771
|
+
}
|
|
38772
|
+
|
|
38773
|
+
// src/setup.ts
|
|
38774
|
+
function setupAgentWallet(options) {
|
|
38775
|
+
const { address, privateKey, isNew } = getOrCreateWallet();
|
|
38776
|
+
if (isNew && !options?.silent) {
|
|
38777
|
+
console.error(
|
|
38778
|
+
`
|
|
38779
|
+
BlockRun Agent Wallet Created!
|
|
38780
|
+
Address: ${address}
|
|
38781
|
+
Send USDC on Base to get started.
|
|
38782
|
+
`
|
|
38783
|
+
);
|
|
38784
|
+
}
|
|
38785
|
+
return new LLMClient({ privateKey });
|
|
38786
|
+
}
|
|
38787
|
+
async function setupAgentSolanaWallet(options) {
|
|
38788
|
+
const result = await getOrCreateSolanaWallet();
|
|
38789
|
+
if (result.isNew && !options?.silent) {
|
|
38790
|
+
console.error(
|
|
38791
|
+
`
|
|
38792
|
+
BlockRun Solana Agent Wallet Created!
|
|
38793
|
+
Address: ${result.address}
|
|
38794
|
+
Send USDC on Solana to get started.
|
|
38795
|
+
`
|
|
38796
|
+
);
|
|
38797
|
+
}
|
|
38798
|
+
return new SolanaLLMClient({ privateKey: result.privateKey });
|
|
38799
|
+
}
|
|
38800
|
+
async function status() {
|
|
38801
|
+
const client = setupAgentWallet({ silent: true });
|
|
38802
|
+
const address = client.getWalletAddress();
|
|
38803
|
+
const balance = await client.getBalance();
|
|
38804
|
+
console.log(`Wallet: ${address}`);
|
|
38805
|
+
console.log(`Balance: $${balance.toFixed(2)} USDC`);
|
|
38806
|
+
return { address, balance };
|
|
38807
|
+
}
|
|
38808
|
+
|
|
38809
|
+
// src/cost-log.ts
|
|
38810
|
+
var fs4 = __toESM(require("fs"), 1);
|
|
38811
|
+
var path4 = __toESM(require("path"), 1);
|
|
38812
|
+
var os4 = __toESM(require("os"), 1);
|
|
38813
|
+
var DATA_DIR = path4.join(os4.homedir(), ".blockrun", "data");
|
|
38814
|
+
var COST_LOG_FILE = path4.join(DATA_DIR, "costs.jsonl");
|
|
38815
|
+
function logCost(entry) {
|
|
38816
|
+
try {
|
|
38817
|
+
fs4.mkdirSync(DATA_DIR, { recursive: true });
|
|
38818
|
+
} catch {
|
|
38819
|
+
}
|
|
38820
|
+
try {
|
|
38821
|
+
fs4.appendFileSync(COST_LOG_FILE, JSON.stringify(entry) + "\n");
|
|
38822
|
+
} catch {
|
|
38823
|
+
}
|
|
38824
|
+
}
|
|
38825
|
+
function getCostSummary() {
|
|
38826
|
+
if (!fs4.existsSync(COST_LOG_FILE)) {
|
|
38827
|
+
return { totalUsd: 0, calls: 0, byModel: {} };
|
|
38828
|
+
}
|
|
38829
|
+
let totalUsd = 0;
|
|
38830
|
+
let calls = 0;
|
|
38831
|
+
const byModel = {};
|
|
38832
|
+
try {
|
|
38833
|
+
const content = fs4.readFileSync(COST_LOG_FILE, "utf-8").trim();
|
|
38834
|
+
if (!content) return { totalUsd: 0, calls: 0, byModel: {} };
|
|
38835
|
+
for (const line of content.split("\n")) {
|
|
38836
|
+
if (!line) continue;
|
|
38837
|
+
try {
|
|
38838
|
+
const entry = JSON.parse(line);
|
|
38839
|
+
totalUsd += entry.costUsd;
|
|
38840
|
+
calls += 1;
|
|
38841
|
+
byModel[entry.model] = (byModel[entry.model] || 0) + entry.costUsd;
|
|
38842
|
+
} catch {
|
|
38843
|
+
}
|
|
38844
|
+
}
|
|
38845
|
+
} catch {
|
|
38846
|
+
}
|
|
38847
|
+
return { totalUsd, calls, byModel };
|
|
38848
|
+
}
|
|
38849
|
+
|
|
37720
38850
|
// src/openai-compat.ts
|
|
37721
38851
|
var StreamingResponse = class {
|
|
37722
38852
|
reader;
|
|
@@ -37903,12 +39033,16 @@ var OpenAI = class {
|
|
|
37903
39033
|
USDC_SOLANA,
|
|
37904
39034
|
WALLET_DIR_PATH,
|
|
37905
39035
|
WALLET_FILE_PATH,
|
|
39036
|
+
clearCache,
|
|
37906
39037
|
createSolanaPaymentPayload,
|
|
37907
39038
|
createSolanaWallet,
|
|
37908
39039
|
createWallet,
|
|
37909
39040
|
formatFundingMessageCompact,
|
|
37910
39041
|
formatNeedsFundingMessage,
|
|
37911
39042
|
formatWalletCreatedMessage,
|
|
39043
|
+
getCached,
|
|
39044
|
+
getCachedByRequest,
|
|
39045
|
+
getCostSummary,
|
|
37912
39046
|
getEip681Uri,
|
|
37913
39047
|
getOrCreateSolanaWallet,
|
|
37914
39048
|
getOrCreateWallet,
|
|
@@ -37916,11 +39050,19 @@ var OpenAI = class {
|
|
|
37916
39050
|
getWalletAddress,
|
|
37917
39051
|
loadSolanaWallet,
|
|
37918
39052
|
loadWallet,
|
|
39053
|
+
logCost,
|
|
37919
39054
|
saveSolanaWallet,
|
|
39055
|
+
saveToCache,
|
|
37920
39056
|
saveWallet,
|
|
39057
|
+
scanSolanaWallets,
|
|
39058
|
+
scanWallets,
|
|
39059
|
+
setCache,
|
|
39060
|
+
setupAgentSolanaWallet,
|
|
39061
|
+
setupAgentWallet,
|
|
37921
39062
|
solanaClient,
|
|
37922
39063
|
solanaKeyToBytes,
|
|
37923
39064
|
solanaPublicKey,
|
|
39065
|
+
status,
|
|
37924
39066
|
testnetClient
|
|
37925
39067
|
});
|
|
37926
39068
|
/*! Bundled license information:
|