Merge pull request #105 from polkadot-api/vo/rpcs
feat: monaco editor + json schema for rpc methods
This commit is contained in:
+1
-1
@@ -16,6 +16,7 @@
|
||||
"dependencies": {
|
||||
"@acala-network/chopsticks-core": "^1.2.4",
|
||||
"@ledgerhq/hw-transport-webusb": "^6.29.13",
|
||||
"@monaco-editor/react": "^4.7.0",
|
||||
"@polkadot-api/descriptors": "file:.papi/descriptors",
|
||||
"@polkadot-api/json-rpc-provider-proxy": "^0.2.6",
|
||||
"@polkadot-api/metadata-builders": "^0.13.7",
|
||||
@@ -40,7 +41,6 @@
|
||||
"@radix-ui/react-tooltip": "^1.2.8",
|
||||
"@react-rxjs/core": "^0.10.8",
|
||||
"@react-rxjs/utils": "^0.9.7",
|
||||
"buffer": "^6.0.3",
|
||||
"class-variance-authority": "^0.7.1",
|
||||
"clsx": "^2.1.1",
|
||||
"idb-keyval": "^6.2.2",
|
||||
|
||||
Generated
+49
-3
@@ -19,6 +19,9 @@ importers:
|
||||
'@ledgerhq/hw-transport-webusb':
|
||||
specifier: ^6.29.13
|
||||
version: 6.29.13
|
||||
'@monaco-editor/react':
|
||||
specifier: ^4.7.0
|
||||
version: 4.7.0(monaco-editor@0.54.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)
|
||||
'@polkadot-api/descriptors':
|
||||
specifier: file:.papi/descriptors
|
||||
version: file:.papi/descriptors(polkadot-api@1.20.4(jiti@2.6.1)(postcss@8.5.6)(rxjs@7.8.2)(yaml@2.6.1))
|
||||
@@ -91,9 +94,6 @@ importers:
|
||||
'@react-rxjs/utils':
|
||||
specifier: ^0.9.7
|
||||
version: 0.9.7(@react-rxjs/core@0.10.8(react@19.2.0)(rxjs@7.8.2))(react@19.2.0)(rxjs@7.8.2)
|
||||
buffer:
|
||||
specifier: ^6.0.3
|
||||
version: 6.0.3
|
||||
class-variance-authority:
|
||||
specifier: ^0.7.1
|
||||
version: 0.7.1
|
||||
@@ -589,6 +589,16 @@ packages:
|
||||
'@polkadot-api/substrate-bindings': '*'
|
||||
'@polkadot-api/utils': '*'
|
||||
|
||||
'@monaco-editor/loader@1.6.1':
|
||||
resolution: {integrity: sha512-w3tEnj9HYEC73wtjdpR089AqkUPskFRcdkxsiSFt3SoUc3OHpmu+leP94CXBm4mHfefmhsdfI0ZQu6qJ0wgtPg==}
|
||||
|
||||
'@monaco-editor/react@4.7.0':
|
||||
resolution: {integrity: sha512-cyzXQCtO47ydzxpQtCGSQGOC8Gk3ZUeBXFAxD+CWXYFo5OqZyZUonFl0DwUlTyAfRHntBfw2p3w4s9R6oe1eCA==}
|
||||
peerDependencies:
|
||||
monaco-editor: '>= 0.25.0 < 1'
|
||||
react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
|
||||
react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
|
||||
|
||||
'@msgpack/msgpack@3.1.2':
|
||||
resolution: {integrity: sha512-JEW4DEtBzfe8HvUYecLU9e6+XJnKDlUAIve8FvPzF3Kzs6Xo/KuZkZJsDH0wJXl/qEZbeeE7edxDNY3kMs39hQ==}
|
||||
engines: {node: '>= 18'}
|
||||
@@ -2240,6 +2250,9 @@ packages:
|
||||
dijkstrajs@1.0.3:
|
||||
resolution: {integrity: sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA==}
|
||||
|
||||
dompurify@3.1.7:
|
||||
resolution: {integrity: sha512-VaTstWtsneJY8xzy7DekmYWEOZcmzIe3Qb3zPd4STve1OBTa+e+WmS1ITQec1fZYXI3HCsOZZiSMpG6oxoWMWQ==}
|
||||
|
||||
eastasianwidth@0.2.0:
|
||||
resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
|
||||
|
||||
@@ -2750,6 +2763,11 @@ packages:
|
||||
magic-string@0.30.21:
|
||||
resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==}
|
||||
|
||||
marked@14.0.0:
|
||||
resolution: {integrity: sha512-uIj4+faQ+MgHgwUW1l2PsPglZLOLOT1uErt06dAPtx2kjteLAkbsd/0FiYg/MGS+i7ZKLb7w2WClxHkzOOuryQ==}
|
||||
engines: {node: '>= 18'}
|
||||
hasBin: true
|
||||
|
||||
merge2@1.4.1:
|
||||
resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
|
||||
engines: {node: '>= 8'}
|
||||
@@ -2783,6 +2801,9 @@ packages:
|
||||
resolution: {integrity: sha512-qxBgB7Qa2sEQgHFjj0dSigq7fX4k6Saisd5Nelwp2q8mlbAFh5dHV9JTTlF8viYJLSSWgMCZFUom8PJcMNBoJw==}
|
||||
engines: {node: '>= 8'}
|
||||
|
||||
monaco-editor@0.54.0:
|
||||
resolution: {integrity: sha512-hx45SEUoLatgWxHKCmlLJH81xBo0uXP4sRkESUpmDQevfi+e7K1VuiSprK6UpQ8u4zOcKNiH0pMvHvlMWA/4cw==}
|
||||
|
||||
ms@2.1.3:
|
||||
resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
|
||||
|
||||
@@ -3281,6 +3302,9 @@ packages:
|
||||
resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==}
|
||||
engines: {node: '>= 10.x'}
|
||||
|
||||
state-local@1.0.7:
|
||||
resolution: {integrity: sha512-HTEHMNieakEnoe33shBYcZ7NX83ACUjCu8c40iOGEZsngj9zRnkqS9j1pqQPXwobB0ZcVTk27REb7COQ0UR59w==}
|
||||
|
||||
stdin-discarder@0.2.2:
|
||||
resolution: {integrity: sha512-UhDfHmA92YAlNnCfhmq0VeNL5bDbiZGg7sZ2IvPsXubGkiNa9EC+tUTsjBRsYUAz87btI6/1wf4XoVvQ3uRnmQ==}
|
||||
engines: {node: '>=18'}
|
||||
@@ -4122,6 +4146,17 @@ snapshots:
|
||||
'@polkadot-api/substrate-bindings': 0.16.5
|
||||
'@polkadot-api/utils': 0.2.0
|
||||
|
||||
'@monaco-editor/loader@1.6.1':
|
||||
dependencies:
|
||||
state-local: 1.0.7
|
||||
|
||||
'@monaco-editor/react@4.7.0(monaco-editor@0.54.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)':
|
||||
dependencies:
|
||||
'@monaco-editor/loader': 1.6.1
|
||||
monaco-editor: 0.54.0
|
||||
react: 19.2.0
|
||||
react-dom: 19.2.0(react@19.2.0)
|
||||
|
||||
'@msgpack/msgpack@3.1.2': {}
|
||||
|
||||
'@noble/ciphers@1.3.0': {}
|
||||
@@ -6656,6 +6691,8 @@ snapshots:
|
||||
|
||||
dijkstrajs@1.0.3: {}
|
||||
|
||||
dompurify@3.1.7: {}
|
||||
|
||||
eastasianwidth@0.2.0: {}
|
||||
|
||||
electron-to-chromium@1.5.250: {}
|
||||
@@ -7154,6 +7191,8 @@ snapshots:
|
||||
dependencies:
|
||||
'@jridgewell/sourcemap-codec': 1.5.5
|
||||
|
||||
marked@14.0.0: {}
|
||||
|
||||
merge2@1.4.1: {}
|
||||
|
||||
micromatch@4.0.8:
|
||||
@@ -7184,6 +7223,11 @@ snapshots:
|
||||
|
||||
mock-socket@9.3.1: {}
|
||||
|
||||
monaco-editor@0.54.0:
|
||||
dependencies:
|
||||
dompurify: 3.1.7
|
||||
marked: 14.0.0
|
||||
|
||||
ms@2.1.3: {}
|
||||
|
||||
multiformats@9.9.0: {}
|
||||
@@ -7792,6 +7836,8 @@ snapshots:
|
||||
|
||||
split2@4.2.0: {}
|
||||
|
||||
state-local@1.0.7: {}
|
||||
|
||||
stdin-discarder@0.2.2: {}
|
||||
|
||||
string-width@4.2.3:
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"title": "chain_getBlock params",
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "object",
|
||||
"description": "{} or { hash }.",
|
||||
"maxProperties": 1,
|
||||
"additionalProperties": false,
|
||||
"properties": { "hash": { "$ref": "./common.json#/$defs/hex" } }
|
||||
},
|
||||
{
|
||||
"type": "array",
|
||||
"description": "[] or [hash].",
|
||||
"maxItems": 1,
|
||||
"items": { "$ref": "./common.json#/$defs/hex" }
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"title": "chain_getBlockHash params",
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "array",
|
||||
"description": "[] or [blockNumber].",
|
||||
"maxItems": 1,
|
||||
"items": {
|
||||
"type": "number"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"title": "chain_getHeader params",
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "object",
|
||||
"description": "{} or { hash }.",
|
||||
"maxProperties": 1,
|
||||
"additionalProperties": false,
|
||||
"properties": { "hash": { "$ref": "./common.json#/$defs/hex" } }
|
||||
},
|
||||
{
|
||||
"type": "array",
|
||||
"description": "[] or [hash].",
|
||||
"maxItems": 1,
|
||||
"items": { "$ref": "./common.json#/$defs/hex" }
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "common.json",
|
||||
"$defs": {
|
||||
"hex": {
|
||||
"type": "string",
|
||||
"pattern": "^0x[0-9a-fA-F]*$",
|
||||
"description": "0x-prefixed hex."
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"title": "state_getReadProof params",
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "array",
|
||||
"description": "[keys] or [keys, at].",
|
||||
"minItems": 1,
|
||||
"maxItems": 2,
|
||||
"prefixItems": [
|
||||
{
|
||||
"type": "array",
|
||||
"description": "Storage keys to prove.",
|
||||
"items": { "$ref": "./common.json#/$defs/hex" }
|
||||
},
|
||||
{ "$ref": "./common.json#/$defs/hex" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"description": "{ keys } or { keys, at } or { keys, hash }.",
|
||||
"required": ["keys"],
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"keys": {
|
||||
"type": "array",
|
||||
"description": "Storage keys to prove.",
|
||||
"items": { "$ref": "./common.json#/$defs/hex" }
|
||||
},
|
||||
"at": { "$ref": "./common.json#/$defs/hex" },
|
||||
"hash": { "$ref": "./common.json#/$defs/hex" }
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -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"
|
||||
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user