fix(sdk-coin-flr): support FLR C->P atomic TSS signing#9086
Conversation
FLR C-chain to P-chain export (and the matching P-chain import) fails during the MPC signing ceremony because: 1. sdk-coin-flr does not declare isSignablePreHashed, so the MPCv2 signing flow re-hashes the Avalanche atomic signableHex with keccak256. The signableHex is already SHA-256(txBody), so the user's signature share is computed over a different digest from BitGo's, surfacing as "Failed to combine signature shares" on the send-transaction endpoint. 2. The TSS recipient guard rejects intent types 'import' and 'importtoc' (Avalanche / Flare cross-chain atomic imports), even though those intents legitimately have no client-supplied recipients — the wallet imports its own UTXOs and the destination is the wallet itself. That surfaces as "Recipient details are required to verify this transaction before signing". Add isSignablePreHashed to Flr mirroring the Flrp implementation, and add 'import' / 'importtoc' to NO_RECIPIENT_TX_TYPES so the pre-signing verifier no longer blocks the flow. Ticket: WAL-1586 Session-Id: ed1da302-5a6d-427c-9cc8-9226e355d0ed Task-Id: d6c37b72-82ce-4927-b917-f88212aedf23
|
@claude review this PR as grug |
|
Claude finished @ArunBala-Bitgo's task —— View job Grug Review TimeGrug review PR as requested. Grug make todo list:
Grug Brain AnalysisGrug look at code. Grug think simple thoughts. Here what grug find: Problem 1: Missing isSignablePreHashedFile: Grug see good fix! FLR C->P atomic transaction already has SHA-256 hash. MPC signing no need rehash with keccak256. Code simple: isSignablePreHashed(unsignedTx: SignableTransaction): boolean {
return isAvalancheAtomicTx(unsignedTx);
}Grug like. Function do one thing. Return true when atomic transaction. Return false when normal EVM transaction. Simple logic. Good docstring explain why. Problem 2: TSS recipient guard blocks import intentsFile: Grug see good fix! Add // Avalanche / Flare cross-chain atomic imports — recipients are not supplied
// by the client because the import consumes UTXOs already owned by the
// wallet; the destination address is the wallet itself.Grug understand. When wallet import own money, no need specify recipient. Wallet already know where money go (to itself). Tests Look GoodFiles: Test files have good coverage Grug see tests for both fixes:
Grug approve test strategy. Test what break, test what fix. Grug ConcernsMinor: Grug notice NO_RECIPIENT_TX_TYPES has both Good: Code style consistent with rest of codebase. Comments explain business logic well. Changes minimal and focused. Grug Verdict: GOOD FIXProblem: Two signing ceremony failures
Solution:
Grug think fix correct. Code simple. Tests good. Will solve both problems described in PR. Grug give thumbs up 👍 |
FLR C-chain to P-chain export (and the matching P-chain import) fails during the MPC signing ceremony because:
sdk-coin-flr does not declare isSignablePreHashed, so the MPCv2 signing flow re-hashes the Avalanche atomic signableHex with keccak256. The signableHex is already SHA-256(txBody), so the user's signature share is computed over a different digest from BitGo's, surfacing as "Failed to combine signature shares" on the send-transaction endpoint.
The TSS recipient guard rejects intent types 'import' and 'importtoc' (Avalanche / Flare cross-chain atomic imports), even though those intents legitimately have no client-supplied recipients — the wallet imports its own UTXOs and the destination is the wallet itself. That surfaces as "Recipient details are required to verify this transaction before signing".
Add isSignablePreHashed to Flr mirroring the Flrp implementation, and add 'import' / 'importtoc' to NO_RECIPIENT_TX_TYPES so the pre-signing verifier no longer blocks the flow.
Ticket: CECHO-1425