Pallet Call
-
- {decodedCallData!.pallet.value.name} {decodedCallData!.call.value.name}
+
+ {decodedCallData?.pallet?.value?.name} :: {decodedCallData?.call?.value?.name}
+
Args
-
+
+
+
)
}
@@ -78,16 +95,16 @@ const DecodedPrimitiveValue = ({ value }: DecodedPrimitiveProps) => {
case "char":
case "str":
case "Bytes": {
- return
{value.value}
+ return
{value.value}
}
case "AccountId": {
- return
{value.value.address}
+ return
{value.value.address}
}
case "bitSequence": {
// FIXME: improve bitsequence UI
// for example: n1,n2,...,n
return (
-
BitSequence: {toHex(value.value.bytes)}({value.value.bitsLen})
+
BitSequence: {toHex(value.value.bytes)}({value.value.bitsLen})
)
}
case "compactBn":
@@ -116,7 +133,7 @@ type DecodedComplexProps = {
const DecodedComplexValue = ({ value }: DecodedComplexProps) => {
switch (value.codec) {
case "BytesArray": {
- return
{value.value}
+ return
{value.value}
}
case "Tuple":
case "Sequence":
@@ -126,7 +143,7 @@ const DecodedComplexValue = ({ value }: DecodedComplexProps) => {
case "Enum": {
return (
<>
-
{value.value.type}
+
{value.value.type}
>
)
@@ -141,7 +158,7 @@ const DecodedComplexValue = ({ value }: DecodedComplexProps) => {
case "Result": {
return (
<>
-
{value.value.success ? "Ok" : "Error"}
+
{value.value.success ? "Ok" : "Error"}
>
)
@@ -149,13 +166,13 @@ const DecodedComplexValue = ({ value }: DecodedComplexProps) => {
case "Struct": {
return Object.entries(value.value).map(([key, value]) => (
<>
-
{key}
+
{key}
>
))
}
default:
- return
{jsonStringify(value)}
+ return
{jsonStringify(value)}
}
}
diff --git a/src/containers/WalletPopup/components/JohnMcAffee.tsx b/src/containers/WalletPopup/components/JohnMcAffee.tsx
new file mode 100644
index 0000000..2fd4b41
--- /dev/null
+++ b/src/containers/WalletPopup/components/JohnMcAffee.tsx
@@ -0,0 +1,302 @@
+import { SVGProps, useEffect, useRef } from "react"
+
+interface McAffeeProps extends SVGProps
{
+ leftEyeRef: React.RefObject
+ rightEyeRef: React.RefObject
+}
+
+export const JohnMcAffeeIcon = (props: SVGProps) => {
+ const leftEyeRef = useRef(null)
+ const rightEyeRef = useRef(null)
+
+ useEffect(() => {
+ const maxDistance = 10
+
+ const targetMouse = { x: 0, y: 0 }
+ const currentPos = { x: 0, y: 0 }
+
+ let isResetting = false
+ let isAwaitingMovement = false
+ let resetTimer: NodeJS.Timeout | null = null
+
+ const handleMouseMove = (event: MouseEvent) => {
+ if (isResetting || isAwaitingMovement) {
+ isResetting = false
+ isAwaitingMovement = false
+ }
+
+ targetMouse.x = event.clientX
+ targetMouse.y = event.clientY
+
+ if (resetTimer) clearTimeout(resetTimer)
+ resetTimer = setTimeout(() => {
+ triggerEyeReset()
+ }, 1500)
+ }
+
+ const triggerEyeReset = () => {
+ if (!isAwaitingMovement) {
+ isResetting = true
+ }
+ }
+
+ let animationFrameId: number
+
+ const updateAnimation = () => {
+ const eyeRefs = [leftEyeRef, rightEyeRef]
+
+ eyeRefs.forEach((ref) => {
+ const eyeElement = ref.current
+ if (!eyeElement) return
+
+ const rect = eyeElement.getBoundingClientRect()
+ const centerX = rect.left + rect.width / 2
+ const centerY = rect.top + rect.height / 2
+
+ let targetX = 0
+ let targetY = 0
+
+ if (isResetting || isAwaitingMovement) {
+ targetX = 0
+ targetY = 0
+ } else {
+ const dx = targetMouse.x - centerX
+ const dy = targetMouse.y - centerY
+ const angle = Math.atan2(dy, dx)
+ const distance = Math.hypot(dx, dy)
+
+ const limitedDistance = Math.min(distance * 0.2, maxDistance)
+ targetX = Math.cos(angle) * limitedDistance
+ targetY = Math.sin(angle) * limitedDistance
+ }
+
+ const speed = 0.12
+
+ currentPos.x += (targetX - currentPos.x) * speed
+ currentPos.y += (targetY - currentPos.y) * speed
+
+ eyeElement.setAttribute("transform", `translate(${currentPos.x}, ${currentPos.y})`)
+ })
+
+ if (isResetting) {
+ const distanceToResetTarget = Math.hypot(currentPos.x - 0, currentPos.y - 0)
+ if (distanceToResetTarget < 0.1) {
+ isResetting = false
+ isAwaitingMovement = true
+ if (resetTimer) clearTimeout(resetTimer)
+ }
+ }
+
+ animationFrameId = requestAnimationFrame(updateAnimation)
+ }
+
+ document.addEventListener("mousemove", handleMouseMove)
+ animationFrameId = requestAnimationFrame(updateAnimation)
+
+ return () => {
+ document.removeEventListener("mousemove", handleMouseMove)
+ cancelAnimationFrame(animationFrameId)
+ if (resetTimer) clearTimeout(resetTimer)
+ }
+ }, [])
+
+ return (
+
+ )
+}
diff --git a/src/containers/WalletPopup/components/NetworkLogo.tsx b/src/containers/WalletPopup/components/NetworkLogo.tsx
new file mode 100644
index 0000000..39d48ea
--- /dev/null
+++ b/src/containers/WalletPopup/components/NetworkLogo.tsx
@@ -0,0 +1,88 @@
+const ghostLogo = () => {
+ return (
+
+ )
+}
+
+const casperLogo = () => {
+ return (
+
+ )
+}
+
+const logoMap: Record>> = {
+ casper_staging_testnet: casperLogo,
+};
+
+export const NetworkLogo = ({ value, className }: { value: string | undefined; className?: string }) => {
+ const Logo = logoMap[value ?? ""];
+ if (!Logo) return ;
+
+ return (
+
+
+
+ )
+};
diff --git a/src/containers/WalletPopup/components/ProtectedRoute.tsx b/src/containers/WalletPopup/components/ProtectedRoute.tsx
deleted file mode 100644
index f30049e..0000000
--- a/src/containers/WalletPopup/components/ProtectedRoute.tsx
+++ /dev/null
@@ -1,33 +0,0 @@
-import { ReactNode, useEffect } from "react"
-import { Navigate, Outlet, useLocation } from "react-router-dom"
-import { useKeyring } from "../hooks"
-
-export const ProtectedRoute = ({ children }: { children?: ReactNode }) => {
- const location = useLocation()
- const {
- lock,
- keyring: { isLocked, hasPassword },
- } = useKeyring()
-
- useEffect(() => {
- if (!isLocked && hasPassword && location.key === "default") {
- lock()
- }
- }, []);
-
- return !hasPassword ? (
-
- ) : isLocked ? (
-
- ) : (
- (children ?? )
- )
-}
diff --git a/src/containers/WalletPopup/components/UserSignedExtensionInputs.tsx b/src/containers/WalletPopup/components/UserSignedExtensionInputs.tsx
index c66384f..ef0a578 100644
--- a/src/containers/WalletPopup/components/UserSignedExtensionInputs.tsx
+++ b/src/containers/WalletPopup/components/UserSignedExtensionInputs.tsx
@@ -12,8 +12,8 @@ import {
SelectContent,
SelectGroup,
SelectItem,
-} from "../../../components/ui/select"
-import { Input } from "../../../components/ui/input"
+} from "@/components/ui/select"
+import { Input } from "@/components/ui/input"
const reducer = (
state: Partial,
@@ -73,20 +73,26 @@ export const UserSignedExtensionInputs = ({
type TipInputProps = {
onChange(value: UserSignedExtensions["ChargeTransactionPayment"]): void
- defaultValue?: number
+ defaultValue?: bigint
}
-const TipInput = ({ onChange, defaultValue = 0 }: TipInputProps) => {
- // @ts-expect-error TODO: improve bigint types
+const TipInput = ({ onChange, defaultValue = 0n }: TipInputProps) => {
useEffect(() => onChange(defaultValue), [])
return (
-
+
)
@@ -107,10 +113,10 @@ const MortalityInput = ({
}: MortalityInputProps) => {
useEffect(() => onChange(defaultValue), [])
return (
-
+
Transaction Mortality
-