Merge pull request #105 from polkadot-api/vo/rpcs

feat: monaco editor + json schema for rpc methods
This commit is contained in:
Victor Oliva
2025-11-15 10:03:57 -03:00
committed by GitHub
9 changed files with 211 additions and 17 deletions
-2
View File
@@ -1,5 +1,3 @@
import { Buffer } from "buffer"
globalThis.Buffer = Buffer
import { dynamicBuilder$ } from "@/state/chains/chain.state"
import { RemoveSubscribe, Subscribe } from "@react-rxjs/core"
import { PolkaHubProvider } from "polkahub"
+63 -11
View File
@@ -1,14 +1,16 @@
import { ActionButton } from "@/components/ActionButton"
import { LoadingMetadata } from "@/components/Loading"
import { SearchableSelect } from "@/components/Select"
import { Textarea } from "@/components/ui/textarea"
import { withSubscribe } from "@/components/withSuspense"
import { chainClient$ } from "@/state/chains/chain.state"
import { state, useStateObservable } from "@react-rxjs/core"
import { useState } from "react"
import { lazy, Suspense, useRef, useState } from "react"
import { firstValueFrom, map, switchMap } from "rxjs"
import { RpcCallResults } from "./RpcCallResults"
import { addRpcCallQuery } from "./rpcCalls.state"
import { useTheme } from "@/ThemeProvider"
const Editor = lazy(() => import("@monaco-editor/react"))
const chainRpcMethods$ = state(
chainClient$.pipe(
@@ -19,11 +21,19 @@ const chainRpcMethods$ = state(
),
)
const SCHEMA_URL = window.location.origin
export const RpcCalls = withSubscribe(
() => {
const methods = useStateObservable(chainRpcMethods$)
const [method, setMethod] = useState<string | null>(null)
const [params, setParams] = useState<string>("[\n\n]")
const setSchema = useRef<((method: string | null) => void) | null>(null)
const [method, _setMethod] = useState<string | null>(null)
const [params, setParams] = useState<string>("[\n \n]")
const theme = useTheme()
const setMethod = (method: string | null) => {
_setMethod(method)
setSchema.current?.(method)
}
const submit = async () => {
const { client } = await firstValueFrom(chainClient$)
@@ -54,14 +64,56 @@ export const RpcCalls = withSubscribe(
allowCustomValue
/>
</label>
<label className="w-full">
<div className="w-full">
JSON Payload
<Textarea
className="w-full font-mono text-sm"
value={params}
onChange={(e) => setParams(e.target.value)}
/>
</label>
<Suspense
fallback={<div className="border rounded p-1 h-80 w-full" />}
>
<Editor
className="border rounded p-1 h-80"
language="json"
onMount={(editor, monaco) => {
const model = editor.getModel()
if (!model) return
setSchema.current = (method) => {
monaco.languages.json.jsonDefaults.setDiagnosticsOptions({
validate: true,
schemas: method
? [
{
uri: `${SCHEMA_URL}/rpc_schemas/${method}.json`,
fileMatch: [model.uri.toString()],
},
]
: [],
enableSchemaRequest: true,
schemaRequest: "ignore",
})
monaco.languages.json.jsonDefaults.setModeConfiguration(
method
? { completionItems: true, diagnostics: true }
: {
completionItems: false,
diagnostics: true,
},
)
}
setSchema.current(method)
}}
value={params}
loading={<div className="border rounded p-1 h-80 w-full" />}
onChange={(v) => setParams(v ?? "[]")}
options={{
minimap: {
enabled: false,
},
lineNumbers: "off",
}}
theme={theme === "dark" ? "vs-dark" : "light"}
/>
</Suspense>
</div>
<ActionButton disabled={!isReady} onClick={submit}>
Call
</ActionButton>