-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathSignButton.tsx
More file actions
97 lines (90 loc) · 2.81 KB
/
Copy pathSignButton.tsx
File metadata and controls
97 lines (90 loc) · 2.81 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
import { type ButtonProps, chakra } from '@chakra-ui/react'
import type { FC, ReactElement } from 'react'
import { useSignMessage } from 'wagmi'
import SwitchChainButton from '@/src/components/sharedComponents/ui/SwitchChainButton'
import { useWalletStatus } from '@/src/hooks/useWalletStatus'
import type { ChainsIds } from '@/src/lib/networks.config'
import { useTransactionNotification } from '@/src/providers/TransactionNotificationProvider'
import { ConnectWalletButton } from '@/src/providers/Web3Provider'
interface SignButtonProps extends Omit<ButtonProps, 'onError'> {
/** Target chain ID for wallet status verification. */
chainId?: ChainsIds
/** Custom fallback when wallet needs connection. Defaults to ConnectWalletButton. */
fallback?: ReactElement
/** Button label while signing. Defaults to 'Signing...'. */
labelSigning?: string
/** The message to sign. */
message: string
/** Callback function called when an error occurs. */
onError?: (error: Error) => void
/** Callback function called when the message is signed. */
onSign?: (signature: string) => void
/** Label for the switch chain button. Defaults to 'Switch to'. */
switchChainLabel?: string
}
/**
* Self-contained message signing button with wallet verification.
*
* Handles wallet connection status internally — shows a connect button if not connected,
* a switch chain button if on the wrong chain, or the sign button when ready.
*
* @example
* ```tsx
* <SignButton
* message="Hello, world!"
* onError={(error) => console.error(error)}
* onSign={(signature) => console.log(signature)}
* />
* ```
*/
const SignButton: FC<SignButtonProps> = ({
chainId,
children = 'Sign Message',
disabled,
fallback = <ConnectWalletButton />,
labelSigning = 'Signing...',
message,
onError,
onSign,
switchChainLabel = 'Switch to',
...restProps
}) => {
const { needsConnect, needsChainSwitch, targetChain, targetChainId, switchChain } =
useWalletStatus({ chainId })
const { watchSignature } = useTransactionNotification()
const { isPending, mutateAsync: signMessageAsync } = useSignMessage({
mutation: {
onSuccess(data) {
onSign?.(data)
},
onError(error) {
onError?.(error)
},
},
})
if (needsConnect) {
return fallback
}
if (needsChainSwitch) {
return (
<SwitchChainButton onClick={() => switchChain(targetChainId)}>
{switchChainLabel} {targetChain.name}
</SwitchChainButton>
)
}
return (
<chakra.button
disabled={disabled || isPending}
onClick={() => {
watchSignature({
message: 'Signing message...',
signaturePromise: signMessageAsync({ message }),
})
}}
{...restProps}
>
{isPending ? labelSigning : children}
</chakra.button>
)
}
export default SignButton