Skip to main content

Sign and Verify Message

Overview

This React component creates a user interface for signing and verifying messages using an Movement wallet. It's commonly used in blockchain applications to prove ownership of a wallet address by signing messages.

Key Features

  1. Message signing
  2. Message verification
  3. Wallet connection status
  4. Error handling

How It Works

1️⃣ Component Setup

const { signMessage, signMessageAndVerify, connected, account } = useWallet();
  • Uses the Aptos wallet adapter to get necessary functions and wallet status
  • connected: Tells if wallet is connected
  • account: Contains wallet information

2️⃣ State Management

const [message, setMessage] = useState<string>('');
const [nonce, setNonce] = useState<string>('');
const [signedMessage, setSignedMessage] = useState<any>(null);
const [verificationResult, setVerificationResult] = useState<boolean | null>(null);
const [error, setError] = useState<string | null>(null);

Manages five different states:

  • message: The text message to be signed
  • nonce: A random string to prevent replay attacks
  • signedMessage: Stores the signed message response
  • verificationResult: Stores whether the message verification was successful
  • error: Stores any error messages

3️⃣ Message Signing Function

const handleSignMessage = async () => {
setError(null);
try {
const response = await signMessage({ message, nonce });
setSignedMessage(response);
} catch (err: any) {
setError(`Failed to sign message: ${err.message}`);
}
};
  • Clears any previous errors
  • Attempts to sign the message using the wallet
  • Stores the signed message or captures any errors

4️⃣ Message Verification Function

const handleVerifyMessage = async () => {
setError(null);
try {
const result = await signMessageAndVerify({ message, nonce });
setVerificationResult(result);
} catch (err: any) {
setError(`Failed to verify message: ${err.message}`);
}
};
  • Clears any previous errors
  • Verifies the signed message
  • Stores the verification result or captures any errors

5️⃣ User Interface

The component renders different UI elements based on wallet connection status:

If wallet is not connected:

  • Shows a message asking user to connect wallet

If wallet is connected:

  1. Shows the connected wallet address
  2. Provides a text area for entering the message
  3. Provides an input field for the nonce
  4. Shows a "Sign Message" button
  5. If message is signed:
    • Displays the signed message
    • Shows a "Verify Message" button
  6. Shows verification result if available
  7. Displays any errors that occur

Use Cases

  1. Identity Verification: Prove ownership of a wallet address
  2. Authentication: Can be used as part of a login system
  3. Message Authentication: Ensure messages are authentic and haven't been tampered with

Error Handling

  • Handles signing errors
  • Handles verification errors
  • Displays user-friendly error messages

This component provides a complete solution for signing and verifying messages using an Aptos wallet, with a user-friendly interface and proper error handling.

Code Example

signAndVerify
import React, { useState } from 'react';
import { useWallet } from '@aptos-labs/wallet-adapter-react';

const SignMessageDemo = () => {
const { signMessage, signMessageAndVerify, connected, account } = useWallet();
const [message, setMessage] = useState<string>('');
const [nonce, setNonce] = useState<string>('');
const [signedMessage, setSignedMessage] = useState<any>(null);
const [verificationResult, setVerificationResult] = useState<boolean | null>(null);
const [error, setError] = useState<string | null>(null);

const handleSignMessage = async () => {
setError(null);
try {
const response = await signMessage({ message, nonce });
setSignedMessage(response);
} catch (err: any) {
setError(`Failed to sign message: ${err.message}`);
}
};

const handleVerifyMessage = async () => {
setError(null);
try {
const result = await signMessageAndVerify({ message, nonce });
setVerificationResult(result);
} catch (err: any) {
setError(`Failed to verify message: ${err.message}`);
}
};

return (
<div>
<h1>Aptos Sign and Verify Message</h1>
<div>
{connected ? (
<div>
<p>Connected to: {account?.address}</p>
<div className="flex flex-col gap-4">
<textarea
value={message}
onChange={(e) => setMessage(e.target.value)}
placeholder="Enter your message here"
className="border rounded p-2"
/>
<input
type="text"
value={nonce}
onChange={(e) => setNonce(e.target.value)}
placeholder="Enter nonce (random string) here"
className="border rounded p-2 mt-2"
/>
<button onClick={handleSignMessage} className="bg-blue-500 text-white rounded p-2 mt-2">
Sign Message
</button>
{signedMessage && (
<div>
<h4>Signed Message</h4>
<pre>{JSON.stringify(signedMessage, null, 2)}</pre>
<button onClick={handleVerifyMessage} className="bg-green-500 text-white rounded p-2 mt-2">
Verify Message
</button>
</div>
)}
{verificationResult !== null && (
<div>
<h4>Verification Result</h4>
<p>{verificationResult ? 'Message is verified!' : 'Failed to verify message.'}</p>
</div>
)}
{error && (
<div className="text-red-600">
<p>{error}</p>
</div>
)}
</div>
</div>
) : (
<p>Please connect your wallet to sign and verify messages.</p>
)}
</div>
</div>
);
};

export default SignMessageDemo;

Sign & Submit BCS Transaction

How to sign and submit a BCS (Binary Canonical Serialization) transaction on the MoveVM blockchain. It specifically shows how to transfer tokens using the Move account module.

Function Breakdown

Transaction Submission Function

const onSignAndSubmitBCSTransaction = async () => {
const response = await signAndSubmitTransaction({
sender: account.address,
data: {
function: "0x1::aptos_account::transfer",
functionArguments: [AccountAddress.from(account.address), new U64(1)],
},
});
// ... transaction confirmation ...
};

Key Components:

  1. Sender: The address of the account initiating the transaction
  2. Function Path: 0x1::aptos_account::transfer
    • 0x1: Core framework address
    • aptos_account: Module name
    • transfer: Function name
  3. Function Arguments:
    • AccountAddress.from(account.address): Recipient address
    • new U64(1): Amount to transfer (1 unit)

Transaction Confirmation

try {
await aptos.waitForTransaction({ transactionHash: response.hash });
} catch (error) {
console.error(error);
}
  • Waits for transaction confirmation
  • Handles any errors during confirmation process

UI Element

<button onClick={onSignAndSubmitTransaction}>
Sign and submit BCS transaction
</button>
  • Simple button to trigger the transaction

Important Notes

  1. BCS Format: Uses Binary Canonical Serialization for efficient transaction encoding
  2. Error Handling: Includes basic error handling for transaction confirmation
  3. Amount: Example shows transfer of 1 unit (adjust as needed)
  4. Gas Fees: Transaction will require gas fees (not shown in example)

Common Use Cases

  1. Token transfers
  2. Smart contract interactions
  3. Blockchain state modifications