fix: remove the fork-with options, and name the workflow step for what it does
**Fork with Chopsticks / Forklift is gone.** Neither can fork a chain in this list. Chopsticks is built on `@polkadot/types`, which cannot decode a Quantus block at all — it caps fixed arrays at 2048 bytes where ML-DSA signatures are 5261 and 7219, reads the extrinsic preamble byte as a version, and knows nothing of this chain's header layout. Forklift resolves its own unpatched copy of `@polkadot-api/substrate-bindings`, so it hits the very header bug this console patches around. So the two buttons offered things that could only fail, and fail without saying why. Removed rather than disabled: a greyed-out control still asks the reader to work out why. `forkMethod` stays in SelectedChain because the hash params and chain.state still read it; nothing in the UI can now set it to anything but "none", so the two light-client guards that reset it go with it. **The workflow step called "the patch is applied"** — an assertion sitting in a list of imperatives (install, build, ship the bundle), reading like a claim CI was making rather than a thing it was doing. Now "verify the signers-common patch". Verified in a browser: the switcher shows Quantus, Heisenberg, Planck and Localhost with both endpoints per chain and no FORK WITH row, and the explorer still runs — Finalized 54,153, Best 54,253. Refs #3 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012uDUodEcRbBwNRi3UCmw8f
This commit is contained in:
@@ -58,7 +58,7 @@ jobs:
|
||||
# shipping a console that rejects every Quantus signature at run time.
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
- name: the patch is applied
|
||||
- name: verify the signers-common patch
|
||||
# Cheap, and it is the one thing about this fork that a normal build
|
||||
# would not notice going missing. Without it every signing attempt dies
|
||||
# with `Unkown signer` — in the browser, after deploy, to a user.
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
import { CopyText } from "@/components/Copy"
|
||||
import {
|
||||
Chopsticks,
|
||||
Forklift,
|
||||
ForkMethodIcon,
|
||||
Spinner,
|
||||
} from "@/components/Icons"
|
||||
@@ -28,7 +26,6 @@ import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group"
|
||||
import {
|
||||
AUTO_RPC_ENDPOINT,
|
||||
currentWsStatus$,
|
||||
ForkMethod,
|
||||
LIGHT_CLIENT_ENDPOINT,
|
||||
Network,
|
||||
networkCategories,
|
||||
@@ -85,10 +82,21 @@ const NetworkSwitchDialogContent: FC<{
|
||||
const [query, setQuery] = useState("")
|
||||
const [network, setNetwork] = useState(selectedChain.network)
|
||||
const [endpoint, setEndpoint] = useState(selectedChain.endpoint)
|
||||
const [forkMethod, setForkMethod] = useState(selectedChain.forkMethod)
|
||||
const customUrl = normalizeWsUrl(query)
|
||||
const canFork = endpoint !== LIGHT_CLIENT_ENDPOINT
|
||||
const selectedForkMethod = canFork ? forkMethod : "none"
|
||||
// Forking is not offered.
|
||||
//
|
||||
// Chopsticks is built on `@polkadot/types`, which cannot decode a Quantus
|
||||
// block at all: it caps fixed arrays at 2048 bytes where ML-DSA signatures are
|
||||
// 5261 and 7219, reads the extrinsic preamble byte as a version, and knows
|
||||
// nothing of this chain's header layout. Forklift resolves its own unpatched
|
||||
// copy of `@polkadot-api/substrate-bindings`, so it hits the very header bug
|
||||
// this console patches around.
|
||||
//
|
||||
// Neither can fork a chain in this list, so the two buttons offered things
|
||||
// that could only fail, and fail without saying why. `forkMethod` stays in
|
||||
// SelectedChain — the hash params and chain.state still read it — but nothing
|
||||
// in the UI can now set it to anything other than "none".
|
||||
const selectedForkMethod = "none" as const
|
||||
const hasChanged =
|
||||
network.id !== selectedChain.network.id ||
|
||||
endpoint !== selectedChain.endpoint ||
|
||||
@@ -100,9 +108,6 @@ const NetworkSwitchDialogContent: FC<{
|
||||
) => {
|
||||
setNetwork(next)
|
||||
setEndpoint(nextEndpoint)
|
||||
if (nextEndpoint === LIGHT_CLIENT_ENDPOINT) {
|
||||
setForkMethod("none")
|
||||
}
|
||||
}
|
||||
|
||||
const selectCustomUrl = (url: string) => {
|
||||
@@ -112,14 +117,8 @@ const NetworkSwitchDialogContent: FC<{
|
||||
|
||||
const setConnection = (nextEndpoint: string) => {
|
||||
setEndpoint(nextEndpoint)
|
||||
if (nextEndpoint === LIGHT_CLIENT_ENDPOINT) {
|
||||
setForkMethod("none")
|
||||
}
|
||||
}
|
||||
|
||||
const toggleForkMethod = (method: ForkMethod) => {
|
||||
setForkMethod((current) => (current === method ? "none" : method))
|
||||
}
|
||||
|
||||
const confirm = () => {
|
||||
if (network.id === "custom") {
|
||||
@@ -185,32 +184,7 @@ const NetworkSwitchDialogContent: FC<{
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="flex shrink-0 items-center justify-between gap-3 border-t pt-3">
|
||||
{canFork ? (
|
||||
<div className="flex min-w-0 items-center gap-3">
|
||||
<div className="text-xs font-medium uppercase tracking-wide text-muted-foreground">
|
||||
Fork with
|
||||
</div>
|
||||
<div className="flex flex-wrap gap-2">
|
||||
<ForkMethodOption
|
||||
value="chopsticks"
|
||||
title="Chopsticks"
|
||||
selected={selectedForkMethod === "chopsticks"}
|
||||
icon={<Chopsticks size={18} />}
|
||||
onSelect={toggleForkMethod}
|
||||
/>
|
||||
<ForkMethodOption
|
||||
value="forklift"
|
||||
title="Forklift"
|
||||
selected={selectedForkMethod === "forklift"}
|
||||
icon={<Forklift size={18} />}
|
||||
onSelect={toggleForkMethod}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<div />
|
||||
)}
|
||||
<div className="flex shrink-0 items-center justify-end gap-3 border-t pt-3">
|
||||
<Button
|
||||
className="min-w-28"
|
||||
onClick={confirm}
|
||||
@@ -227,26 +201,6 @@ const NetworkSwitchDialogContent: FC<{
|
||||
)
|
||||
}
|
||||
|
||||
const ForkMethodOption: FC<{
|
||||
value: Exclude<ForkMethod, "none">
|
||||
title: string
|
||||
selected: boolean
|
||||
icon?: React.ReactNode
|
||||
onSelect: (value: ForkMethod) => void
|
||||
}> = ({ value, title, selected, icon, onSelect }) => (
|
||||
<button
|
||||
type="button"
|
||||
className={twMerge(
|
||||
"flex items-center gap-1.5 rounded-md border border-transparent px-2 py-1.5 text-sm",
|
||||
selected && "border-polkadot bg-polkadot/5",
|
||||
)}
|
||||
aria-pressed={selected}
|
||||
onClick={() => onSelect(value)}
|
||||
>
|
||||
{icon}
|
||||
{title}
|
||||
</button>
|
||||
)
|
||||
|
||||
const NetworkList: FC<{
|
||||
query: string
|
||||
|
||||
Reference in New Issue
Block a user