From de4c639ae2b34450986f67af938a4226c87231fc Mon Sep 17 00:00:00 2001 From: Gregory Hill Date: Thu, 5 Sep 2024 18:44:17 +0100 Subject: [PATCH] feat: add sign message component Signed-off-by: Gregory Hill --- packages/sats-wagmi/src/connectors/mm-snap.ts | 22 +++++++++++-- packages/sats-wagmi/src/hooks/index.ts | 1 + .../src/hooks/useSendTransaction.tsx | 2 +- .../sats-wagmi/src/hooks/useSignMessage.tsx | 33 +++++++++++++++++++ playgrounds/vite-react/src/App.tsx | 28 +++++++++++++++- 5 files changed, 82 insertions(+), 4 deletions(-) create mode 100644 packages/sats-wagmi/src/hooks/useSignMessage.tsx diff --git a/packages/sats-wagmi/src/connectors/mm-snap.ts b/packages/sats-wagmi/src/connectors/mm-snap.ts index 3a54ce3..b160149 100644 --- a/packages/sats-wagmi/src/connectors/mm-snap.ts +++ b/packages/sats-wagmi/src/connectors/mm-snap.ts @@ -198,8 +198,26 @@ class MMSnapConnector extends SatsConnector { return pubkey.toString('hex'); } - signMessage(): Promise { - throw new Error('Not implemented'); + async signMessage(message: string): Promise { + try { + return (await ethereum.request({ + method: 'wallet_invokeSnap', + params: { + snapId, + request: { + method: 'btc_signMessage', + params: { + message, + hdPath: getDefaultBip32Path(DEFAULT_SCRIPT_TYPE, this.snapNetwork) + } + } + } + })) as string; + } catch (err: any) { + const error = new SnapError(err?.message || 'Could not sign message'); + + throw error; + } } async signInput(inputIndex: number, psbt: Psbt) { diff --git a/packages/sats-wagmi/src/hooks/index.ts b/packages/sats-wagmi/src/hooks/index.ts index 0fd627b..4341df0 100644 --- a/packages/sats-wagmi/src/hooks/index.ts +++ b/packages/sats-wagmi/src/hooks/index.ts @@ -5,3 +5,4 @@ export * from './useBalance'; export * from './useFeeRate'; export * from './useFeeEstimate'; export * from './useSendTransaction'; +export * from './useSignMessage'; diff --git a/packages/sats-wagmi/src/hooks/useSendTransaction.tsx b/packages/sats-wagmi/src/hooks/useSendTransaction.tsx index 1317513..fbf2abb 100644 --- a/packages/sats-wagmi/src/hooks/useSendTransaction.tsx +++ b/packages/sats-wagmi/src/hooks/useSendTransaction.tsx @@ -5,7 +5,7 @@ import { useSatsWagmi } from '../provider'; import { useAccount } from './useAccount'; type UseSendTransactionProps = Omit< - UseMutationOptions, + UseMutationOptions, 'mutationKey' | 'mutationFn' >; diff --git a/packages/sats-wagmi/src/hooks/useSignMessage.tsx b/packages/sats-wagmi/src/hooks/useSignMessage.tsx new file mode 100644 index 0000000..3d7a74d --- /dev/null +++ b/packages/sats-wagmi/src/hooks/useSignMessage.tsx @@ -0,0 +1,33 @@ +import { useMutation, UseMutationOptions } from '@tanstack/react-query'; + +import { useSatsWagmi } from '../provider'; + +import { useAccount } from './useAccount'; + +type UseSignMessageProps = Omit< + UseMutationOptions, + 'mutationKey' | 'mutationFn' +>; + +const useSignMessage = (props: UseSignMessageProps = {}) => { + const { connector } = useSatsWagmi(); + const { address } = useAccount(); + + const { mutate, mutateAsync, ...result } = useMutation({ + mutationKey: ['sats-sign-message', address], + mutationFn: async ({ message }: { message: string }) => { + if (!connector) return undefined; + + return await connector.signMessage(message); + }, + ...props + }); + + return { + ...result, + signMessage: mutate, + signMessageAsync: mutateAsync + }; +}; + +export { useSignMessage }; diff --git a/playgrounds/vite-react/src/App.tsx b/playgrounds/vite-react/src/App.tsx index 3a33662..ebf9273 100644 --- a/playgrounds/vite-react/src/App.tsx +++ b/playgrounds/vite-react/src/App.tsx @@ -6,7 +6,8 @@ import { useBalance, useConnect, useDisconnect, - useSendTransaction + useSendTransaction, + useSignMessage // useWaitForTransactionReceipt, } from '@gobob/sats-wagmi'; @@ -23,6 +24,7 @@ function App() { <> + @@ -71,6 +73,30 @@ function Connect() { ); } +function SignMessage() { + const { data, signMessage } = useSignMessage(); + + return ( +
+

Sign Message

+ +
{ + event.preventDefault(); + const formData = new FormData(event.target as HTMLFormElement); + + signMessage({ message: formData.get('message') as string }); + }} + > + + +
+ + {data} +
+ ); +} + function Balance() { const { data: account_ } = useBalance();