Skip to content

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

@0xultravioleta

Description

@0xultravioleta

Bug

ows sign message --chain evm returns a 64-byte signature (128 hex chars) instead of the expected 65 bytes (130 hex chars). The v byte (recovery ID) is missing from the output.

Environment

  • OWS CLI v1.2.0 (installed via npm install -g @open-wallet-standard/core)
  • Platform: Linux x64 (Ubuntu 24.04 via WSL)
  • Node.js v20

Steps to Reproduce

ows wallet create --name test-wallet
ows sign message --wallet test-wallet --chain evm --message "hello world"

Expected

65-byte signature (130 hex chars): r (32 bytes) + s (32 bytes) + v (1 byte)

Actual

64-byte signature (128 hex chars): r (32 bytes) + s (32 bytes) — v byte is missing.

The recoveryId field IS returned correctly (0 or 1), but the signature hex itself is only 64 bytes.

Impact

ERC-8128 (HTTP Message Signatures with Ethereum) and any EIP-191 personal_sign verification requires 65-byte signatures. The missing v byte causes ecrecover to fail with "Signature recovery failed".

Workaround

We detect 64-byte signatures and append the v byte from recoveryId:

if (sigHex.length === 128) {
  const v = recoveryId < 27 ? recoveryId + 27 : recoveryId;
  sigHex = sigHex + v.toString(16).padStart(2, '0');
}

Note

The Node.js SDK (NAPI-RS binding, @open-wallet-standard/core used programmatically) does NOT have this bug — signMessage() returns correct 65-byte signatures with recoveryId: 27/28. The bug appears to be CLI-specific.

Context

Discovered during Execution Market integration with OWS for the OWS Hackathon (April 3, 2026). We're using OWS as the wallet layer for AI agent commerce with ERC-8128 authentication.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions