Feat/connect compose psbt tx - #26056
Conversation
3244e95 to
6fa44ba
Compare
93d46b7 to
b8e8a84
Compare
There was a problem hiding this comment.
Pull request overview
Adds PSBT (BIP-174 v0) support to the Connect transaction composition flow by introducing a minimal PSBT parser in utxo-lib and a new psbtTransactionData parameter for composeTransaction precompose requests, enabling mapping PSBT inputs/outputs to Trezor protobuf types (including OP_RETURN).
Changes:
- Implement minimal PSBT parser/serializer (
Psbt) in@trezor/utxo-libwith fixtures + unit tests. - Extend
composeTransactionAPI/types/docs with optionalpsbtTransactionDataand add PSBT parsing path in Connect. - Refactor output-script parsing into a shared helper and add E2E fixtures covering PSBT precompose.
Reviewed changes
Copilot reviewed 12 out of 12 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/utxo-lib/src/psbt.ts | Adds minimal PSBTv0 parser/serializer and exposes unsigned tx + maps. |
| packages/utxo-lib/src/index.ts | Re-exports Psbt from the library entrypoint. |
| packages/utxo-lib/tests/fixtures/psbt.ts | Adds PSBT fixtures (BIP174 + derived vectors). |
| packages/utxo-lib/tests/psbt.test.ts | Adds unit tests for parsing/round-tripping/strictness and mutation serialization. |
| packages/connect/src/api/bitcoin/parsePSBTx.ts | Adds PSBT-to-PrecomposeResultFinal mapping (inputs/outputs/fee computation). |
| packages/connect/src/api/composeTransaction.ts | Adds psbtTransactionData param and precompose fast-path using PSBT parsing. |
| packages/connect/src/api/bitcoin/outputs.ts | Exposes shared parseOutputScript helper (address vs OP_RETURN). |
| packages/connect/src/api/bitcoin/refTx.ts | Switches to shared parseOutputScript helper and adjusts OP_RETURN handling. |
| packages/connect/e2e/fixtures/composeTransaction.ts | Adds PSBT precompose fixture cases (mainnet P2PKH + testnet P2WPKH/OP_RETURN). |
| packages/connect-explorer/src/pages/methods/bitcoin/composeTransaction.mdx | Documents psbtTransactionData in Explorer schema/param descriptions. |
| packages/connect-common/src/types/api/composeTransaction.ts | Extends public API types with psbtTransactionData. |
| packages/connect-common/src/types/api/tests/bitcoin.ts | Updates type-level API tests to include psbtTransactionData. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
7a3b526 to
daa4fa1
Compare
daa4fa1 to
6b9c153
Compare
6b9c153 to
073c198
Compare
073c198 to
5edf5cf
Compare
|
✅ Previously successful run of [Test] suite-native Android E2E workflow has been found. |
|
|
||
| export declare function composePsbt( | ||
| params: Params<ComposePsbtParams>, | ||
| ): Response<PrecomposeResultFinal>; |
There was a problem hiding this comment.
new api is introduced here so it is natural to ask if we really need all the fields in its return type?
these are non negotiable - type, inputs, outputs. But the question is do we also need these? fee totalSpent feePerByte bytes, outputsPermutation, and max.
There was a problem hiding this comment.
yes we do need them, similar to composeTransaction this method is meant to return data for suite send form and later for TrezorConnect.signTrancation
| const coinInfo = getBitcoinNetwork(payload.coin); | ||
| if (!coinInfo) { | ||
| throw ERRORS.TypedError('Method_UnknownCoin'); | ||
| } |
|
|
||
| export type ComposePsbtParams = { | ||
| account: { | ||
| path: string; |
| } | ||
| } | ||
|
|
||
| const fee = sumOfInputs - sumOfOutputs; |
There was a problem hiding this comment.
little hardening suggested here #32184
not very important.
| bytes, | ||
| inputs, | ||
| outputs, | ||
| outputsPermutation: [], |
There was a problem hiding this comment.
is this really okey to ignore outuptsPermutation? maybe nobody uses it but if the return type is PrecomposeResultFinal it could be confusing that it does not contain same data
| } | ||
| outputs.push({ | ||
| script_type: 'PAYTOOPRETURN', | ||
| amount: '0', |
There was a problem hiding this comment.
I understand that op_return outputs are basically unspendable but is it necessary to set their amout to 0? doesn't it have some effect on fee calculation? 🤔
There was a problem hiding this comment.
no it doesnt have effect on fe calculation, but this is the shape of PROTO.TxOutputType used in the next step in TrezorConnect.signTransaction
| } | ||
|
|
||
| const fee = sumOfInputs - sumOfOutputs; | ||
| const bytes = psbt.unsignedTx.virtualSize(); |
There was a problem hiding this comment.
my agent claims that using unsignedTx for fee calculation inflates fee
There was a problem hiding this comment.
good catch, now its calculated using getTransactionVbytes (TxWeightCalculator)
| const bytes = psbt.unsignedTx.virtualSize(); | ||
| const feePerByte = Number(fee) / bytes; | ||
|
|
||
| return { |
There was a problem hiding this comment.
what about version and lock_time? if they are provided in psbt data, they should be decoded and passed to the subsequent singTransaction call. If they are not, we are safe, but in that case I would at least throw some "ntot supported error" from psbt parsing
There was a problem hiding this comment.
cdf40ff added to ComposePsbtResult (extended PrecomposeResultFinal)
| if (unsignedTxEntries.length !== 1 || !unsignedTxEntries[0]) { | ||
| throw new Error('PSBT must contain exactly one unsigned transaction.'); | ||
| } |
There was a problem hiding this comment.
yes, but are we checking that it is really unsigned? according to the specs and my agent it should be unsigned but the Transaction.fromBuffer is just a general parser of btc transaction which does not enforce this.
Description
PSBTminimal parsercomposePsbtmethod.When requested parse psbt data and map inputs/outputs to trezor protobuf format, find tx inputs in known account utxos set, find tx outputs in known account addresses set.
Resolve
#22565
Screenshots:
🔍 Currents Test Results
🔍 Suite desktop test results: View in Currents
🔍 Suite web test results: View in Currents
🔍 Suite native android test results: View in Currents
🔒 Quarantined E2E Tests
Trezor Suite (web) — 5 test(s)
Updated: 2026-09-08T12:09:11.092Z • 5 test(s) total
Trezor Suite (desktop) — 4 test(s)
Updated: 2026-09-08T12:05:53.450Z • 4 test(s) total
🤖 LLM Test Recommendations
Summary: The changes concentrate on Bitcoin/PSBT transaction handling in @trezor/connect and @trezor/utxo-lib, including composePsbt, output composition, reference transactions, and PSBT parsing. The highest risk is regressions in Bitcoin transaction signing and sending. Rather than running the 134 tests that transitively import the broad utility files, the recommended strategy targets tests that actually construct, sign, or broadcast Bitcoin (and Bitcoin-like) transactions, plus the direct Connect signTransaction test. Type definitions, test fixtures, the CI matrix generator, and the composePsbt method itself are not exercised by the available suite/e2e candidates and should be covered by connect-level unit/e2e tests instead.
Changed files (17)
packages/connect-common/src/callableMethods.tspackages/connect-common/src/types/api/bitcoin.type-test.tspackages/connect-common/src/types/api/bitcoin/composePsbt.tspackages/connect-common/src/types/api/bitcoin/index.tspackages/connect-common/src/types/index.tspackages/connect/e2e/__fixtures__/composePsbt.tspackages/connect/e2e/__fixtures__/index.tspackages/connect/src/api/bitcoin/outputs.tspackages/connect/src/api/bitcoin/parsePsbt.tspackages/connect/src/api/bitcoin/refTx.tspackages/connect/src/api/composePsbt.tspackages/connect/src/api/index.tspackages/utxo-lib/src/__fixtures__/psbt.tspackages/utxo-lib/src/index.tspackages/utxo-lib/src/psbt.test.tspackages/utxo-lib/src/psbt.tsscripts/ci/connect-test-matrix-generator.jsRecommended tests (8)
🔴 High priority (4)
suite/e2e/tests/trezor-connect/signTransaction.test.ts— Directly exercises TrezorConnect.signTransaction for a BTC transaction, which shares the same Bitcoin output, reference transaction, and PSBT parsing/composition code paths modified in connect and utxo-lib. A regression here would be immediately visible in Connect-based signing flows.suite/e2e/tests/wallet/pending-transactions.test.ts— Sends multiple Bitcoin regtest transactions with multiple outputs and verifies pending/confirmed state transitions. This directly exercises Bitcoin transaction composition, output handling, and broadcast paths affected by outputs.ts, refTx.ts, and psbt.ts changes.suite/e2e/tests/wallet/send-doge.test.ts— Sends Dogecoin and validates device prompt amounts, total, fee, and address formatting. Dogecoin uses the Bitcoin-like output/refTx/PSBT infrastructure, so this catches regressions in UTXO transaction construction.suite/e2e/tests/wallet/send-form-regtest.test.ts— Tests Bitcoin send form with multiple outputs, OP_RETURN data, locktime by block height, and satoshi unit switching. These features directly depend on correct output composition and transaction serialization logic touched by the changes.🟡 Medium priority (4)
suite/e2e/tests/trading/sell-bitcoin.test.ts— Sells Bitcoin through the trading flow, requiring a real BTC send transaction to a provider address with device signing. This exercises the end-to-end output construction and signing path in a different user flow than wallet sends.suite/e2e/tests/trading/swap-fees-bitcoin.test.ts— Performs a BTC swap with custom fee settings and verifies fee/total details on both the app prompt and the hardware device. Custom fee handling reaches deep into Bitcoin transaction composition and fee calculation logic.suite/e2e/tests/wallet/import-btc-csv.test.ts— Imports a CSV file to populate multiple send outputs with addresses, amounts, and metadata labels. This exercises output creation and label association in the Bitcoin send form.suite/e2e/tests/wallet/send-form-ltc.test.ts— Sends Litecoin using an output originating from a MimbleWimble peg-out transaction. This tests handling of non-standard Bitcoin-like outputs and custom blockbook backend integration.packages/connect-common/src/types/api/bitcoin.type-test.tspackages/connect-common/src/types/api/bitcoin/composePsbt.tspackages/connect-common/src/types/api/bitcoin/index.tspackages/connect-common/src/types/index.tspackages/connect/e2e/__fixtures__/composePsbt.tspackages/connect/e2e/__fixtures__/index.tspackages/connect/src/api/bitcoin/parsePsbt.tspackages/connect/src/api/composePsbt.tspackages/utxo-lib/src/__fixtures__/psbt.tspackages/utxo-lib/src/psbt.test.tsscripts/ci/connect-test-matrix-generator.jsUpdated: 2026-09-08T12:05:55.079Z
🌐 Preview deployments
🌐 Suite Web preview: https://dev.suite.sldev.cz/suite-web/feat/connect-psbt/web/