Drift
Escrow.depositTx/deposit_tx and Escrow.withdrawTx/withdraw_tx are meant to accept the same set of amount representations (both route through the same normalizeUsdcAmount helper in TypeScript). In TypeScript, both entry points accept number | string | bigint. In Python, deposit_tx accepts float | Decimal, but withdraw_tx only accepts float — it is missing Decimal entirely, and neither method accepts a str/int-like precision-safe type. This means Python's own two escrow-amount methods have inconsistent type contracts with each other, and withdraw_tx specifically is the narrowest of all four (TS deposit, TS withdraw, Python deposit, Python withdraw).
TypeScript SDK
sdks/typescript/pmxt/escrow.ts:84
function normalizeUsdcAmount(value: number | string | bigint, field: string = "amount"): number | string {
Used by both:
sdks/typescript/pmxt/escrow.ts:139 — async depositTx(amount: number | string | bigint): Promise<unknown>
sdks/typescript/pmxt/escrow.ts:158 — async withdrawTx(action: "request" | "claim" | "cancel", amount?: number | string | bigint): Promise<unknown>
Both depositTx and withdrawTx accept the identical number | string | bigint union.
Python SDK
sdks/python/pmxt/escrow.py:125
def deposit_tx(self, amount: float | Decimal) -> dict[str, Any]:
sdks/python/pmxt/escrow.py:134-137
def withdraw_tx(
self,
action: str,
amount: float | None = None,
) -> dict[str, Any]:
withdraw_tx's amount parameter is typed float | None only — no Decimal, no str, no int. This is narrower than deposit_tx (which at least accepts Decimal), and narrower still than TypeScript's withdrawTx.
Expected
withdraw_tx's accepted amount type should match deposit_tx's (float | Decimal) at minimum, for internal Python consistency. Beyond that, both Python methods should ideally accept the same precision-safe representations TypeScript's normalizeUsdcAmount supports (string for exact-precision decimal input), matching TypeScript's depositTx/withdrawTx contract.
Impact
A Python caller who successfully passes a Decimal to deposit_tx (to avoid float precision loss) will hit a type-contract violation if they try to do the same for withdraw_tx — the declared type doesn't allow it, and depending on how the value is used downstream, this can silently reintroduce the float-precision-loss problem for withdrawals that Decimal was meant to avoid for deposits. TypeScript callers can safely pass a bigint/decimal string to either depositTx or withdrawTx, but Python callers have no consistent precision-safe path for withdrawals.
Found by automated SDK cross-language drift audit
Drift
Escrow.depositTx/deposit_txandEscrow.withdrawTx/withdraw_txare meant to accept the same set of amount representations (both route through the samenormalizeUsdcAmounthelper in TypeScript). In TypeScript, both entry points acceptnumber | string | bigint. In Python,deposit_txacceptsfloat | Decimal, butwithdraw_txonly acceptsfloat— it is missingDecimalentirely, and neither method accepts astr/int-like precision-safe type. This means Python's own two escrow-amount methods have inconsistent type contracts with each other, andwithdraw_txspecifically is the narrowest of all four (TS deposit, TS withdraw, Python deposit, Python withdraw).TypeScript SDK
sdks/typescript/pmxt/escrow.ts:84Used by both:
sdks/typescript/pmxt/escrow.ts:139—async depositTx(amount: number | string | bigint): Promise<unknown>sdks/typescript/pmxt/escrow.ts:158—async withdrawTx(action: "request" | "claim" | "cancel", amount?: number | string | bigint): Promise<unknown>Both
depositTxandwithdrawTxaccept the identicalnumber | string | bigintunion.Python SDK
sdks/python/pmxt/escrow.py:125sdks/python/pmxt/escrow.py:134-137withdraw_tx'samountparameter is typedfloat | Noneonly — noDecimal, nostr, noint. This is narrower thandeposit_tx(which at least acceptsDecimal), and narrower still than TypeScript'swithdrawTx.Expected
withdraw_tx's accepted amount type should matchdeposit_tx's (float | Decimal) at minimum, for internal Python consistency. Beyond that, both Python methods should ideally accept the same precision-safe representations TypeScript'snormalizeUsdcAmountsupports (stringfor exact-precision decimal input), matching TypeScript'sdepositTx/withdrawTxcontract.Impact
A Python caller who successfully passes a
Decimaltodeposit_tx(to avoid float precision loss) will hit a type-contract violation if they try to do the same forwithdraw_tx— the declared type doesn't allow it, and depending on how the value is used downstream, this can silently reintroduce the float-precision-loss problem for withdrawals thatDecimalwas meant to avoid for deposits. TypeScript callers can safely pass abigint/decimalstringto eitherdepositTxorwithdrawTx, but Python callers have no consistent precision-safe path for withdrawals.Found by automated SDK cross-language drift audit