requirePin: true.
All signatures are:
0x-prefixed 130-character hex strings- Recoverable ECDSA in
r(32) ‖ s(32) ‖ v(1)format - Low-s normalised (EIP-2 compliant)
v ∈ {27, 28}— verifiable withecrecover
Sign a personal message (EIP-191)
signMessage prepends the \x19Ethereum Signed Message:\n{length} prefix before hashing and signing. This matches the personal_sign RPC method used by SIWE, login challenges, and most wallet connect flows.
requirePin: false, omit the pin argument:
Sign a 32-byte hash
signTransactionHash signs a pre-computed 32-byte digest directly, without adding any prefix. Use this for:
- ERC-4337
userOpHash - EIP-712 structured-data digests
- Raw Ethereum transaction hashes
- Any other 32-byte payload you’ve already hashed yourself
0x-prefixed 64-hex-character (32-byte) string. Anything else throws signInvalidHash.
Server-side verification
Signatures are ECDSA-recoverable. Your backend (or a smart contract) only needs the address frominitWallet():
Gating pattern
A common pattern is to ask for the PIN only whenrequirePin is true, and skip the prompt otherwise:
Prerequisites checklist
Before calling either signing method you need:- A provisioned wallet (
initWallet()succeeded orhasWallet()istrue) - A PIN set (
hasPin()istrue) — only whenrequirePin: true
pinNotSet or result in a native error.
