138 lines
5.7 KiB
TypeScript
138 lines
5.7 KiB
TypeScript
import { useState } from "react"
|
|
import { useParams } from "react-router-dom"
|
|
import useSWR from "swr"
|
|
|
|
import { rpc } from "../api"
|
|
import { UserSignedExtensions as UserSignedExtensionsTy } from "@/types/UserSignedExtension"
|
|
import { wellKnownChainIdByGenesisHash } from "@/constants"
|
|
|
|
import { Layout } from "@/components/Layout"
|
|
import { Button } from "@/components/ui/button"
|
|
import { Input } from "@/components/ui/input"
|
|
import { ScrollArea } from "@/components/ui/scroll-area"
|
|
import { Textarea } from "@/components/ui/textarea"
|
|
import {
|
|
DecodedCallData,
|
|
UserSignedExtensionInputs,
|
|
UserSignedExtensions,
|
|
} from "../components"
|
|
|
|
export const SignRequest = () => {
|
|
const { signRequestId } = useParams<{ signRequestId: string }>()
|
|
const [userSignedExtensions, setUserSignedExtensions] = useState<Partial<UserSignedExtensionsTy>>({})
|
|
const {
|
|
data: signRequests,
|
|
error,
|
|
isLoading,
|
|
} = useSWR(signRequestId ? ["getSignRequest"] : null, () =>
|
|
rpc.client.getSignRequests(),
|
|
)
|
|
if (!signRequestId) {
|
|
window.close()
|
|
return null
|
|
}
|
|
if (isLoading) {
|
|
return (
|
|
<Layout>
|
|
<h1 className="text-3xl font-bold mb-6 px-6">Loading Sign Request #{signRequestId}</h1>
|
|
</Layout>
|
|
)
|
|
}
|
|
const request = signRequests?.[signRequestId]
|
|
if (error || !request) {
|
|
return (
|
|
<Layout>
|
|
<h1>Could not parse the sign request #{signRequestId}</h1>
|
|
<br />
|
|
Error: {error?.message}
|
|
</Layout>
|
|
)
|
|
}
|
|
|
|
return (
|
|
<Layout>
|
|
<h1 className="text-3xl font-bold mb-6 px-6">Sign Request #{signRequestId}</h1>
|
|
<ScrollArea className="px-6 mb-4 grow sm:px-8">
|
|
<section>
|
|
<div className="my-4">
|
|
<div className="my-2">
|
|
<div className="text-xs font-semibold mb-2 mt-4">Origin</div>
|
|
<Input
|
|
readOnly
|
|
aria-label="Request Origin"
|
|
type="text"
|
|
className="pr-10"
|
|
placeholder={request.url}
|
|
/>
|
|
</div>
|
|
<div className="my-2 overflow-hidden">
|
|
<div className="text-xs font-semibold mb-2 mt-4">Chain</div>
|
|
<Input
|
|
readOnly
|
|
aria-label="Request Origin"
|
|
type="text"
|
|
className="pr-10"
|
|
placeholder={wellKnownChainIdByGenesisHash[request.chainId]}
|
|
/>
|
|
</div>
|
|
<div className="my-2">
|
|
<div className="text-xs font-semibold mb-2 mt-4">From Address</div>
|
|
<Input
|
|
readOnly
|
|
aria-label="From Address"
|
|
type="text"
|
|
className="pr-10"
|
|
placeholder={request.address}
|
|
/>
|
|
</div>
|
|
<div className="my-2 overflow-hidden">
|
|
<div className="text-xs font-semibold mb-2 mt-4">Call data</div>
|
|
<Textarea
|
|
readOnly
|
|
aria-label="Call data"
|
|
rows={6}
|
|
className="text-sm text-justify resize-none"
|
|
placeholder={request.callData}
|
|
/>
|
|
</div>
|
|
<div className="my-2">
|
|
<div className="text-xs font-semibold mb-2 mt-4">Decoded Call data</div>
|
|
<DecodedCallData chainId={request.chainId} callData={request.callData} />
|
|
</div>
|
|
<div className="my-2">
|
|
{request.userSignedExtensions.type === "names" ? (
|
|
<UserSignedExtensionInputs
|
|
userSignedExtensionNames={request.userSignedExtensions.names}
|
|
onChange={setUserSignedExtensions}
|
|
/>
|
|
) : (
|
|
<UserSignedExtensions
|
|
userSignedExtensions={request.userSignedExtensions.values}
|
|
/>
|
|
)}
|
|
</div>
|
|
</div>
|
|
<div className="w-full flex gap-4 justify-center space-x-4 pt-6">
|
|
<Button
|
|
variant="secondary"
|
|
size="full"
|
|
className="h-12"
|
|
onClick={() => rpc.client.approveSignRequest(signRequestId, userSignedExtensions)}
|
|
>
|
|
Approve
|
|
</Button>
|
|
<Button
|
|
variant="secondary"
|
|
size="full"
|
|
className="h-12"
|
|
onClick={() => rpc.client.cancelSignRequest(signRequestId)}
|
|
>
|
|
Cancel
|
|
</Button>
|
|
</div>
|
|
</section>
|
|
</ScrollArea>
|
|
</Layout>
|
|
)
|
|
}
|