Skip to content

SDK drift: Escrow.approveTx amountWei is typed bigint in TypeScript but int in Python #1025

Open

Description

@realfishsam

Drift

The amountWei / amount_wei parameter of the escrow approval method uses incompatible numeric types: TypeScript uses JavaScript's native bigint while Python uses int. Although both are arbitrary-precision integers semantically, the TypeScript side also serializes the value as a string (amountWei.toString()) before sending to the server, while Python sends it as a JSON number. This creates a wire-format mismatch.

TypeScript SDK

sdks/typescript/pmxt/escrow.ts:27

async approveTx(token: string, amountWei?: bigint): Promise<unknown>

The value is serialized at line 34 as:

amount_wei: amountWei === undefined ? null : amountWei.toString(),

Wire format: string (e.g. "1000000000000000000").

Python SDK

sdks/python/pmxt/escrow.py:46,114

def _amount_wei(value: int | None) -> int | None: ...

def approve_tx(self, token: str, amount_wei: int | None = None) -> dict[str, Any]:

Wire format: JSON number (e.g. 1000000000000000000).

Expected

Both SDKs should accept the same input type and produce the same wire format. Large Wei values (e.g. 2^96 - 1 for unlimited approval) exceed JavaScript's safe integer range, so string serialization is correct. Python should also serialize amount_wei as a string, or the server must be documented to accept both.

Impact

The server receives amount_wei as a string from TypeScript callers and as a JSON number from Python callers. If the server strictly validates the type, one of the two SDKs will fail. For large ERC-20 unlimited approvals, Python's integer JSON encoding may overflow the server's JSON parser if it uses a 64-bit integer type.

Activity

  1. realfishsam commented on Jul 3, 2026

    @realfishsam
    ContributorAuthor

    Additional context from duplicate #1049: adds the symmetric failure-mode framing — if the server expects a JSON number, TypeScript callers cause a type error/silent misparse; if the server expects a JSON string, Python callers may cause a parse error. Explicit bidirectional risk analysis for the amountWei wire-format mismatch on approve_tx/approveTx.


    Generated by Claude Code

  2. realfishsam commented on Jul 18, 2026

    @realfishsam
    ContributorAuthor

    Additional context from duplicate #1705: TypeScript's wire-serialization helper is normalizeAmountWei (sdks/typescript/pmxt/escrow.ts:51-62, used in the approveTx body at line 130), which explicitly converts bigint to a decimal string via .toString(). Python's _amount_wei (sdks/python/pmxt/escrow.py:46-56, used in approve_tx's body at line 121) returns the raw int unchanged, so it serializes as a native JSON number via json.dumps. Since amount_wei for ERC-20 "unlimited" approvals is frequently near uint256 max, sending it as a bare JSON number risks precision loss/misinterpretation by any downstream JSON consumer that treats numbers as IEEE-754 doubles (e.g. a JS-based service) — exactly the failure mode TypeScript's pre-stringification is designed to avoid.


    Generated by Claude Code

  3. realfishsam commented on Sep 4, 2026

    @realfishsam
    ContributorAuthor

    Additional context from duplicate #1923: confirms the same wire-format mismatch with precise code locations — TypeScript's sdks/typescript/pmxt/escrow.ts:51-62 (normalizeAmountWei) always serializes amount_wei as a string via .toString(), while Python's sdks/python/pmxt/escrow.py:46-56 (_amount_wei) passes the raw int through unchanged, producing a JSON number on the wire. Same underlying fix as tracked here and in the linked PR #1045 (serialize Python's amount_wei as a string to match TypeScript).


    Generated by Claude Code

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions