Prerequisites
You need Web3 libraries configured with Para authentication.Setup Web3 Libraries
Sign Personal Messages
- Ethers.js
- Viem
- Wagmi
Copy
Ask AI
import { ethers } from "ethers";
import { ParaEthersSigner } from "@getpara/ethers-v6-integration";
async function signMessage(
signer: ParaEthersSigner,
message: string
) {
try {
const signature = await signer.signMessage(message);
console.log("Signature:", signature);
const address = await signer.getAddress();
const recoveredAddress = ethers.verifyMessage(message, signature);
console.log("Signer address:", address);
console.log("Recovered address:", recoveredAddress);
console.log("Signature valid:", address === recoveredAddress);
return {
signature,
address,
message,
isValid: address.toLowerCase() === recoveredAddress.toLowerCase()
};
} catch (error) {
console.error("Failed to sign message:", error);
throw error;
}
}
Copy
Ask AI
import { verifyMessage } from "viem";
async function signMessage(
walletClient: any,
account: any,
message: string
) {
try {
const signature = await walletClient.signMessage({
account,
message
});
console.log("Signature:", signature);
const isValid = await verifyMessage({
address: account.address,
message,
signature
});
console.log("Signature valid:", isValid);
return {
signature,
address: account.address,
message,
isValid
};
} catch (error) {
console.error("Failed to sign message:", error);
throw error;
}
}
Copy
Ask AI
import { useSignMessage } from "wagmi";
import { verifyMessage } from "viem";
function SignMessage() {
const {
data: signature,
isLoading,
signMessage,
variables
} = useSignMessage();
const handleSign = () => {
signMessage({
message: "Hello from Para!"
});
};
const verifySignature = async () => {
if (!signature || !variables?.message) return;
const isValid = await verifyMessage({
address: "0x...", // User's address
message: variables.message,
signature
});
console.log("Signature valid:", isValid);
};
return (
<div>
<button
onClick={handleSign}
disabled={isLoading}
>
{isLoading ? "Signing..." : "Sign Message"}
</button>
{signature && (
<div>
<p>Signature: {signature.slice(0, 20)}...</p>
<button onClick={verifySignature}>
Verify Signature
</button>
</div>
)}
</div>
);
}
Sign Structured Messages
- Ethers.js
- Viem
- Wagmi
Copy
Ask AI
async function signStructuredMessage(
signer: ParaEthersSigner,
data: any
) {
try {
const message = JSON.stringify(data, null, 2);
const messageHash = ethers.hashMessage(message);
console.log("Message hash:", messageHash);
const signature = await signer.signMessage(message);
const signerAddress = await signer.getAddress();
const recoveredAddress = ethers.recoverAddress(
messageHash,
signature
);
return {
message,
messageHash,
signature,
signerAddress,
recoveredAddress,
isValid: signerAddress.toLowerCase() === recoveredAddress.toLowerCase()
};
} catch (error) {
console.error("Failed to sign structured message:", error);
throw error;
}
}
Copy
Ask AI
import { hashMessage, recoverMessageAddress } from "viem";
async function signStructuredMessage(
walletClient: any,
account: any,
data: any
) {
try {
const message = JSON.stringify(data, null, 2);
const messageHash = hashMessage(message);
console.log("Message hash:", messageHash);
const signature = await walletClient.signMessage({
account,
message
});
const recoveredAddress = await recoverMessageAddress({
message,
signature
});
return {
message,
messageHash,
signature,
signerAddress: account.address,
recoveredAddress,
isValid: account.address.toLowerCase() === recoveredAddress.toLowerCase()
};
} catch (error) {
console.error("Failed to sign structured message:", error);
throw error;
}
}
Copy
Ask AI
import { useAccount, useSignMessage } from "wagmi";
import { hashMessage } from "viem";
function SignStructuredMessage() {
const { address } = useAccount();
const { signMessage, data: signature } = useSignMessage();
const signData = (data: any) => {
const message = JSON.stringify(data, null, 2);
const messageHash = hashMessage(message);
console.log("Signing hash:", messageHash);
signMessage({ message });
};
const handleSign = () => {
const data = {
action: "authenticate",
timestamp: Date.now(),
nonce: Math.random().toString(36).substring(7)
};
signData(data);
};
return (
<div>
<button onClick={handleSign}>
Sign Structured Data
</button>
{signature && (
<p>Signature: {signature.slice(0, 30)}...</p>
)}
</div>
);
}