From d45d3dcd38b246248b89486eb446b114f3624829 Mon Sep 17 00:00:00 2001 From: Luis Covarrubias Date: Thu, 19 Mar 2026 17:11:19 -0700 Subject: [PATCH] feat: add compact call_data length prefix to unsigned signing payload Without the prefix, wasm-dot signing payloads can't be decoded by polkadot-js/txwrapper, which expects compact(call_data_len) before the call data. This makes wasm-dot a drop-in replacement for the legacy builder in any code path that uses TransactionBuilderFactory.from(). signablePayload() (used for signature generation) is unchanged. BTC-3198 --- packages/wasm-dot/src/transaction.rs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/packages/wasm-dot/src/transaction.rs b/packages/wasm-dot/src/transaction.rs index fb18404..7a43a23 100644 --- a/packages/wasm-dot/src/transaction.rs +++ b/packages/wasm-dot/src/transaction.rs @@ -220,9 +220,15 @@ impl Transaction { // Fall back to manual serialization if no context self.to_bytes_manual() } else { - // Unsigned: return the signing payload (call_data + extensions + additional_signed). - // This matches legacy toBroadcastFormat which returns construct.signingPayload(). - self.signable_payload() + // Unsigned: return the signing payload with a compact call_data length prefix. + // Format: compact(call_data_len) | call_data | extensions | additional_signed + // This matches legacy toBroadcastFormat (construct.signingPayload from txwrapper) + // and is decodable by both wasm-dot and polkadot-js/txwrapper. + use parity_scale_codec::{Compact, Encode}; + let payload = self.signable_payload()?; + let mut result = Compact(self.call_data.len() as u32).encode(); + result.extend_from_slice(&payload); + Ok(result) } }