@medialane/sdk 0.85.13 → 0.87.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/dist/index.cjs CHANGED
@@ -1308,48 +1308,7 @@ function requestIp(req) {
1308
1308
  return req.headers.get("x-forwarded-for")?.split(",")[0].trim() ?? "unknown";
1309
1309
  }
1310
1310
 
1311
- // src/server/rpc-proxy.ts
1312
- var DEFAULT_STARKNET_RPC_METHODS = [
1313
- "starknet_call",
1314
- "starknet_addInvokeTransaction",
1315
- "starknet_getTransactionReceipt",
1316
- "starknet_getTransactionStatus",
1317
- "starknet_getTransactionByHash",
1318
- "starknet_getTransaction",
1319
- "starknet_getBlockWithReceipts",
1320
- "starknet_estimateFee",
1321
- "starknet_getNonce",
1322
- "starknet_simulateTransactions",
1323
- "starknet_specVersion",
1324
- "starknet_chainId",
1325
- "starknet_blockNumber",
1326
- "starknet_blockHashAndNumber",
1327
- "starknet_getClassAt",
1328
- "starknet_getClass",
1329
- "starknet_getClassHashAt",
1330
- "starknet_getStorageAt",
1331
- "starknet_getBlockWithTxHashes",
1332
- "starknet_getBlockWithTxs",
1333
- "starknet_getEvents"
1334
- ];
1335
- function isAllowedMethod(body, allowed) {
1336
- if (Array.isArray(body)) {
1337
- return body.every((item) => isAllowedMethod(item, allowed));
1338
- }
1339
- if (body && typeof body === "object") {
1340
- const method = body.method;
1341
- return typeof method === "string" && allowed.has(method);
1342
- }
1343
- return false;
1344
- }
1345
- function extractMethod(body) {
1346
- if (Array.isArray(body)) return "batch";
1347
- if (body && typeof body === "object") {
1348
- const method = body.method;
1349
- if (typeof method === "string") return method;
1350
- }
1351
- return "unknown";
1352
- }
1311
+ // src/server/origin.ts
1353
1312
  function isSameOrigin(req) {
1354
1313
  const origin = req.headers.get("origin");
1355
1314
  if (!origin) return true;
@@ -1360,98 +1319,52 @@ function isSameOrigin(req) {
1360
1319
  return false;
1361
1320
  }
1362
1321
  }
1363
- function rpcError(code, message, status = 200, id = null) {
1364
- return Response.json({ jsonrpc: "2.0", error: { code, message }, id }, { status });
1365
- }
1366
- async function billRpcCall(backendUrl, apiKey, method) {
1367
- if (!apiKey) {
1368
- console.error("[rpc-proxy] no API key configured \u2014 refusing to bill/forward");
1369
- return false;
1370
- }
1371
- try {
1372
- const res = await fetch(`${backendUrl.replace(/\/$/, "")}/v1/rpc/meter`, {
1373
- method: "POST",
1374
- headers: { "Content-Type": "application/json", "x-api-key": apiKey },
1375
- body: JSON.stringify({ method })
1376
- });
1377
- return res.ok;
1378
- } catch (err) {
1379
- console.error("[rpc-proxy] billing call failed", { err: err instanceof Error ? err.message : String(err) });
1380
- return false;
1381
- }
1322
+
1323
+ // src/server/backend-proxy.ts
1324
+ function proxyError(code, message, status) {
1325
+ return Response.json({ jsonrpc: "2.0", error: { code, message }, id: null }, { status });
1382
1326
  }
1383
- function createRpcProxyHandler(config) {
1384
- const allowed = new Set(config.allowedMethods ?? DEFAULT_STARKNET_RPC_METHODS);
1385
- return async function handleRpcProxy(req) {
1327
+ function createBackendProxyHandler(config) {
1328
+ const doFetch = config.fetchImpl ?? fetch;
1329
+ const endpoint = `${config.backendUrl.replace(/\/$/, "")}/${config.path.replace(/^\//, "")}`;
1330
+ return async function handleBackendProxy(req) {
1386
1331
  if (!isSameOrigin(req)) {
1387
- return rpcError(-32600, "Cross-origin requests are not allowed", 403);
1332
+ return proxyError(-32600, "Cross-origin requests are not allowed", 403);
1388
1333
  }
1389
1334
  if (!config.checkRateLimit(requestIp(req))) {
1390
- return rpcError(-32005, "Too many requests", 429);
1335
+ return proxyError(-32005, "Too many requests", 429);
1336
+ }
1337
+ if (!config.apiKey) {
1338
+ return proxyError(-32003, "No API key configured \u2014 request not forwarded", 402);
1391
1339
  }
1392
1340
  let body;
1393
1341
  try {
1394
1342
  body = await req.json();
1395
1343
  } catch {
1396
- return rpcError(-32700, "Parse error");
1344
+ return proxyError(-32700, "Parse error", 400);
1397
1345
  }
1398
- if (!isAllowedMethod(body, allowed)) {
1399
- const method2 = !Array.isArray(body) && body && typeof body === "object" ? String(body.method ?? "<unknown>") : "<batch or invalid>";
1400
- return rpcError(-32601, `Method not allowed: ${method2}`);
1401
- }
1402
- const method = extractMethod(body);
1403
- if (!await billRpcCall(config.backendUrl, config.apiKey, method)) {
1404
- return rpcError(-32003, "Insufficient credits or billing unavailable \u2014 RPC call not forwarded", 402);
1405
- }
1406
- let lastError = "No RPC upstream configured";
1407
- for (const rpcUrl of config.rpcUrls) {
1408
- try {
1409
- const response = await fetch(rpcUrl, {
1410
- method: "POST",
1411
- headers: { "Content-Type": "application/json" },
1412
- body: JSON.stringify(body)
1413
- });
1414
- const text = await response.text();
1415
- const upstream = rpcUrl.split("/")[2];
1416
- if (!text) {
1417
- lastError = `Upstream RPC returned empty body (HTTP ${response.status})`;
1418
- console.warn("[rpc-proxy] upstream returned empty body", { status: response.status, upstream });
1419
- continue;
1420
- }
1421
- try {
1422
- const data = JSON.parse(text);
1423
- if (isTransientRpcError({ status: response.status, body: data })) {
1424
- const errObj = data.error;
1425
- lastError = `Upstream RPC returned transient JSON-RPC error: ${String(errObj?.message ?? "(no message)")}`;
1426
- console.warn("[rpc-proxy] upstream returned transient JSON-RPC error", {
1427
- upstream,
1428
- code: errObj?.code,
1429
- message: errObj?.message
1430
- });
1431
- continue;
1432
- }
1433
- return Response.json(data, { status: 200 });
1434
- } catch {
1435
- lastError = `Upstream RPC returned non-JSON (HTTP ${response.status})`;
1436
- console.warn("[rpc-proxy] upstream returned non-JSON", {
1437
- status: response.status,
1438
- upstream,
1439
- bodyPreview: text.slice(0, 200)
1440
- });
1441
- continue;
1442
- }
1443
- } catch (err) {
1444
- lastError = `Upstream RPC unreachable: ${err instanceof Error ? err.message : "unknown error"}`;
1445
- console.warn("[rpc-proxy] upstream fetch failed", {
1446
- upstream: rpcUrl.split("/")[2],
1447
- err: err instanceof Error ? err.message : String(err)
1448
- });
1449
- }
1346
+ try {
1347
+ const upstream = await doFetch(endpoint, {
1348
+ method: "POST",
1349
+ headers: { "Content-Type": "application/json", "x-api-key": config.apiKey },
1350
+ body: JSON.stringify(body)
1351
+ });
1352
+ const text = await upstream.text();
1353
+ return new Response(text, {
1354
+ status: upstream.status,
1355
+ headers: { "Content-Type": "application/json" }
1356
+ });
1357
+ } catch {
1358
+ return proxyError(-32603, "Backend unreachable", 502);
1450
1359
  }
1451
- return rpcError(-32603, lastError);
1452
1360
  };
1453
1361
  }
1454
1362
 
1363
+ // src/server/rpc-proxy.ts
1364
+ function createRpcProxyHandler(config) {
1365
+ return createBackendProxyHandler({ ...config, path: "/v1/rpc" });
1366
+ }
1367
+
1455
1368
  // src/metadata.ts
1456
1369
  var RESERVED_TRAITS = /* @__PURE__ */ new Set([
1457
1370
  "Creator",
@@ -1536,7 +1449,6 @@ exports.ApiClient = ApiClient;
1536
1449
  exports.CHAINS = CHAINS;
1537
1450
  exports.DEFAULT_CHAIN = DEFAULT_CHAIN;
1538
1451
  exports.DEFAULT_CURRENCY = DEFAULT_CURRENCY;
1539
- exports.DEFAULT_STARKNET_RPC_METHODS = DEFAULT_STARKNET_RPC_METHODS;
1540
1452
  exports.FeeConfigSchema = FeeConfigSchema;
1541
1453
  exports.IPFS_SAFE_CONTENT_TYPE_PREFIXES = IPFS_SAFE_CONTENT_TYPE_PREFIXES;
1542
1454
  exports.MAX_IPFS_GATEWAY_RESPONSE_BYTES = MAX_IPFS_GATEWAY_RESPONSE_BYTES;
@@ -1583,6 +1495,7 @@ exports.chainFromSlug = chainFromSlug;
1583
1495
  exports.chainSlug = chainSlug;
1584
1496
  exports.coinHref = coinHref;
1585
1497
  exports.collectionHref = collectionHref;
1498
+ exports.createBackendProxyHandler = createBackendProxyHandler;
1586
1499
  exports.createFailoverFetch = createFailoverFetch;
1587
1500
  exports.createRateLimiter = createRateLimiter;
1588
1501
  exports.createRpcProxyHandler = createRpcProxyHandler;
@@ -1596,6 +1509,7 @@ exports.getStarknetCoordinates = getStarknetCoordinates;
1596
1509
  exports.getTokenByAddress = getTokenByAddress;
1597
1510
  exports.getTokenBySymbol = getTokenBySymbol;
1598
1511
  exports.hasCapability = hasCapability;
1512
+ exports.isSameOrigin = isSameOrigin;
1599
1513
  exports.isServiceId = isServiceId;
1600
1514
  exports.isTransientRpcError = isTransientRpcError;
1601
1515
  exports.isValidIpfsCidPath = isValidIpfsCidPath;