Sign Message
JoyID implements the EIP-191 ↗ (opens in a new tab) standard for signing messages. This allows for a more secure way of signing messages, as it prevents the user from signing a message that they did not intend to sign.
Sign text message
You can sign a message using the signMessage
method. This method takes a string
or bytes
as a parameter and returns a hex-encoded signature.
import { Address } from 'viem'
import { signMessage } from '@joyid/evm';
interface Props {
address: Address | null;
}
const SignMessage = ({ address }: Props) => {
const [message, setMessage] = React.useState("Hello world");
const [signature, setSignature] = React.useState<Address>("0x");
const onSign = async () => {
const sig = await signMessage(message, address!);
setSignature(sig);
};
return address ? (
<div className="w-full">
<h2 className="mb-4 text-lg text-center">Sign Message</h2>
<label className="label">Message:</label>
<input
className="input input-bordered w-full mb-4"
value={message}
onChange={(e) => setMessage(e.target.value)}
/>
<label className="label">Signature:</label>
<textarea
className="textarea textarea-bordered w-full mb-4"
placeholder="Signature"
value={signature}
disabled
></textarea>
<button className="btn btn-primary mb-4 mr-4" onClick={onSign}>
Sign
</button>
<div className="divider"></div>
</div>
) : null;
};
Sign bytes message
Note that the signMessage
method also accepts a bytes
parameter. This allows you to sign any arbitrary data. If the message is a string, it is signed as UTF-8 encoded bytes. It is not interpretted as a BytesLike; so the string "0x1234" is signed as six characters, not two bytes.
To sign that example as two bytes, the Uint8Array
should be used (i.e. new Uint8Array([ 0x12, 0x34 ])
).
If your message is a hex string, you should convert it to a Uint8Array
.
import { toBytes } from 'viem'
import { signMessage } from '@joyid/evm'
function signHexMessage(message: string, address: Address) {
// message is a hex string, like "0x1234"
const bytes = toBytes(message);
return signMessage(bytes, address);
}
function signBytesMessage(message: Uint8Array, address: Address) {
// message is a Uint8Array, just pass it through
return signMessage(message, address);
}
Verify Message
Since the message is signed using the EIP-191 standard, it can be verified using any EIP-191 compliant library.
import { verifyMessage } from 'ethers/lib/utils'
function verify(message: string, address: string) {
const signature = await signMessage(message, address);
const res = verifyMessage(message, signature);
}