Skip to content

fix(adapters): serialize bigints in viem signTypedData - #242

Open
SgtPooki wants to merge 1 commit into
open-wallet-standard:mainfrom
SgtPooki:fix/viem-signtypeddata-bigint
Open

fix(adapters): serialize bigints in viem signTypedData#242
SgtPooki wants to merge 1 commit into
open-wallet-standard:mainfrom
SgtPooki:fix/viem-signtypeddata-bigint

Conversation

@SgtPooki

@SgtPooki SgtPooki commented Jul 27, 2026

Copy link
Copy Markdown

What changed

owsToViemAccount().signTypedData serialized the payload with JSON.stringify, which throws TypeError: Do not know how to serialize a BigInt whenever the message holds a uint256. viem hands a local account its message with bigints intact (only viem's JSON-RPC path pre-serializes), so an EIP-712 payload that signs an id, nonce, amount, or deadline never signed. That covers EIP-2612 permits and most protocol authorizations.

This encodes bigints as even-length hex before handing the JSON to the core. The core's parser enforces two things: decimal uint values above 2^128 are rejected ("exceeds u128 range; use hex encoding"), and hex must have an even number of digits. Even-length hex satisfies both across the full uint256 range.

It also adds EIP712Domain to types when the caller omits it. viem's signTypedData action adds it before calling an account, but a direct account.signTypedData() call does not, and the core needs it to resolve the domain type.

signMessage and signTransaction are unchanged.

How to verify

cd bindings/node-adapters && npm test

The added test signs a message carrying uint256 and uint256[] values (0, 2^200, 2^256-1) and asserts the signature is byte-identical to viem's privateKeyToAccount. It fails on main with Do not know how to serialize a BigInt and passes with this change.

Notes

JS-only change under bindings/node-adapters; no Rust or public API change. Also verified against a Filecoin FEVM integration on the Calibration testnet: AddPieces and SchedulePieceRemovals both signed and confirmed on-chain through this adapter.

related filecoin-project/filecoin-pin#458

owsToViemAccount().signTypedData ran JSON.stringify over the typed data,
which throws "Do not know how to serialize a BigInt" whenever the message
holds a uint256 (nonce, id, amount, deadline). viem hands a local account
its message with bigints intact, so a real EIP-712 payload never signed.

Encode bigints as even-length hex, which the core's parser accepts across
the full uint256 range, and add EIP712Domain when the caller omits it
(viem's signTypedData action adds it; a direct account call does not).

The added test signs a uint256-bearing message and compares the signature
to viem's privateKeyToAccount.
@vercel

vercel Bot commented Jul 27, 2026

Copy link
Copy Markdown

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

A member of the Team first needs to authorize it.

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.

1 participant