Skip to content

fix(cli): append v byte to EVM signMessage output - #188

Open
teyrebaz33 wants to merge 1 commit into
open-wallet-standard:mainfrom
teyrebaz33:fix/sign-message-missing-v-byte
Open

fix(cli): append v byte to EVM signMessage output#188
teyrebaz33 wants to merge 1 commit into
open-wallet-standard:mainfrom
teyrebaz33:fix/sign-message-missing-v-byte

Conversation

@teyrebaz33

Copy link
Copy Markdown

Bug

ows sign message --chain evm returns 64-byte signatures (r + s) instead of the expected 65 bytes (r + s + v), causing ecrecover failures in ERC-8128 and EIP-191 verification flows.

Fixes #171

Root cause

In sign_message.rs, the owner mode path encoded only output.signature (64 bytes) without appending the recovery ID as the v byte. The recoveryId field was correct but not included in the hex output.

Fix

Append v (normalized to 27/28) to the signature bytes before hex-encoding:

let mut sig = output.signature.clone();
if let Some(rid) = output.recovery_id {
    let v = if rid < 27 { rid + 27 } else { rid };
    sig.push(v);
}
hex::encode(&sig)

Notes

  • Node SDK binding was not affected — CLI only
  • API key path (via ows_lib::sign_message) was also not affected
  • 1 file changed, 7 lines

The CLI was returning 64-byte signatures (r + s only) instead of the
expected 65-byte format (r + s + v). The recovery ID was available in
the recoveryId field but not appended to the signature hex.

Fixes open-wallet-standard#171
@teyrebaz33
teyrebaz33 requested a review from njdawn as a code owner April 4, 2026 13:38
@vercel

vercel Bot commented Apr 4, 2026

Copy link
Copy Markdown

@teyrebaz33 is attempting to deploy a commit to the MoonPay Team on Vercel.

A member of the Team first needs to authorize it.

@0xultravioleta

Copy link
Copy Markdown
Collaborator

Thanks for digging into the message-signing path. I think this one introduces a regression though.

EvmSigner::sign_message already sets the recovery byte before it returns: it writes the v value into signature[64] and stores the matching recovery_id as 27 or 28. This PR appends another v byte on top of that, so the result comes out as r || s || v || v at 66 bytes instead of the standard 65-byte r || s || v. That breaks EIP-191 signatures for anything that verifies them.

Could you drop the extra append so the signature stays 65 bytes, and add a regression test against one of the existing EVM message vectors that asserts the length is 65 and v is 27 or 28? That'll lock the behavior in and make sure we don't slip back into a double byte. Happy to re-review once that's in.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

signMessage returns 64 bytes instead of 65 (missing v byte) on EVM

2 participants