Skip to content

Fixed: three viem mismatches in native ABI coding, and moved to viem 2.56.3 - #1

Merged
PetromirDev merged 2 commits into
mainfrom
fix/viem-2.56.3-parity
Oct 6, 2026
Merged

PetromirDev merged 2 commits into
mainfrom
fix/viem-2.56.3-parity

Conversation

@PetromirDev

Copy link
Copy Markdown
Member

Ambire's app moved to viem 2.56.3 (AmbireTech/ambire-app#8120), so this releases 1.0.1 pinned to it. Checking every viem change on the paths this package mirrors found nothing that needs new Rust, but it did find three older cases where the native path returns a value viem would not (since v1.0.0). The app never asks viem about those calls, so mobile can end up disagreeing with the extension.

How to reproduce

Address with a wrong checksum:

  1. Encode transfer(address,uint256) with the recipient 0xD8DA6BF26964AF9D7EED9E03E53415D37AA96045, or with a checksummed address that has one letter's case flipped.

Before, the native path built the calldata. Now it hands the call to viem, which throws InvalidAddressError as it always did, so a mistyped address is caught on mobile too.

Small integer past JavaScript's safe range:

  1. Decode a uint8 result, or any type of 48 bits or fewer, whose word holds 2^53 or more, for example from a broken or malicious RPC.

Before, the native path returned a rounded number. Now viem gets the call and throws IntegerOutOfRangeError.

String starting with a byte-order mark:

  1. Decode a token whose name() returns the bytes EF BB BF followed by USDC.

Before, mobile showed the name with an invisible character in front while the extension showed USDC. Now both show USDC.

What we did

Encoding an address now goes through parse_viem_strict_address, which holds a mixed-case address to its EIP-55 checksum the way viem's strict isAddress does. checksum_address keeps the lenient parse, matching viem's checksumAddress and getAddress.

int_to_json refused values past i64 but returned anything below that, so values between 2^53 and 2^63 came back rounded. It now refuses anything outside JS_MAX_SAFE_INTEGER on either side.

Decoded strings drop one leading BYTE_ORDER_MARK, as viem's TextDecoder does.

Also: moved the viem peer dependency to 2.56.3, added tests that pin its two behaviour changes on these paths (a string keeps its leading NUL bytes, and zero-width types such as uint256[0] still go to viem), and bumped the version to 1.0.1.

@PetromirDev PetromirDev self-assigned this Oct 6, 2026

@superKalo superKalo left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me 👍

@PetromirDev
PetromirDev marked this pull request as ready for review October 6, 2026 12:52
@PetromirDev
PetromirDev merged commit da218b7 into main Oct 6, 2026
3 checks passed
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.

2 participants