@medialane/sdk 0.85.13 → 0.86.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,28 +1319,14 @@ function isSameOrigin(req) {
1360
1319
  return false;
1361
1320
  }
1362
1321
  }
1322
+
1323
+ // src/server/rpc-proxy.ts
1363
1324
  function rpcError(code, message, status = 200, id = null) {
1364
1325
  return Response.json({ jsonrpc: "2.0", error: { code, message }, id }, { status });
1365
1326
  }
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
- }
1382
- }
1383
1327
  function createRpcProxyHandler(config) {
1384
- const allowed = new Set(config.allowedMethods ?? DEFAULT_STARKNET_RPC_METHODS);
1328
+ const doFetch = config.fetchImpl ?? fetch;
1329
+ const endpoint = `${config.backendUrl.replace(/\/$/, "")}/v1/rpc`;
1385
1330
  return async function handleRpcProxy(req) {
1386
1331
  if (!isSameOrigin(req)) {
1387
1332
  return rpcError(-32600, "Cross-origin requests are not allowed", 403);
@@ -1389,66 +1334,29 @@ function createRpcProxyHandler(config) {
1389
1334
  if (!config.checkRateLimit(requestIp(req))) {
1390
1335
  return rpcError(-32005, "Too many requests", 429);
1391
1336
  }
1337
+ if (!config.apiKey) {
1338
+ return rpcError(-32003, "No API key configured \u2014 RPC call not forwarded", 402);
1339
+ }
1392
1340
  let body;
1393
1341
  try {
1394
1342
  body = await req.json();
1395
1343
  } catch {
1396
1344
  return rpcError(-32700, "Parse error");
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 rpcError(-32603, "RPC backend unreachable");
1450
1359
  }
1451
- return rpcError(-32603, lastError);
1452
1360
  };
1453
1361
  }
1454
1362
 
@@ -1536,7 +1444,6 @@ exports.ApiClient = ApiClient;
1536
1444
  exports.CHAINS = CHAINS;
1537
1445
  exports.DEFAULT_CHAIN = DEFAULT_CHAIN;
1538
1446
  exports.DEFAULT_CURRENCY = DEFAULT_CURRENCY;
1539
- exports.DEFAULT_STARKNET_RPC_METHODS = DEFAULT_STARKNET_RPC_METHODS;
1540
1447
  exports.FeeConfigSchema = FeeConfigSchema;
1541
1448
  exports.IPFS_SAFE_CONTENT_TYPE_PREFIXES = IPFS_SAFE_CONTENT_TYPE_PREFIXES;
1542
1449
  exports.MAX_IPFS_GATEWAY_RESPONSE_BYTES = MAX_IPFS_GATEWAY_RESPONSE_BYTES;
@@ -1596,6 +1503,7 @@ exports.getStarknetCoordinates = getStarknetCoordinates;
1596
1503
  exports.getTokenByAddress = getTokenByAddress;
1597
1504
  exports.getTokenBySymbol = getTokenBySymbol;
1598
1505
  exports.hasCapability = hasCapability;
1506
+ exports.isSameOrigin = isSameOrigin;
1599
1507
  exports.isServiceId = isServiceId;
1600
1508
  exports.isTransientRpcError = isTransientRpcError;
1601
1509
  exports.isValidIpfsCidPath = isValidIpfsCidPath;