diff --git a/docusaurus.config.js b/docusaurus.config.js
index 1d8fe01a04..6ce07aa717 100644
--- a/docusaurus.config.js
+++ b/docusaurus.config.js
@@ -2,6 +2,8 @@
// Note: type annotations allow type checking and IDEs autocompletion
require("dotenv").config();
+const { fetchAndGenerateSidebarItems } = require("./src/helpers/index.ts");
+const capitalize = require("lodash.capitalize");
const { themes } = require("prism-react-renderer");
const codeTheme = themes.dracula;
const remarkCodesandbox = require("remark-codesandbox");
@@ -32,6 +34,7 @@ const config = {
customFields: {
LD_CLIENT_ID: process.env.LD_CLIENT_ID,
+ sidebarData: {},
},
trailingSlash: true,
@@ -122,6 +125,19 @@ const config = {
editUrl: "https://github.com/MetaMask/metamask-docs/edit/main/",
sidebarPath: require.resolve("./services-sidebar.js"),
breadcrumbs: false,
+ sidebarItemsGenerator: async function ({ defaultSidebarItemsGenerator, ...args }) {
+ config.customFields.sidebarData = args;
+ let sidebarItems = await defaultSidebarItemsGenerator(args);
+ const networkName = "linea";
+ const dynamicSidebarItems = await fetchAndGenerateSidebarItems(networkName);
+ const updatedItems = sidebarItems.map(item => {
+ if (item?.label === capitalize(networkName) && item?.items) {
+ item.items = [...item.items, ...dynamicSidebarItems]
+ }
+ return item;
+ })
+ return [...updatedItems];
+ },
},
],
[
diff --git a/package.json b/package.json
index 20e3e53e62..22e2c8c15d 100644
--- a/package.json
+++ b/package.json
@@ -48,6 +48,7 @@
"dotenv": "^16.4.5",
"js-cookie": "^3.0.5",
"launchdarkly-js-client-sdk": "^3.3.0",
+ "lodash.capitalize": "^4.2.1",
"lodash.debounce": "^4.0.8",
"lodash.isobject": "^3.0.2",
"node-polyfill-webpack-plugin": "^2.0.1",
diff --git a/src/components/ParserOpenRPC/index.tsx b/src/components/ParserOpenRPC/index.tsx
index 63b1192426..874263fea5 100644
--- a/src/components/ParserOpenRPC/index.tsx
+++ b/src/components/ParserOpenRPC/index.tsx
@@ -13,6 +13,7 @@ import clsx from "clsx";
import { useColorMode } from "@docusaurus/theme-common";
import { trackClickForSegment, trackInputChangeForSegment } from "@site/src/lib/segmentAnalytics";
import { MetamaskProviderContext } from "@site/src/theme/Root";
+import { useLocation } from "@docusaurus/router";
interface ParserProps {
network: NETWORK_NAMES;
@@ -40,6 +41,16 @@ export default function ParserOpenRPC({ network, method, extraContent }: ParserP
const [drawerLabel, setDrawerLabel] = useState(null);
const [isComplexTypeView, setIsComplexTypeView] = useState(false);
const { colorMode } = useColorMode();
+ const location = useLocation();
+ const isWalletReferencePage = location.pathname.includes("/wallet/reference");
+ const trackAnalyticsForRequest = (response) => {
+ trackClickForSegment({
+ eventName: "Request Sent",
+ clickType: "Request Sent",
+ userExperience: "B",
+ ...(response?.code && { responseStatus: response.code }),
+ });
+ }
const openModal = () => {
setModalOpen(true);
trackClickForSegment({
@@ -132,21 +143,40 @@ export default function ParserOpenRPC({ network, method, extraContent }: ParserP
};
const onSubmitRequestHandle = async () => {
- if (!metaMaskProvider) return
- try {
- const response = await metaMaskProvider?.request({
- method: method,
- params: paramsData
- })
- setReqResult(response);
- trackClickForSegment({
- eventName: "Request Sent",
- clickType: "Request Sent",
- userExperience: "B",
- ...(response?.code && { responseStatus: response.code }),
- });
- } catch (e) {
- setReqResult(e);
+ if (isMetamaskNetwork) {
+ if (!metaMaskProvider) return
+ try {
+ const response = await metaMaskProvider?.request({
+ method: method,
+ params: paramsData
+ })
+ setReqResult(response);
+ trackAnalyticsForRequest(response);
+ } catch (e) {
+ setReqResult(e);
+ }
+ } else {
+ const NETWORK_URL = "https://linea-mainnet.infura.io";
+ const API_KEY = "366ba274ec6f4cf1810de6003cbb9a5e";
+ const URL = `${NETWORK_URL}/v3/${API_KEY}`;
+ let params = {
+ method: "POST",
+ "Content-Type": "application/json",
+ body: JSON.stringify({
+ jsonrpc: "2.0",
+ method,
+ params: paramsData,
+ id: 1,
+ }),
+ };
+ const res = await fetch(URL, params);
+ if (res.ok) {
+ const response = await res.json();
+ setReqResult(response.result);
+ trackAnalyticsForRequest(response.result);
+ } else {
+ console.error("error");
+ }
}
};
@@ -228,7 +258,7 @@ export default function ParserOpenRPC({ network, method, extraContent }: ParserP
- {!metaMaskAccount &&
}
+ {isWalletReferencePage && !metaMaskAccount &&
}
{
+ try {
+ const response = await fetch(`https://sot-network-methods.vercel.app/specs/${networkName}`);
+ const data = await response.json();
+ const dynamicItems = data.methods.map((method) => ({
+ type: "link",
+ label: method.name,
+ href: `/services/reference/linea/json-rpc-methods-new/${method.name}`,
+ })).sort((a, b) => a.label.localeCompare(b.label));
+ return [
+ {
+ type: "category",
+ label: "JSON-RPC Methods NEW",
+ collapsed: true,
+ collapsible: true,
+ items: dynamicItems,
+ },
+ ];
+ } catch (error) {
+ console.error("Error fetching methods:", error);
+ return [];
+ }
+}
diff --git a/src/pages/CustomPage/index.tsx b/src/pages/CustomPage/index.tsx
new file mode 100644
index 0000000000..d2413a9e86
--- /dev/null
+++ b/src/pages/CustomPage/index.tsx
@@ -0,0 +1,125 @@
+import Layout from "@theme/Layout";
+import { NETWORK_NAMES } from "@site/src/plugins/plugin-json-rpc";
+import ParserOpenRPC from "@site/src/components/ParserOpenRPC";
+import React, { useEffect, useState } from "react";
+import DocSidebar from '@theme/DocSidebar';
+import styles from "@site/src/theme/Layout/styles.module.css"
+import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
+import { fetchAndGenerateSidebarItems } from "@site/src/helpers";
+import * as capitalize from "lodash.capitalize"
+
+function generateSidebarItems(docs) {
+ const categories = {};
+
+ docs.forEach((doc) => {
+ if (doc.id === 'index') {
+ categories['Introduction'] = {
+ type: 'link',
+ href: '/services',
+ label: capitalize(doc.frontMatter?.sidebar_label || doc.title),
+ };
+ return;
+ }
+
+ const pathParts = doc.sourceDirName.split('/');
+ let currentCategory = categories;
+ let isIndexPage = doc.id.endsWith('/index');
+
+ pathParts.forEach((part, index) => {
+ if (!currentCategory[part]) {
+ if (isIndexPage && index === pathParts.length - 2) {
+ currentCategory[part] = {
+ type: 'category',
+ label: capitalize(doc.frontMatter?.sidebar_label || doc.frontMatter?.title || part),
+ collapsed: true,
+ collapsible: true,
+ link: {
+ type: 'generated-index',
+ slug: pathParts.slice(0, index + 1).join('/')
+ },
+ items: []
+ };
+ } else {
+ currentCategory[part] = {
+ type: 'category',
+ label: capitalize(part),
+ collapsed: true,
+ collapsible: true,
+ items: []
+ };
+ }
+ }
+
+ if (index === pathParts.length - 1 && !isIndexPage) {
+ currentCategory[part].items.push({
+ type: 'link',
+ label: capitalize(doc.frontMatter?.title || doc.title),
+ href: `/services/${doc.id.replace(/\/index$/, '')}`,
+ sidebar_position: doc.frontMatter?.sidebar_position || Number.MAX_SAFE_INTEGER
+ });
+ }
+ currentCategory = currentCategory[part].items;
+ });
+ });
+
+ const convertToArray = (categoryObj) => {
+ return Object.values(categoryObj).map((category) => {
+ if (category.items && typeof category.items === 'object') {
+ category.items = convertToArray(category.items);
+ if (category.items.every(item => item.sidebar_position !== undefined)) {
+ category.items.sort((a, b) => (a.sidebar_position || Number.MAX_SAFE_INTEGER) - (b.sidebar_position || Number.MAX_SAFE_INTEGER));
+ }
+ }
+ return category;
+ });
+ };
+ return convertToArray(categories);
+}
+
+const sidebar_wrapper_classes = "theme-doc-sidebar-container docSidebarContainer_node_modules-@docusaurus-theme-classic-lib-theme-DocRoot-Layout-Sidebar-styles-module"
+
+const CustomPage = (props) => {
+ const customData = props.route.customData;
+ const { siteConfig } = useDocusaurusContext();
+ const [formattedData, setFormattedData] = useState([]);
+ const networkName = "linea";
+
+ useEffect(() => {
+ fetchAndGenerateSidebarItems(networkName).then(generatedItems => {
+ setFormattedData(generateSidebarItems(siteConfig.customFields.sidebarData.docs).map(item => {
+ if (item?.label === "Reference" && item?.items) {
+ return {
+ ...item,
+ items: item.items.map(referenceItem => {
+ if (referenceItem?.label === capitalize(networkName) && referenceItem?.items) {
+ return { ...referenceItem, items: [...referenceItem.items, ...generatedItems] };
+ }
+ return referenceItem;
+ })
+ }
+ }
+ return item;
+ }));
+ });
+ }, []);
+
+ return formattedData ? (
+
+
+
+
+
+
+ ) : null;
+};
+
+export default CustomPage;
diff --git a/src/plugins/plugin-json-rpc.ts b/src/plugins/plugin-json-rpc.ts
index 505d3c23d0..78ccb5f18c 100644
--- a/src/plugins/plugin-json-rpc.ts
+++ b/src/plugins/plugin-json-rpc.ts
@@ -40,14 +40,42 @@ const requests = [
},
];
+function generateMethodMDX(page) {
+ return `---
+title: '${page.name}'
+---
+# ${page.name}
+ `;
+}
+
export default function useNetworksMethodPlugin() {
return {
name: "plugin-json-rpc",
async contentLoaded({ actions }) {
- const { setGlobalData } = actions;
+ const { setGlobalData, createData, addRoute } = actions;
await fetchMultipleData(requests)
.then((responseArray) => {
+ const networkName = "linea";
setGlobalData({ netData: responseArray });
+ return Promise.all(responseArray[responseArray.findIndex(item => item.name === networkName) || 0].data.methods.map(async (page) => {
+
+ const methodMDXContent = generateMethodMDX(page);
+
+ const filePath = await createData(
+ `services/reference/linea/json-rpc-methods-new/${page.name}.mdx`,
+ methodMDXContent
+ );
+
+ return addRoute({
+ path: `/services/reference/linea/json-rpc-methods-new/${page.name}`,
+ component: require.resolve("../pages/CustomPage/index.tsx"),
+ exact: true,
+ modules: {
+ methodFile: filePath,
+ },
+ customData: { ...page }
+ });
+ }));
})
.catch(() => {
setGlobalData({ netData: [] });
diff --git a/yarn.lock b/yarn.lock
index a42fab8b4e..cdd67c8e90 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -12493,6 +12493,13 @@ __metadata:
languageName: node
linkType: hard
+"lodash.capitalize@npm:^4.2.1":
+ version: 4.2.1
+ resolution: "lodash.capitalize@npm:4.2.1"
+ checksum: d9195f31d48c105206f1099946d8bbc8ab71435bc1c8708296992a31a992bb901baf120fdcadd773098ac96e62a79e6b023ee7d26a2deb0d6c6aada930e6ad0a
+ languageName: node
+ linkType: hard
+
"lodash.debounce@npm:^4.0.8":
version: 4.0.8
resolution: "lodash.debounce@npm:4.0.8"
@@ -13380,6 +13387,7 @@ __metadata:
eslint-plugin-react: ^7.34.2
js-cookie: ^3.0.5
launchdarkly-js-client-sdk: ^3.3.0
+ lodash.capitalize: ^4.2.1
lodash.debounce: ^4.0.8
lodash.isobject: ^3.0.2
node-polyfill-webpack-plugin: ^2.0.1