@t54-labs/clawcredit-blockrun-sdk 0.1.2 → 0.1.3
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.
|
@@ -108,6 +108,34 @@ function createClawCreditFetch(config) {
|
|
|
108
108
|
|
|
109
109
|
// src/server.ts
|
|
110
110
|
import { createServer } from "http";
|
|
111
|
+
import { appendFileSync, mkdirSync } from "fs";
|
|
112
|
+
import { dirname } from "path";
|
|
113
|
+
import { randomUUID } from "crypto";
|
|
114
|
+
var VALID_ROLES = /* @__PURE__ */ new Set(["system", "user", "assistant", "tool", "function"]);
|
|
115
|
+
var ROLE_MAPPINGS = {
|
|
116
|
+
developer: "system",
|
|
117
|
+
model: "assistant"
|
|
118
|
+
};
|
|
119
|
+
function normalizeMessageRoles(messages) {
|
|
120
|
+
if (messages.length === 0) return messages;
|
|
121
|
+
let hasChanges = false;
|
|
122
|
+
const normalized = messages.map((msg) => {
|
|
123
|
+
const role = msg.role;
|
|
124
|
+
if (typeof role !== "string") {
|
|
125
|
+
hasChanges = true;
|
|
126
|
+
return { ...msg, role: "user" };
|
|
127
|
+
}
|
|
128
|
+
if (VALID_ROLES.has(role)) return msg;
|
|
129
|
+
const mappedRole = ROLE_MAPPINGS[role];
|
|
130
|
+
if (mappedRole) {
|
|
131
|
+
hasChanges = true;
|
|
132
|
+
return { ...msg, role: mappedRole };
|
|
133
|
+
}
|
|
134
|
+
hasChanges = true;
|
|
135
|
+
return { ...msg, role: "user" };
|
|
136
|
+
});
|
|
137
|
+
return hasChanges ? normalized : messages;
|
|
138
|
+
}
|
|
111
139
|
function readBody(req) {
|
|
112
140
|
return new Promise((resolve, reject) => {
|
|
113
141
|
const chunks = [];
|
|
@@ -136,17 +164,51 @@ function normalizePayloadForGateway(body) {
|
|
|
136
164
|
try {
|
|
137
165
|
const parsed = JSON.parse(body.toString("utf-8"));
|
|
138
166
|
if (parsed.stream === true) parsed.stream = false;
|
|
167
|
+
if (Array.isArray(parsed.messages)) {
|
|
168
|
+
parsed.messages = normalizeMessageRoles(parsed.messages);
|
|
169
|
+
}
|
|
139
170
|
return Buffer.from(JSON.stringify(parsed));
|
|
140
171
|
} catch {
|
|
141
172
|
return body;
|
|
142
173
|
}
|
|
143
174
|
}
|
|
175
|
+
function parseJsonIfPossible(text) {
|
|
176
|
+
try {
|
|
177
|
+
return JSON.parse(text);
|
|
178
|
+
} catch {
|
|
179
|
+
return text;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
function safeHeadersObject(headers) {
|
|
183
|
+
const out = {};
|
|
184
|
+
headers.forEach((value, key) => {
|
|
185
|
+
out[key] = value;
|
|
186
|
+
});
|
|
187
|
+
return out;
|
|
188
|
+
}
|
|
189
|
+
function createCaptureWriter() {
|
|
190
|
+
const enabled = process.env.GATEWAY_CAPTURE === "1" || process.env.GATEWAY_CAPTURE === "true";
|
|
191
|
+
const file = (process.env.GATEWAY_CAPTURE_FILE || "/tmp/clawcredit-blockrun-gateway/.run/capture.jsonl").trim();
|
|
192
|
+
if (!enabled) {
|
|
193
|
+
return (_entry) => {
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
mkdirSync(dirname(file), { recursive: true });
|
|
197
|
+
return (entry) => {
|
|
198
|
+
try {
|
|
199
|
+
appendFileSync(file, `${JSON.stringify(entry)}
|
|
200
|
+
`, "utf-8");
|
|
201
|
+
} catch {
|
|
202
|
+
}
|
|
203
|
+
};
|
|
204
|
+
}
|
|
144
205
|
async function startGateway(options) {
|
|
145
206
|
const host = options.host ?? "127.0.0.1";
|
|
146
207
|
const port = options.port ?? 3402;
|
|
147
208
|
const apiBase = (options.blockrunApiBase ?? "https://blockrun.ai/api").replace(/\/+$/, "");
|
|
148
209
|
const defaultAmountUsd = Number.isFinite(options.defaultAmountUsd) ? Number(options.defaultAmountUsd) : 0.1;
|
|
149
210
|
const payFetch = createClawCreditFetch(options.clawCredit);
|
|
211
|
+
const writeCapture = createCaptureWriter();
|
|
150
212
|
const server = createServer(async (req, res) => {
|
|
151
213
|
if (req.url === "/health") {
|
|
152
214
|
return sendJson(res, 200, {
|
|
@@ -159,8 +221,11 @@ async function startGateway(options) {
|
|
|
159
221
|
return sendJson(res, 404, { error: "Not found" });
|
|
160
222
|
}
|
|
161
223
|
try {
|
|
224
|
+
const requestId = randomUUID();
|
|
225
|
+
const startedAt = Date.now();
|
|
162
226
|
const body = await readBody(req);
|
|
163
227
|
const normalized = normalizePayloadForGateway(body);
|
|
228
|
+
const normalizedText = normalized.toString("utf-8");
|
|
164
229
|
const maxTokens = extractMaxTokens(normalized);
|
|
165
230
|
const estimatedMicros = String(
|
|
166
231
|
Math.max(1e4, Math.round(defaultAmountUsd * 1e6 + maxTokens * 8))
|
|
@@ -176,6 +241,20 @@ async function startGateway(options) {
|
|
|
176
241
|
if (!headers.has("content-type")) {
|
|
177
242
|
headers.set("content-type", "application/json");
|
|
178
243
|
}
|
|
244
|
+
writeCapture({
|
|
245
|
+
kind: "request",
|
|
246
|
+
requestId,
|
|
247
|
+
at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
248
|
+
source: {
|
|
249
|
+
userAgent: req.headers["user-agent"] || null,
|
|
250
|
+
xOpenClawSession: req.headers["x-openclaw-session-id"] || null
|
|
251
|
+
},
|
|
252
|
+
method: "POST",
|
|
253
|
+
target: upstreamUrl,
|
|
254
|
+
estimatedMicros,
|
|
255
|
+
headers: safeHeadersObject(headers),
|
|
256
|
+
body: parseJsonIfPossible(normalizedText)
|
|
257
|
+
});
|
|
179
258
|
const upstream = await payFetch(
|
|
180
259
|
upstreamUrl,
|
|
181
260
|
{
|
|
@@ -186,12 +265,26 @@ async function startGateway(options) {
|
|
|
186
265
|
{ estimatedAmount: estimatedMicros }
|
|
187
266
|
);
|
|
188
267
|
const responseBody = await upstream.text();
|
|
268
|
+
writeCapture({
|
|
269
|
+
kind: "response",
|
|
270
|
+
requestId,
|
|
271
|
+
at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
272
|
+
durationMs: Date.now() - startedAt,
|
|
273
|
+
status: upstream.status,
|
|
274
|
+
headers: safeHeadersObject(upstream.headers),
|
|
275
|
+
body: parseJsonIfPossible(responseBody)
|
|
276
|
+
});
|
|
189
277
|
res.writeHead(upstream.status, {
|
|
190
278
|
"content-type": upstream.headers.get("content-type") || "application/json"
|
|
191
279
|
});
|
|
192
280
|
res.end(responseBody);
|
|
193
281
|
} catch (err) {
|
|
194
282
|
const msg = err instanceof Error ? err.message : String(err);
|
|
283
|
+
writeCapture({
|
|
284
|
+
kind: "error",
|
|
285
|
+
at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
286
|
+
message: msg
|
|
287
|
+
});
|
|
195
288
|
sendJson(res, 502, { error: msg });
|
|
196
289
|
}
|
|
197
290
|
});
|
|
@@ -214,4 +307,4 @@ export {
|
|
|
214
307
|
createClawCreditFetch,
|
|
215
308
|
startGateway
|
|
216
309
|
};
|
|
217
|
-
//# sourceMappingURL=chunk-
|
|
310
|
+
//# sourceMappingURL=chunk-VFHQPROQ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/clawcredit.ts","../src/server.ts"],"sourcesContent":["import { ClawCredit, withTrace } from \"@t54-labs/clawcredit-sdk\";\n\nconst DEFAULT_SERVICE_URL = \"https://api.claw.credit\";\n\nexport type ClawCreditConfig = {\n baseUrl?: string;\n apiToken: string;\n chain: string;\n asset: string;\n agent?: string;\n agentId?: string;\n};\n\nexport type PreAuthParams = {\n estimatedAmount: string;\n};\n\ntype SdkClient = {\n pay: (args: {\n transaction: {\n recipient: string;\n amount: number;\n chain: string;\n asset: string;\n amount_unit?: \"human\" | \"atomic\";\n };\n request_body: Record<string, unknown>;\n context?: {\n reasoning_process?: string;\n current_task?: string;\n };\n idempotencyKey?: string;\n }) => Promise<{ merchant_response?: unknown }>;\n};\n\nfunction headersToObject(headersInit?: HeadersInit): Record<string, string> {\n if (!headersInit) return {};\n const headers = new Headers(headersInit);\n const out: Record<string, string> = {};\n headers.forEach((value, key) => {\n const lower = key.toLowerCase();\n if (lower === \"host\" || lower === \"content-length\" || lower === \"connection\") return;\n out[key] = value;\n });\n return out;\n}\n\nfunction parseJsonBody(body: RequestInit[\"body\"]): unknown {\n if (body == null) return undefined;\n\n let raw = \"\";\n if (typeof body === \"string\") {\n raw = body;\n } else if (body instanceof Uint8Array) {\n raw = Buffer.from(body).toString(\"utf-8\");\n } else if (body instanceof ArrayBuffer) {\n raw = Buffer.from(body).toString(\"utf-8\");\n } else {\n return undefined;\n }\n\n if (!raw.trim()) return undefined;\n try {\n return JSON.parse(raw);\n } catch {\n return undefined;\n }\n}\n\nfunction microsToUsd(estimatedAmount?: string): number {\n const micros = Number(estimatedAmount ?? \"\");\n if (!Number.isFinite(micros) || micros <= 0) return 0.01;\n return Number((micros / 1_000_000).toFixed(6));\n}\n\nfunction inferStatusCode(err: unknown): number {\n const msg = err instanceof Error ? err.message : String(err);\n const match = msg.match(/ClawCredit API Error:\\s*(\\d{3})\\s*-/i);\n if (match) return parseInt(match[1], 10);\n if (/payment required/i.test(msg)) return 402;\n if (/prequalification_pending/i.test(msg)) return 403;\n if (/unauthorized/i.test(msg)) return 401;\n return 502;\n}\n\nexport function createClawCreditFetch(config: ClawCreditConfig) {\n const serviceUrl = (config.baseUrl || DEFAULT_SERVICE_URL).replace(/\\/+$/, \"\");\n const chain = config.chain.toUpperCase();\n const asset = config.asset;\n const apiToken = config.apiToken.trim();\n\n if (!apiToken) {\n throw new Error(\"CLAWCREDIT_API_TOKEN is required for claw.credit payment mode\");\n }\n\n const credit = new ClawCredit({\n serviceUrl,\n apiToken,\n agent: config.agent,\n agentId: config.agentId,\n }) as SdkClient;\n\n return async (\n input: RequestInfo | URL,\n init?: RequestInit,\n preAuth?: PreAuthParams,\n ): Promise<Response> => {\n const upstreamUrl =\n typeof input === \"string\" ? input : input instanceof URL ? input.href : input.url;\n const method = (init?.method || \"POST\").toUpperCase();\n const headers = headersToObject(init?.headers);\n const idempotencyKey = new Headers(init?.headers).get(\"idempotency-key\") || undefined;\n const requestBody = parseJsonBody(init?.body);\n const amountUsd = microsToUsd(preAuth?.estimatedAmount);\n\n try {\n const result = await withTrace(async () =>\n credit.pay({\n transaction: {\n recipient: upstreamUrl,\n amount: amountUsd,\n chain,\n asset,\n },\n request_body: {\n http: {\n url: upstreamUrl,\n method,\n headers,\n },\n body: requestBody,\n },\n context: {\n current_task: \"blockrun_inference_via_clawcredit_blockrun_gateway\",\n reasoning_process: \"Pay BlockRun inference through claw.credit SDK\",\n },\n idempotencyKey,\n }),\n );\n\n const merchantResponse =\n result && typeof result === \"object\" && \"merchant_response\" in result\n ? (result as { merchant_response?: unknown }).merchant_response\n : result;\n\n return new Response(JSON.stringify(merchantResponse ?? {}), {\n status: 200,\n headers: { \"content-type\": \"application/json\" },\n });\n } catch (err) {\n const status = inferStatusCode(err);\n const message = err instanceof Error ? err.message : String(err);\n return new Response(JSON.stringify({ error: message }), {\n status,\n headers: { \"content-type\": \"application/json\" },\n });\n }\n };\n}\n","import { createServer, type IncomingMessage, type ServerResponse } from \"node:http\";\nimport type { AddressInfo } from \"node:net\";\nimport { appendFileSync, mkdirSync } from \"node:fs\";\nimport { dirname } from \"node:path\";\nimport { randomUUID } from \"node:crypto\";\nimport { createClawCreditFetch, type ClawCreditConfig } from \"./clawcredit.js\";\n\nexport type GatewayOptions = {\n port?: number;\n host?: string;\n blockrunApiBase?: string;\n clawCredit: ClawCreditConfig;\n defaultAmountUsd?: number;\n};\n\nexport type GatewayInstance = {\n port: number;\n baseUrl: string;\n close: () => Promise<void>;\n};\n\ntype CompletionRequest = {\n model?: string;\n stream?: boolean;\n max_tokens?: number;\n messages?: Array<Record<string, unknown>>;\n};\n\nconst VALID_ROLES = new Set([\"system\", \"user\", \"assistant\", \"tool\", \"function\"]);\nconst ROLE_MAPPINGS: Record<string, string> = {\n developer: \"system\",\n model: \"assistant\",\n};\n\nfunction normalizeMessageRoles(messages: Array<Record<string, unknown>>): Array<Record<string, unknown>> {\n if (messages.length === 0) return messages;\n\n let hasChanges = false;\n const normalized = messages.map((msg) => {\n const role = msg.role;\n if (typeof role !== \"string\") {\n hasChanges = true;\n return { ...msg, role: \"user\" };\n }\n if (VALID_ROLES.has(role)) return msg;\n\n const mappedRole = ROLE_MAPPINGS[role];\n if (mappedRole) {\n hasChanges = true;\n return { ...msg, role: mappedRole };\n }\n\n hasChanges = true;\n return { ...msg, role: \"user\" };\n });\n\n return hasChanges ? normalized : messages;\n}\n\nfunction readBody(req: IncomingMessage): Promise<Buffer> {\n return new Promise((resolve, reject) => {\n const chunks: Buffer[] = [];\n req.on(\"data\", (chunk) => chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk)));\n req.on(\"end\", () => resolve(Buffer.concat(chunks)));\n req.on(\"error\", reject);\n });\n}\n\nfunction sendJson(res: ServerResponse, status: number, payload: unknown): void {\n const text = JSON.stringify(payload);\n res.writeHead(status, {\n \"content-type\": \"application/json\",\n \"content-length\": Buffer.byteLength(text).toString(),\n });\n res.end(text);\n}\n\nfunction extractMaxTokens(body: Buffer): number {\n try {\n const parsed = JSON.parse(body.toString(\"utf-8\")) as CompletionRequest;\n return parsed.max_tokens && Number.isFinite(parsed.max_tokens) ? parsed.max_tokens : 512;\n } catch {\n return 512;\n }\n}\n\nfunction normalizePayloadForGateway(body: Buffer): Buffer {\n try {\n const parsed = JSON.parse(body.toString(\"utf-8\")) as CompletionRequest;\n if (parsed.stream === true) parsed.stream = false;\n if (Array.isArray(parsed.messages)) {\n parsed.messages = normalizeMessageRoles(parsed.messages);\n }\n return Buffer.from(JSON.stringify(parsed));\n } catch {\n return body;\n }\n}\n\nfunction parseJsonIfPossible(text: string): unknown {\n try {\n return JSON.parse(text);\n } catch {\n return text;\n }\n}\n\nfunction safeHeadersObject(headers: Headers): Record<string, string> {\n const out: Record<string, string> = {};\n headers.forEach((value, key) => {\n out[key] = value;\n });\n return out;\n}\n\nfunction createCaptureWriter() {\n const enabled =\n process.env.GATEWAY_CAPTURE === \"1\" || process.env.GATEWAY_CAPTURE === \"true\";\n const file =\n (process.env.GATEWAY_CAPTURE_FILE || \"/tmp/clawcredit-blockrun-gateway/.run/capture.jsonl\").trim();\n\n if (!enabled) {\n return (_entry: unknown) => {};\n }\n\n mkdirSync(dirname(file), { recursive: true });\n return (entry: unknown) => {\n try {\n appendFileSync(file, `${JSON.stringify(entry)}\\n`, \"utf-8\");\n } catch {\n // Best-effort debug capture only.\n }\n };\n}\n\nexport async function startGateway(options: GatewayOptions): Promise<GatewayInstance> {\n const host = options.host ?? \"127.0.0.1\";\n const port = options.port ?? 3402;\n const apiBase = (options.blockrunApiBase ?? \"https://blockrun.ai/api\").replace(/\\/+$/, \"\");\n const defaultAmountUsd = Number.isFinite(options.defaultAmountUsd)\n ? Number(options.defaultAmountUsd)\n : 0.1;\n const payFetch = createClawCreditFetch(options.clawCredit);\n const writeCapture = createCaptureWriter();\n\n const server = createServer(async (req, res) => {\n if (req.url === \"/health\") {\n return sendJson(res, 200, {\n status: \"ok\",\n service: \"clawcredit-blockrun-gateway\",\n payment_mode: \"clawcredit\",\n });\n }\n\n if (req.url !== \"/v1/chat/completions\" || req.method !== \"POST\") {\n return sendJson(res, 404, { error: \"Not found\" });\n }\n\n try {\n const requestId = randomUUID();\n const startedAt = Date.now();\n const body = await readBody(req);\n const normalized = normalizePayloadForGateway(body);\n const normalizedText = normalized.toString(\"utf-8\");\n const maxTokens = extractMaxTokens(normalized);\n\n const estimatedMicros = String(\n Math.max(10_000, Math.round(defaultAmountUsd * 1_000_000 + maxTokens * 8)),\n );\n\n const upstreamUrl = `${apiBase}/v1/chat/completions`;\n\n const headers = new Headers();\n for (const [key, value] of Object.entries(req.headers)) {\n if (typeof value !== \"string\") continue;\n const lower = key.toLowerCase();\n if (lower === \"host\" || lower === \"content-length\" || lower === \"connection\") continue;\n headers.set(key, value);\n }\n if (!headers.has(\"content-type\")) {\n headers.set(\"content-type\", \"application/json\");\n }\n\n writeCapture({\n kind: \"request\",\n requestId,\n at: new Date().toISOString(),\n source: {\n userAgent: req.headers[\"user-agent\"] || null,\n xOpenClawSession: req.headers[\"x-openclaw-session-id\"] || null,\n },\n method: \"POST\",\n target: upstreamUrl,\n estimatedMicros,\n headers: safeHeadersObject(headers),\n body: parseJsonIfPossible(normalizedText),\n });\n\n const upstream = await payFetch(\n upstreamUrl,\n {\n method: \"POST\",\n headers,\n body: new Uint8Array(normalized),\n },\n { estimatedAmount: estimatedMicros },\n );\n\n const responseBody = await upstream.text();\n writeCapture({\n kind: \"response\",\n requestId,\n at: new Date().toISOString(),\n durationMs: Date.now() - startedAt,\n status: upstream.status,\n headers: safeHeadersObject(upstream.headers),\n body: parseJsonIfPossible(responseBody),\n });\n res.writeHead(upstream.status, {\n \"content-type\": upstream.headers.get(\"content-type\") || \"application/json\",\n });\n res.end(responseBody);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n writeCapture({\n kind: \"error\",\n at: new Date().toISOString(),\n message: msg,\n });\n sendJson(res, 502, { error: msg });\n }\n });\n\n await new Promise<void>((resolve, reject) => {\n server.once(\"error\", reject);\n server.listen(port, host, () => {\n server.removeListener(\"error\", reject);\n resolve();\n });\n });\n\n const actualPort = (server.address() as AddressInfo).port;\n return {\n port: actualPort,\n baseUrl: `http://${host}:${actualPort}`,\n close: () => new Promise<void>((resolve, reject) => server.close((err) => (err ? reject(err) : resolve()))),\n };\n}\n"],"mappings":"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","names":[]}
|
package/dist/cli.js
CHANGED
package/dist/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/clawcredit.ts","../src/server.ts"],"sourcesContent":["import { ClawCredit, withTrace } from \"@t54-labs/clawcredit-sdk\";\n\nconst DEFAULT_SERVICE_URL = \"https://api.claw.credit\";\n\nexport type ClawCreditConfig = {\n baseUrl?: string;\n apiToken: string;\n chain: string;\n asset: string;\n agent?: string;\n agentId?: string;\n};\n\nexport type PreAuthParams = {\n estimatedAmount: string;\n};\n\ntype SdkClient = {\n pay: (args: {\n transaction: {\n recipient: string;\n amount: number;\n chain: string;\n asset: string;\n amount_unit?: \"human\" | \"atomic\";\n };\n request_body: Record<string, unknown>;\n context?: {\n reasoning_process?: string;\n current_task?: string;\n };\n idempotencyKey?: string;\n }) => Promise<{ merchant_response?: unknown }>;\n};\n\nfunction headersToObject(headersInit?: HeadersInit): Record<string, string> {\n if (!headersInit) return {};\n const headers = new Headers(headersInit);\n const out: Record<string, string> = {};\n headers.forEach((value, key) => {\n const lower = key.toLowerCase();\n if (lower === \"host\" || lower === \"content-length\" || lower === \"connection\") return;\n out[key] = value;\n });\n return out;\n}\n\nfunction parseJsonBody(body: RequestInit[\"body\"]): unknown {\n if (body == null) return undefined;\n\n let raw = \"\";\n if (typeof body === \"string\") {\n raw = body;\n } else if (body instanceof Uint8Array) {\n raw = Buffer.from(body).toString(\"utf-8\");\n } else if (body instanceof ArrayBuffer) {\n raw = Buffer.from(body).toString(\"utf-8\");\n } else {\n return undefined;\n }\n\n if (!raw.trim()) return undefined;\n try {\n return JSON.parse(raw);\n } catch {\n return undefined;\n }\n}\n\nfunction microsToUsd(estimatedAmount?: string): number {\n const micros = Number(estimatedAmount ?? \"\");\n if (!Number.isFinite(micros) || micros <= 0) return 0.01;\n return Number((micros / 1_000_000).toFixed(6));\n}\n\nfunction inferStatusCode(err: unknown): number {\n const msg = err instanceof Error ? err.message : String(err);\n const match = msg.match(/ClawCredit API Error:\\s*(\\d{3})\\s*-/i);\n if (match) return parseInt(match[1], 10);\n if (/payment required/i.test(msg)) return 402;\n if (/prequalification_pending/i.test(msg)) return 403;\n if (/unauthorized/i.test(msg)) return 401;\n return 502;\n}\n\nexport function createClawCreditFetch(config: ClawCreditConfig) {\n const serviceUrl = (config.baseUrl || DEFAULT_SERVICE_URL).replace(/\\/+$/, \"\");\n const chain = config.chain.toUpperCase();\n const asset = config.asset;\n const apiToken = config.apiToken.trim();\n\n if (!apiToken) {\n throw new Error(\"CLAWCREDIT_API_TOKEN is required for claw.credit payment mode\");\n }\n\n const credit = new ClawCredit({\n serviceUrl,\n apiToken,\n agent: config.agent,\n agentId: config.agentId,\n }) as SdkClient;\n\n return async (\n input: RequestInfo | URL,\n init?: RequestInit,\n preAuth?: PreAuthParams,\n ): Promise<Response> => {\n const upstreamUrl =\n typeof input === \"string\" ? input : input instanceof URL ? input.href : input.url;\n const method = (init?.method || \"POST\").toUpperCase();\n const headers = headersToObject(init?.headers);\n const idempotencyKey = new Headers(init?.headers).get(\"idempotency-key\") || undefined;\n const requestBody = parseJsonBody(init?.body);\n const amountUsd = microsToUsd(preAuth?.estimatedAmount);\n\n try {\n const result = await withTrace(async () =>\n credit.pay({\n transaction: {\n recipient: upstreamUrl,\n amount: amountUsd,\n chain,\n asset,\n },\n request_body: {\n http: {\n url: upstreamUrl,\n method,\n headers,\n },\n body: requestBody,\n },\n context: {\n current_task: \"blockrun_inference_via_clawcredit_blockrun_gateway\",\n reasoning_process: \"Pay BlockRun inference through claw.credit SDK\",\n },\n idempotencyKey,\n }),\n );\n\n const merchantResponse =\n result && typeof result === \"object\" && \"merchant_response\" in result\n ? (result as { merchant_response?: unknown }).merchant_response\n : result;\n\n return new Response(JSON.stringify(merchantResponse ?? {}), {\n status: 200,\n headers: { \"content-type\": \"application/json\" },\n });\n } catch (err) {\n const status = inferStatusCode(err);\n const message = err instanceof Error ? err.message : String(err);\n return new Response(JSON.stringify({ error: message }), {\n status,\n headers: { \"content-type\": \"application/json\" },\n });\n }\n };\n}\n","import { createServer, type IncomingMessage, type ServerResponse } from \"node:http\";\nimport type { AddressInfo } from \"node:net\";\nimport { createClawCreditFetch, type ClawCreditConfig } from \"./clawcredit.js\";\n\nexport type GatewayOptions = {\n port?: number;\n host?: string;\n blockrunApiBase?: string;\n clawCredit: ClawCreditConfig;\n defaultAmountUsd?: number;\n};\n\nexport type GatewayInstance = {\n port: number;\n baseUrl: string;\n close: () => Promise<void>;\n};\n\ntype CompletionRequest = {\n model?: string;\n stream?: boolean;\n max_tokens?: number;\n};\n\nfunction readBody(req: IncomingMessage): Promise<Buffer> {\n return new Promise((resolve, reject) => {\n const chunks: Buffer[] = [];\n req.on(\"data\", (chunk) => chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk)));\n req.on(\"end\", () => resolve(Buffer.concat(chunks)));\n req.on(\"error\", reject);\n });\n}\n\nfunction sendJson(res: ServerResponse, status: number, payload: unknown): void {\n const text = JSON.stringify(payload);\n res.writeHead(status, {\n \"content-type\": \"application/json\",\n \"content-length\": Buffer.byteLength(text).toString(),\n });\n res.end(text);\n}\n\nfunction extractMaxTokens(body: Buffer): number {\n try {\n const parsed = JSON.parse(body.toString(\"utf-8\")) as CompletionRequest;\n return parsed.max_tokens && Number.isFinite(parsed.max_tokens) ? parsed.max_tokens : 512;\n } catch {\n return 512;\n }\n}\n\nfunction normalizePayloadForGateway(body: Buffer): Buffer {\n try {\n const parsed = JSON.parse(body.toString(\"utf-8\")) as CompletionRequest;\n if (parsed.stream === true) parsed.stream = false;\n return Buffer.from(JSON.stringify(parsed));\n } catch {\n return body;\n }\n}\n\nexport async function startGateway(options: GatewayOptions): Promise<GatewayInstance> {\n const host = options.host ?? \"127.0.0.1\";\n const port = options.port ?? 3402;\n const apiBase = (options.blockrunApiBase ?? \"https://blockrun.ai/api\").replace(/\\/+$/, \"\");\n const defaultAmountUsd = Number.isFinite(options.defaultAmountUsd)\n ? Number(options.defaultAmountUsd)\n : 0.1;\n const payFetch = createClawCreditFetch(options.clawCredit);\n\n const server = createServer(async (req, res) => {\n if (req.url === \"/health\") {\n return sendJson(res, 200, {\n status: \"ok\",\n service: \"clawcredit-blockrun-gateway\",\n payment_mode: \"clawcredit\",\n });\n }\n\n if (req.url !== \"/v1/chat/completions\" || req.method !== \"POST\") {\n return sendJson(res, 404, { error: \"Not found\" });\n }\n\n try {\n const body = await readBody(req);\n const normalized = normalizePayloadForGateway(body);\n const maxTokens = extractMaxTokens(normalized);\n\n const estimatedMicros = String(\n Math.max(10_000, Math.round(defaultAmountUsd * 1_000_000 + maxTokens * 8)),\n );\n\n const upstreamUrl = `${apiBase}/v1/chat/completions`;\n\n const headers = new Headers();\n for (const [key, value] of Object.entries(req.headers)) {\n if (typeof value !== \"string\") continue;\n const lower = key.toLowerCase();\n if (lower === \"host\" || lower === \"content-length\" || lower === \"connection\") continue;\n headers.set(key, value);\n }\n if (!headers.has(\"content-type\")) {\n headers.set(\"content-type\", \"application/json\");\n }\n\n const upstream = await payFetch(\n upstreamUrl,\n {\n method: \"POST\",\n headers,\n body: new Uint8Array(normalized),\n },\n { estimatedAmount: estimatedMicros },\n );\n\n const responseBody = await upstream.text();\n res.writeHead(upstream.status, {\n \"content-type\": upstream.headers.get(\"content-type\") || \"application/json\",\n });\n res.end(responseBody);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n sendJson(res, 502, { error: msg });\n }\n });\n\n await new Promise<void>((resolve, reject) => {\n server.once(\"error\", reject);\n server.listen(port, host, () => {\n server.removeListener(\"error\", reject);\n resolve();\n });\n });\n\n const actualPort = (server.address() as AddressInfo).port;\n return {\n port: actualPort,\n baseUrl: `http://${host}:${actualPort}`,\n close: () => new Promise<void>((resolve, reject) => server.close((err) => (err ? reject(err) : resolve()))),\n };\n}\n"],"mappings":";AAAA,SAAS,YAAY,iBAAiB;AAEtC,IAAM,sBAAsB;AAiC5B,SAAS,gBAAgB,aAAmD;AAC1E,MAAI,CAAC,YAAa,QAAO,CAAC;AAC1B,QAAM,UAAU,IAAI,QAAQ,WAAW;AACvC,QAAM,MAA8B,CAAC;AACrC,UAAQ,QAAQ,CAAC,OAAO,QAAQ;AAC9B,UAAM,QAAQ,IAAI,YAAY;AAC9B,QAAI,UAAU,UAAU,UAAU,oBAAoB,UAAU,aAAc;AAC9E,QAAI,GAAG,IAAI;AAAA,EACb,CAAC;AACD,SAAO;AACT;AAEA,SAAS,cAAc,MAAoC;AACzD,MAAI,QAAQ,KAAM,QAAO;AAEzB,MAAI,MAAM;AACV,MAAI,OAAO,SAAS,UAAU;AAC5B,UAAM;AAAA,EACR,WAAW,gBAAgB,YAAY;AACrC,UAAM,OAAO,KAAK,IAAI,EAAE,SAAS,OAAO;AAAA,EAC1C,WAAW,gBAAgB,aAAa;AACtC,UAAM,OAAO,KAAK,IAAI,EAAE,SAAS,OAAO;AAAA,EAC1C,OAAO;AACL,WAAO;AAAA,EACT;AAEA,MAAI,CAAC,IAAI,KAAK,EAAG,QAAO;AACxB,MAAI;AACF,WAAO,KAAK,MAAM,GAAG;AAAA,EACvB,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,SAAS,YAAY,iBAAkC;AACrD,QAAM,SAAS,OAAO,mBAAmB,EAAE;AAC3C,MAAI,CAAC,OAAO,SAAS,MAAM,KAAK,UAAU,EAAG,QAAO;AACpD,SAAO,QAAQ,SAAS,KAAW,QAAQ,CAAC,CAAC;AAC/C;AAEA,SAAS,gBAAgB,KAAsB;AAC7C,QAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC3D,QAAM,QAAQ,IAAI,MAAM,sCAAsC;AAC9D,MAAI,MAAO,QAAO,SAAS,MAAM,CAAC,GAAG,EAAE;AACvC,MAAI,oBAAoB,KAAK,GAAG,EAAG,QAAO;AAC1C,MAAI,4BAA4B,KAAK,GAAG,EAAG,QAAO;AAClD,MAAI,gBAAgB,KAAK,GAAG,EAAG,QAAO;AACtC,SAAO;AACT;AAEO,SAAS,sBAAsB,QAA0B;AAC9D,QAAM,cAAc,OAAO,WAAW,qBAAqB,QAAQ,QAAQ,EAAE;AAC7E,QAAM,QAAQ,OAAO,MAAM,YAAY;AACvC,QAAM,QAAQ,OAAO;AACrB,QAAM,WAAW,OAAO,SAAS,KAAK;AAEtC,MAAI,CAAC,UAAU;AACb,UAAM,IAAI,MAAM,+DAA+D;AAAA,EACjF;AAEA,QAAM,SAAS,IAAI,WAAW;AAAA,IAC5B;AAAA,IACA;AAAA,IACA,OAAO,OAAO;AAAA,IACd,SAAS,OAAO;AAAA,EAClB,CAAC;AAED,SAAO,OACL,OACA,MACA,YACsB;AACtB,UAAM,cACJ,OAAO,UAAU,WAAW,QAAQ,iBAAiB,MAAM,MAAM,OAAO,MAAM;AAChF,UAAM,UAAU,MAAM,UAAU,QAAQ,YAAY;AACpD,UAAM,UAAU,gBAAgB,MAAM,OAAO;AAC7C,UAAM,iBAAiB,IAAI,QAAQ,MAAM,OAAO,EAAE,IAAI,iBAAiB,KAAK;AAC5E,UAAM,cAAc,cAAc,MAAM,IAAI;AAC5C,UAAM,YAAY,YAAY,SAAS,eAAe;AAEtD,QAAI;AACF,YAAM,SAAS,MAAM;AAAA,QAAU,YAC7B,OAAO,IAAI;AAAA,UACT,aAAa;AAAA,YACX,WAAW;AAAA,YACX,QAAQ;AAAA,YACR;AAAA,YACA;AAAA,UACF;AAAA,UACA,cAAc;AAAA,YACZ,MAAM;AAAA,cACJ,KAAK;AAAA,cACL;AAAA,cACA;AAAA,YACF;AAAA,YACA,MAAM;AAAA,UACR;AAAA,UACA,SAAS;AAAA,YACP,cAAc;AAAA,YACd,mBAAmB;AAAA,UACrB;AAAA,UACA;AAAA,QACF,CAAC;AAAA,MACH;AAEA,YAAM,mBACJ,UAAU,OAAO,WAAW,YAAY,uBAAuB,SAC1D,OAA2C,oBAC5C;AAEN,aAAO,IAAI,SAAS,KAAK,UAAU,oBAAoB,CAAC,CAAC,GAAG;AAAA,QAC1D,QAAQ;AAAA,QACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,MAChD,CAAC;AAAA,IACH,SAAS,KAAK;AACZ,YAAM,SAAS,gBAAgB,GAAG;AAClC,YAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC/D,aAAO,IAAI,SAAS,KAAK,UAAU,EAAE,OAAO,QAAQ,CAAC,GAAG;AAAA,QACtD;AAAA,QACA,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,MAChD,CAAC;AAAA,IACH;AAAA,EACF;AACF;;;AC9JA,SAAS,oBAA+D;AAwBxE,SAAS,SAAS,KAAuC;AACvD,SAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,UAAM,SAAmB,CAAC;AAC1B,QAAI,GAAG,QAAQ,CAAC,UAAU,OAAO,KAAK,OAAO,SAAS,KAAK,IAAI,QAAQ,OAAO,KAAK,KAAK,CAAC,CAAC;AAC1F,QAAI,GAAG,OAAO,MAAM,QAAQ,OAAO,OAAO,MAAM,CAAC,CAAC;AAClD,QAAI,GAAG,SAAS,MAAM;AAAA,EACxB,CAAC;AACH;AAEA,SAAS,SAAS,KAAqB,QAAgB,SAAwB;AAC7E,QAAM,OAAO,KAAK,UAAU,OAAO;AACnC,MAAI,UAAU,QAAQ;AAAA,IACpB,gBAAgB;AAAA,IAChB,kBAAkB,OAAO,WAAW,IAAI,EAAE,SAAS;AAAA,EACrD,CAAC;AACD,MAAI,IAAI,IAAI;AACd;AAEA,SAAS,iBAAiB,MAAsB;AAC9C,MAAI;AACF,UAAM,SAAS,KAAK,MAAM,KAAK,SAAS,OAAO,CAAC;AAChD,WAAO,OAAO,cAAc,OAAO,SAAS,OAAO,UAAU,IAAI,OAAO,aAAa;AAAA,EACvF,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,SAAS,2BAA2B,MAAsB;AACxD,MAAI;AACF,UAAM,SAAS,KAAK,MAAM,KAAK,SAAS,OAAO,CAAC;AAChD,QAAI,OAAO,WAAW,KAAM,QAAO,SAAS;AAC5C,WAAO,OAAO,KAAK,KAAK,UAAU,MAAM,CAAC;AAAA,EAC3C,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,eAAsB,aAAa,SAAmD;AACpF,QAAM,OAAO,QAAQ,QAAQ;AAC7B,QAAM,OAAO,QAAQ,QAAQ;AAC7B,QAAM,WAAW,QAAQ,mBAAmB,2BAA2B,QAAQ,QAAQ,EAAE;AACzF,QAAM,mBAAmB,OAAO,SAAS,QAAQ,gBAAgB,IAC7D,OAAO,QAAQ,gBAAgB,IAC/B;AACJ,QAAM,WAAW,sBAAsB,QAAQ,UAAU;AAEzD,QAAM,SAAS,aAAa,OAAO,KAAK,QAAQ;AAC9C,QAAI,IAAI,QAAQ,WAAW;AACzB,aAAO,SAAS,KAAK,KAAK;AAAA,QACxB,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,cAAc;AAAA,MAChB,CAAC;AAAA,IACH;AAEA,QAAI,IAAI,QAAQ,0BAA0B,IAAI,WAAW,QAAQ;AAC/D,aAAO,SAAS,KAAK,KAAK,EAAE,OAAO,YAAY,CAAC;AAAA,IAClD;AAEA,QAAI;AACF,YAAM,OAAO,MAAM,SAAS,GAAG;AAC/B,YAAM,aAAa,2BAA2B,IAAI;AAClD,YAAM,YAAY,iBAAiB,UAAU;AAE7C,YAAM,kBAAkB;AAAA,QACtB,KAAK,IAAI,KAAQ,KAAK,MAAM,mBAAmB,MAAY,YAAY,CAAC,CAAC;AAAA,MAC3E;AAEA,YAAM,cAAc,GAAG,OAAO;AAE9B,YAAM,UAAU,IAAI,QAAQ;AAC5B,iBAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,IAAI,OAAO,GAAG;AACtD,YAAI,OAAO,UAAU,SAAU;AAC/B,cAAM,QAAQ,IAAI,YAAY;AAC9B,YAAI,UAAU,UAAU,UAAU,oBAAoB,UAAU,aAAc;AAC9E,gBAAQ,IAAI,KAAK,KAAK;AAAA,MACxB;AACA,UAAI,CAAC,QAAQ,IAAI,cAAc,GAAG;AAChC,gBAAQ,IAAI,gBAAgB,kBAAkB;AAAA,MAChD;AAEA,YAAM,WAAW,MAAM;AAAA,QACrB;AAAA,QACA;AAAA,UACE,QAAQ;AAAA,UACR;AAAA,UACA,MAAM,IAAI,WAAW,UAAU;AAAA,QACjC;AAAA,QACA,EAAE,iBAAiB,gBAAgB;AAAA,MACrC;AAEA,YAAM,eAAe,MAAM,SAAS,KAAK;AACzC,UAAI,UAAU,SAAS,QAAQ;AAAA,QAC7B,gBAAgB,SAAS,QAAQ,IAAI,cAAc,KAAK;AAAA,MAC1D,CAAC;AACD,UAAI,IAAI,YAAY;AAAA,IACtB,SAAS,KAAK;AACZ,YAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC3D,eAAS,KAAK,KAAK,EAAE,OAAO,IAAI,CAAC;AAAA,IACnC;AAAA,EACF,CAAC;AAED,QAAM,IAAI,QAAc,CAAC,SAAS,WAAW;AAC3C,WAAO,KAAK,SAAS,MAAM;AAC3B,WAAO,OAAO,MAAM,MAAM,MAAM;AAC9B,aAAO,eAAe,SAAS,MAAM;AACrC,cAAQ;AAAA,IACV,CAAC;AAAA,EACH,CAAC;AAED,QAAM,aAAc,OAAO,QAAQ,EAAkB;AACrD,SAAO;AAAA,IACL,MAAM;AAAA,IACN,SAAS,UAAU,IAAI,IAAI,UAAU;AAAA,IACrC,OAAO,MAAM,IAAI,QAAc,CAAC,SAAS,WAAW,OAAO,MAAM,CAAC,QAAS,MAAM,OAAO,GAAG,IAAI,QAAQ,CAAE,CAAC;AAAA,EAC5G;AACF;","names":[]}
|