Sign a Message
Sign an arbitrary message with the connected wallet — useful for off-chain authentication (e.g. "Sign in with Solana").
Code
SignMessage.tsx
import { useSignMessage } from '@wankmi/wankmi'
export function SignMessage() {
const { signMessage, isPending, isSuccess, isError, data: signature } =
useSignMessage()
function handleSign() {
const message = new TextEncoder().encode(
`Sign in to MyApp\nTimestamp: ${Date.now()}`
)
signMessage(message)
}
return (
<div>
<button onClick={handleSign} disabled={isPending}>
{isPending ? 'Waiting for signature...' : 'Sign In with Solana'}
</button>
{isSuccess && signature && (
<p>
✅ Signed! Signature:{' '}
<code>{Buffer.from(signature).toString('hex').slice(0, 16)}...</code>
</p>
)}
{isError && <p>❌ Signing rejected.</p>}
</div>
)
}Verifying the signature (server-side)
verify.ts
import nacl from 'tweetnacl'
import { PublicKey } from '@solana/web3.js'
import bs58 from 'bs58'
function verifySignature(
message: string,
signature: Uint8Array,
publicKeyBase58: string
): boolean {
const messageBytes = new TextEncoder().encode(message)
const publicKeyBytes = new PublicKey(publicKeyBase58).toBytes()
return nacl.sign.detached.verify(messageBytes, signature, publicKeyBytes)
}Install the required packages:
npm install tweetnacl bs58Notes
- The message should include a timestamp or nonce to prevent replay attacks.
- The signature is a
Uint8Array— encode it as hex or base58 to transmit over HTTP. - This pattern is the basis of Sign In With Solana (SIWS) (opens in a new tab).