setCollapsed((expanded) => !expanded)}
>
{collapsed ? "Show child attributes" : "Hide child attributes"}
{
- const lines = content.split('\n');
+const parseLists = (text: string) => {
+ const lines = text.split('\n');
let result = '';
- let isFirstLevelOpen = false;
- let isSecondLevelOpen = false;
+ let inList = false;
+ let inSubList = false;
+
lines.forEach((line) => {
- if (line.match(/^ {2}-\s+/)) {
- if (!isSecondLevelOpen) {
- result += '
';
- isSecondLevelOpen = true;
- }
- result += `- ${line.trim().substring(4)}
`;
- } else if (line.match(/^ -\s+/)) {
- if (isSecondLevelOpen) {
- result += '
';
- isSecondLevelOpen = false;
+ const trimmed = line.trim();
+ const isListItem = trimmed.startsWith('- ');
+ const isSubListItem = line.startsWith(' - ');
+
+ if (isListItem && !isSubListItem) {
+ if (!inList) {
+ result += '
\n';
+ inList = true;
+ } else if (inSubList) {
+ result += '
\n';
+ inSubList = false;
}
- if (!isFirstLevelOpen) {
- result += '
';
- isFirstLevelOpen = true;
+ result += `- ${trimmed.slice(2).trim()}
\n`;
+ } else if (isSubListItem) {
+ if (!inSubList) {
+ result = result.replace(/<\/li>\n$/, '');
+ result += '\n';
+ inSubList = true;
}
- result += `- ${line.trim().substring(2)}
`;
+ result += `- ${trimmed.slice(4).trim()}
\n`;
} else {
- if (isSecondLevelOpen) {
- result += '
';
- isSecondLevelOpen = false;
+ if (inSubList) {
+ result += '
\n';
+ inSubList = false;
}
- if (isFirstLevelOpen) {
- result += '';
- isFirstLevelOpen = false;
+ if (inList) {
+ result += '\n';
+ inList = false;
}
- result += line;
+ result += `${line}\n`;
}
});
- if (isSecondLevelOpen) result += '';
- if (isFirstLevelOpen) result += '';
+ if (inSubList) result += '\n';
+ if (inList) result += '\n';
return result;
-};
+}
const parseMarkdown = (content: string) => {
return parseLists(
@@ -45,6 +50,7 @@ const parseMarkdown = (content: string) => {
.replace(/\[(.*?)\]\((.*?)\)/g, '
$1')
.replace(/`(.*?)`/g, '
$1
')
.replace(/\*\*(.*?)\*\*/g, '
$1')
+ .replace(/\*(.*?)\*/g, '
$1')
);
};
diff --git a/src/components/ParserOpenRPC/DetailsBox/RenderParams.tsx b/src/components/ParserOpenRPC/DetailsBox/RenderParams.tsx
index 887b977a4f..8272b60c76 100644
--- a/src/components/ParserOpenRPC/DetailsBox/RenderParams.tsx
+++ b/src/components/ParserOpenRPC/DetailsBox/RenderParams.tsx
@@ -29,7 +29,7 @@ const renderSchema = (schemaItem, schemas, name) => {
description={item.description || item.title || ""}
/>
-
+
<>
{Object.entries(item.properties).map(([key, value]) => (
@@ -96,6 +96,10 @@ const renderSchema = (schemaItem, schemas, name) => {
);
+ if (schemaItem?.schema?.oneOf) return renderCombinations(schemaItem.schema, name, "oneOf");
+ if (schemaItem?.schema?.allOf) return renderCombinations(schemaItem.schema, name, "allOf");
+ if (schemaItem?.schema?.anyOf) return renderCombinations(schemaItem.schema, name, "anyOf");
+
if (schemaItem.oneOf) return renderCombinations(schemaItem, name, "oneOf");
if (schemaItem.allOf) return renderCombinations(schemaItem, name, "allOf");
if (schemaItem.anyOf) return renderCombinations(schemaItem, name, "anyOf");
@@ -184,5 +188,9 @@ export const renderParamSchemas = (inputSchema, schemas) => {
};
export const renderResultSchemas = (inputSchema, schemas) => {
+ const customResult = inputSchema?.schema?.maxPriorityFeePerGas;
+ if (customResult) {
+ return <>{renderSchema(customResult, schemas, inputSchema.name)}>
+ }
return <>{renderSchema(inputSchema, schemas, inputSchema.name)}>;
};
diff --git a/src/components/ParserOpenRPC/DetailsBox/index.tsx b/src/components/ParserOpenRPC/DetailsBox/index.tsx
index 912b1640e9..e72022c881 100644
--- a/src/components/ParserOpenRPC/DetailsBox/index.tsx
+++ b/src/components/ParserOpenRPC/DetailsBox/index.tsx
@@ -18,6 +18,7 @@ interface TagItem {
interface DetailsBoxProps {
method: string;
description: string | null;
+ summary: string | null;
params: MethodParam[];
components: SchemaComponents;
result: any;
@@ -28,6 +29,7 @@ interface DetailsBoxProps {
export default function DetailsBox({
method,
description,
+ summary,
params,
components,
result,
@@ -46,7 +48,14 @@ export default function DetailsBox({
)}
{method}
-
+ {summary !== null && (
+
+
+
+ )}
+ {description !== null && (
+
+ )}
{extraContent &&
{extraContent}
}
void;
+ requestURL: string;
+ isLoading: boolean;
}
export default function RequestBox({
@@ -32,6 +33,8 @@ export default function RequestBox({
isMetamaskNetwork = false,
defExampleResponse,
resetResponseHandle,
+ requestURL = "",
+ isLoading,
}: RequestBoxProps) {
const { userAPIKey } = useContext(MetamaskProviderContext);
const exampleRequest = useMemo(() => {
@@ -41,7 +44,7 @@ export default function RequestBox({
if (isMetamaskNetwork) {
return `await window.ethereum.request({\n "method": "${method}",\n "params": ${preparedParams.replace(/"([^"]+)":/g, '$1:')},\n});`;
}
- return `curl ${LINEA_REQUEST_URL}/v3/${API_KEY} \\\n -X POST \\\n -H "Content-Type: application/json" \\\n -d '{\n "jsonrpc": "2.0",\n "method": "${method}",\n "params": ${preparedShellParams},\n "id": 1\n }'`;
+ return `curl ${requestURL}${API_KEY} \\\n -X POST \\\n -H "Content-Type: application/json" \\\n -d '{\n "jsonrpc": "2.0",\n "method": "${method}",\n "params": ${preparedShellParams},\n "id": 1\n }'`;
}, [userAPIKey, method, paramsData]);
const exampleResponse = useMemo(() => {
@@ -59,18 +62,18 @@ export default function RequestBox({
}, [response, defExampleResponse]);
const methodsWithRequiredWalletConnection = ["eth_accounts", "eth_sendTransaction", "personal_sign", "eth_signTypedData_v4"];
- const isRunAndCustomizeRequestDisabled = methodsWithRequiredWalletConnection.includes(method) ?
+ const isRunAndCustomizeRequestDisabled = isMetamaskNetwork && methodsWithRequiredWalletConnection.includes(method) ?
!isMetamaskInstalled :
false;
const runRequestButton = (
);
diff --git a/src/components/ParserOpenRPC/RequestBox/styles.module.css b/src/components/ParserOpenRPC/RequestBox/styles.module.css
index 78f14a484a..0ded51e680 100644
--- a/src/components/ParserOpenRPC/RequestBox/styles.module.css
+++ b/src/components/ParserOpenRPC/RequestBox/styles.module.css
@@ -40,3 +40,28 @@
background: none;
border: 0;
}
+
+.runBtnWrap {
+ display: flex;
+ justify-content: center;
+ min-width: 109px;
+}
+
+.loader {
+ width: 16px;
+ height: 16px;
+ border: 2px solid #FFF;
+ border-bottom-color: transparent;
+ border-radius: 50%;
+ display: inline-block;
+ animation: rotation 1s linear infinite;
+}
+
+@keyframes rotation {
+ 0% {
+ transform: rotate(0deg);
+ }
+ 100% {
+ transform: rotate(360deg);
+ }
+}
diff --git a/src/components/ParserOpenRPC/index.tsx b/src/components/ParserOpenRPC/index.tsx
index 9f39881622..935e66ab95 100644
--- a/src/components/ParserOpenRPC/index.tsx
+++ b/src/components/ParserOpenRPC/index.tsx
@@ -6,7 +6,6 @@ import React, {
useEffect,
} from "react";
import { usePluginData } from "@docusaurus/useGlobalData";
-import { useLocation } from "@docusaurus/router";
import { ResponseItem, NETWORK_NAMES } from "@site/src/plugins/plugin-json-rpc";
import DetailsBox from "@site/src/components/ParserOpenRPC/DetailsBox";
import InteractiveBox from "@site/src/components/ParserOpenRPC/InteractiveBox";
@@ -24,7 +23,7 @@ import {
import { AuthBox } from "@site/src/components/ParserOpenRPC/AuthBox";
import { MetamaskProviderContext } from "@site/src/theme/Root";
import ProjectsBox from "@site/src/components/ParserOpenRPC/ProjectsBox";
-import { LINEA_REQUEST_URL, REF_PATH } from "@site/src/lib/constants";
+import { LINEA_REQUEST_URL } from "@site/src/lib/constants";
interface ParserProps {
network: NETWORK_NAMES;
@@ -49,8 +48,6 @@ export default function ParserOpenRPC({
extraContent,
}: ParserProps) {
if (!method || !network) return null;
- const location = useLocation();
- const { pathname } = location;
const [isModalOpen, setModalOpen] = useState(false);
const [reqResult, setReqResult] = useState(undefined);
const [paramsData, setParamsData] = useState([]);
@@ -59,6 +56,7 @@ export default function ParserOpenRPC({
const [isComplexTypeView, setIsComplexTypeView] = useState(false);
const { metaMaskAccount, metaMaskProvider, userAPIKey } = useContext(MetamaskProviderContext);
const [defExampleResponse, setDefExampleResponse] = useState(undefined);
+ const [isLoading, setIsLoading] = useState(false);
const { colorMode } = useColorMode();
const trackAnalyticsForRequest = (response) => {
trackClickForSegment({
@@ -124,7 +122,8 @@ export default function ParserOpenRPC({
);
return {
- description: currentMethod.description || currentMethod.summary || null,
+ description: currentMethod.description || null,
+ summary: currentMethod.summary || null,
params: currentMethod.params || [],
result: currentMethod.result || null,
components: currentNetwork.data.components || null,
@@ -132,6 +131,7 @@ export default function ParserOpenRPC({
paramStructure: currentMethod?.paramStructure || null,
errors,
tags,
+ servers: currentNetwork.data?.servers?.[0]?.url || null
};
}, [currentNetwork, method]);
@@ -187,39 +187,71 @@ export default function ParserOpenRPC({
setParamsData(Object.values(data));
};
- const onSubmitRequestHandle = async () => {
- if (isMetamaskNetwork) {
- if (!metaMaskProvider) return
- try {
- const response = await metaMaskProvider?.request({
- method: method,
- params: paramsData
- })
- setReqResult(response);
- trackAnalyticsForRequest(response);
- } catch (e) {
- setReqResult(e);
- }
+ const handleMetaMaskRequest = async () => {
+ if (!metaMaskProvider) return;
+ setIsLoading(true);
+ try {
+ const response = await metaMaskProvider.request({
+ method,
+ params: paramsData,
+ });
+ setReqResult(response);
+ trackAnalyticsForRequest(response);
+ } catch (e) {
+ setReqResult(e);
+ } finally {
+ setIsLoading(false);
+ }
+ };
+
+ const getInfuraUrl = (url: string) => {
+ if (process.env.VERCEL_ENV === "production") {
+ return url;
} else {
- const URL = `${LINEA_REQUEST_URL}/v3/${userAPIKey}`;
- let params = {
- method: "POST",
+ return url.replace("infura.io", "dev.infura.org");
+ }
+ }
+
+ const INIT_URL = currentMethodData.servers !== null ? getInfuraUrl(currentMethodData.servers) : `${LINEA_REQUEST_URL}/v3/`;
+
+ const handleServiceRequest = async () => {
+ const URL = `${INIT_URL}${userAPIKey}`;
+ const params = {
+ method: "POST",
+ headers: {
"Content-Type": "application/json",
- body: JSON.stringify({
- jsonrpc: "2.0",
- method,
- params: paramsData,
- id: 1,
- }),
- };
+ },
+ body: JSON.stringify({
+ jsonrpc: "2.0",
+ method,
+ params: paramsData,
+ id: 1,
+ }),
+ };
+ setIsLoading(true);
+ try {
const res = await fetch(URL, params);
if (res.ok) {
const response = await res.json();
- setReqResult(response.result);
- trackAnalyticsForRequest(response.result);
+ setReqResult(response);
+ trackAnalyticsForRequest(response);
} else {
- console.error("error");
+ const errorText = await res.text();
+ const errorState = JSON.parse(errorText);
+ setReqResult(`Request failed. Status: ${res.status}. ${errorState}`);
}
+ } catch (e) {
+ setReqResult(`${e}`);
+ } finally {
+ setIsLoading(false);
+ }
+ };
+
+ const onSubmitRequestHandle = async () => {
+ if (isMetamaskNetwork) {
+ await handleMetaMaskRequest();
+ } else {
+ await handleServiceRequest();
}
};
@@ -250,6 +282,7 @@ export default function ParserOpenRPC({
- {pathname.startsWith(REF_PATH) &&
}
- {!pathname.startsWith(REF_PATH) && !metaMaskAccount && (
+ {!isMetamaskNetwork &&
}
+ {isMetamaskNetwork && !metaMaskAccount && (
)}
diff --git a/src/css/custom.css b/src/css/custom.css
index 637fe43655..20d51c594d 100644
--- a/src/css/custom.css
+++ b/src/css/custom.css
@@ -359,6 +359,10 @@ button:hover {
color: #ffffff;
}
+[data-theme="light"] .react-dropdown-select-dropdown-handle {
+ color: #24272A;
+}
+
@media (width <= 1200px) {
.navbar__item,
.navbar__link {