Mensagem de erro
invalid raw signature length
Também aparece como
- invalid raw signature length (argument="signature", value="0x…", code=INVALID_ARGUMENT, version=6.17.0)
- TypeError: invalid raw signature length
`err.shortMessage` é “invalid raw signature length”; `err.message` acrescenta o argumento, o valor e a versão do ethers. O erro é um `TypeError` com `code: "INVALID_ARGUMENT"`.
ethers v6 (JavaScript) — Signature.from() inside verifyMessage / verifyTypedData / recoverAddress
O que significa
O ethers tentou interpretar os bytes da assinatura como uma assinatura ECDSA para recuperar o endereço, e o comprimento não se encaixa em nenhuma das formas que ele conhece: 65 bytes (r‖s‖v) ou 64 bytes (a forma compacta da EIP-2098). Nenhuma recuperação foi tentada. Em geral, os bytes são de outro tipo de assinatura — uma assinatura de conta inteligente, que precisa ser verificada on-chain, ou uma assinatura codificada em DER vinda de um serviço de gerenciamento de chaves.
Por que acontece
Uma assinatura de carteira de contrato inteligente
comumSafe, Coinbase Smart Wallet, Argent e outras contas ERC-4337 retornam assinaturas que só o contrato da conta consegue validar (ERC-1271), muitas vezes encapsuladas conforme a ERC-6492 no caso de contas ainda não implantadas. Elas têm centenas de bytes e não podem ser verificadas com `verifyMessage`.
Uma assinatura DER do AWS KMS ou do Google Cloud KMS
comumChaves `ECC_SECG_P256K1` do AWS KMS e `EC_SIGN_SECP256K1_SHA256` do Google Cloud KMS retornam ASN.1 DER (70–72 bytes) sem ID de recuperação. A assinatura precisa ser convertida antes para r‖s‖v.
Assinatura truncada ou codificada duas vezes
ocasionalUma assinatura cortada por uma coluna do banco de dados, o hex de uma string que já era hex ou um valor que perdeu o último byte quando o `v` foi armazenado separadamente.
Como corrigir
- 1.
Verificar contas inteligentes on-chain
Chame `isValidSignature` (ERC-1271) na conta ou use uma biblioteca que implemente a ERC-6492 para contas contrafactuais (por exemplo, o `verifyMessage` do viem com um cliente público).
js import { Contract, hashMessage, JsonRpcProvider } from "ethers"; // Smart accounts (Safe, Coinbase Smart Wallet, ERC-4337 accounts) are verified on-chain (ERC-1271). const provider = new JsonRpcProvider(process.env.RPC_URL); const account = new Contract(address, ["function isValidSignature(bytes32,bytes) view returns (bytes4)"], provider); const magic = await account.isValidSignature(hashMessage(message), signature); const valid = magic === "0x1626ba7e"; - 2.
Converter DER para r‖s‖v
Extraia r e s, normalize s para a metade inferior da ordem da curva (o Ethereum rejeita valores high-s) e teste os dois bits de recuperação para achar o que produz o endereço esperado.
js import { Signature, recoverAddress, hashMessage, toBeHex } from "ethers"; import { secp256k1 } from "@noble/curves/secp256k1.js"; // @noble/curves v2 const N = 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141n; // secp256k1 order // KMS/HSM: parse DER, move s to the lower half (Ethereum rejects high-s), then find the recovery bit. function derToEthSignature(derBytes, digest, expectedAddress) { const { r, s } = secp256k1.Signature.fromBytes(derBytes, "der"); const lowS = s > N / 2n ? N - s : s; for (const yParity of [0, 1]) { const candidate = Signature.from({ r: toBeHex(r, 32), s: toBeHex(lowS, 32), yParity }); if (recoverAddress(digest, candidate) === expectedAddress) return candidate.serialized; // 65 bytes } throw new Error("signature does not belong to " + expectedAddress); } const signature = derToEthSignature(kmsDer, hashMessage(message), kmsAddress);