Skip to content

fix(sdk-coin-flr): add getSignablePayload and addSignatureToTransaction for atomic txs#9358

Draft
bitgo-ai-agent-dev[bot] wants to merge 1 commit into
masterfrom
fix/CECHO-1784-flr-atomic-tss-signing
Draft

fix(sdk-coin-flr): add getSignablePayload and addSignatureToTransaction for atomic txs#9358
bitgo-ai-agent-dev[bot] wants to merge 1 commit into
masterfrom
fix/CECHO-1784-flr-atomic-tss-signing

Conversation

@bitgo-ai-agent-dev

Copy link
Copy Markdown

What

  • Added getSignablePayload override to Flr that routes atomic cross-chain transactions (codec prefix 0x0000) to the FLRP atomic builder, which correctly computes SHA-256(txBody) as the signing payload
  • Added addSignatureToTransaction method to Flr that injects a TSS-produced signature into an unsigned atomic ExportInC transaction to produce the final broadcastable hex
  • Added 3 unit tests verifying the new methods work correctly and produce identical results to the FLRP builder reference implementation

Why

When a FLR TSS wallet performs a C→P cross-chain withdrawal (FLR to FLRP), the ExportInC atomic transaction has codec prefix 0x0000. The FLR coin inherited getSignablePayload from AbstractEthLikeCoin, which uses the EVM transaction builder — but the EVM builder cannot parse Avalanche/Flare atomic transaction format.

Without a proper getSignablePayload override, the server-side TSS signature injection step fails for FLR→FLRP withdrawals. When signature injection fails, the server may retry the withdrawal by building a new ExportInC transaction using the same C-chain address nonce as the already-pending transaction. The Flare node then rejects the duplicate as "transaction attempted to double spend."

Adding getSignablePayload and addSignatureToTransaction (mirroring the existing FLRP coin implementations, but using getAtomicBuilder()) gives the server the correct codec path for assembling signed atomic transactions, preventing the retry loop that causes the double spend.

Test plan

  • getSignablePayload returns a 32-byte SHA-256 hash for atomic tx hex
  • getSignablePayload returns the same bytes as the FLRP builder's signablePayload
  • addSignatureToTransaction produces identical signed hex to the FLRP builder's sign() method
  • All 64 existing FLR unit tests continue to pass

Ticket: CECHO-1784

…ddSignatureToTransaction

The FLR coin was missing getSignablePayload and addSignatureToTransaction
overrides for atomic cross-chain transactions (C-chain to P-chain export,
codec prefix 0x0000). The inherited EVM implementation from
AbstractEthLikeCoin uses the EVM transaction builder which cannot parse
Avalanche/Flare PVM/EVM atomic format, causing the TSS server-side
signature injection step to fail for FLR→FLRP withdrawals.

When signature injection fails, the server may retry building a new
ExportInC with the same nonce as the already-pending transaction,
resulting in "transaction attempted to double spend" from the blockchain.

Fix: override getSignablePayload to route atomic txs (codec prefix 0000)
to the FLRP atomic builder (getAtomicBuilder), which correctly parses the
transaction and computes SHA-256(txBody) as the signable payload. Add
addSignatureToTransaction to inject the TSS-produced signature into the
unsigned atomic transaction to produce the final broadcastable hex.

Both methods mirror the existing FLRP coin implementations but use
getAtomicBuilder() (which wraps the FLRP builder) instead of the FLRP-
internal getBuilder().

Ticket: CECHO-1784
Session-Id: e17e771f-ba61-468a-a77e-c2c97ade3e23
Task-Id: 81aaba89-3f88-4d30-a6f6-81d77b7908d9
@linear-code

linear-code Bot commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

CECHO-1784

@ralph-bitgo
ralph-bitgo Bot force-pushed the fix/CECHO-1784-flr-atomic-tss-signing branch from 2e4fca5 to fc4045f Compare July 27, 2026 09:30
@bitgo-ai-agent-dev
bitgo-ai-agent-dev Bot force-pushed the fix/CECHO-1784-flr-atomic-tss-signing branch from fc4045f to bf8c700 Compare July 27, 2026 09:30
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