2fa mobile cosigner - #10979
Draft
ecdsa wants to merge 3 commits into
Draft
2fa mobile cosigner#10979ecdsa wants to merge 3 commits into
ecdsa wants to merge 3 commits into
Conversation
SomberNight
reviewed
Sep 17, 2026
Comment on lines
+131
to
+143
| def add_cosigner(config: 'SimpleConfig', *, xprv2: str, xpub1: str, xpub3: str, password: str) -> None: | ||
| """Stores the keys of a 2fa wallet.""" | ||
| assert password, 'the cosigner key must be encrypted' | ||
| xpub2 = keystore.from_xprv(xprv2).get_master_public_key() | ||
| cosigner = { | ||
| 'xpub1': xpub1, | ||
| 'xpub2': xpub2, | ||
| 'xpub3': xpub3, | ||
| 'xprv2': pw_encode_with_version_and_mac(xprv2.encode('utf8'), password), | ||
| } | ||
| cosigners = [c for c in get_cosigners(config) if c['xpub2'] != xpub2] | ||
| cosigners.append(cosigner) | ||
| config.PLUGIN_TRUSTEDCOIN_COSIGNERS = cosigners |
Member
There was a problem hiding this comment.
This is really blurring the boundaries of wallet vs config. It is abusing the config IMO.
Also, what if someone has multiple 2fa wallets?
Member
Author
There was a problem hiding this comment.
This is really blurring the boundaries of wallet vs config. It is abusing the config IMO.
could be moved to a separate file. the point is that is should not be a wallet.
Also, what if someone has multiple 2fa wallets?
that's why cosigners is a list.
ecdsa
force-pushed
the
2fa_mobile_cosigner
branch
3 times, most recently
from
September 18, 2026 11:07
8aada38 to
54fbfce
Compare
TrustedCoin is going to stop their cosigning service. To keep things running, we shall use the Electrum mobile app as cosigner. - Wallets keep the '2fa' type, because two xprvs are derived from a seed. - desktop wizard (restore only): show xprv2, xpub1, xpub3 in a '2fa_cosigner:' QR code. - mobile wizard: scan that QR code (xpub1, xprv2, xpub3). - desktop shows the PSBT as a QR code after signing; that dialog closes once the wallet sees the transaction. Existing 2fa wallets can set up the mobile cosigner from the status bar icon; missing x3 is derived. - remove server client, TOS, OTP, billing and related hooks (tc_sign_wrapper, abort_send, get_tx_extra_fee, get_action/WalletUnfinished, is_sweep). what is missing: - QR codes are size limited. We should implement animated QR or use nostr - not sure if we want a full wallet on the mobile app. We could as well store the (encrypted) xprv in the config file.
The mobile app no longer creates a wallet when it is set up as cosigner: the keys of the wallets it cosigns for are stored in its config file, so the user does not have to open a wallet in order to sign. - the keys live in the config file, see electrum/cosigner.py: a cosigner is indexed by the fingerprint its key uses in transactions, and everything else is encrypted with the password of the device, so that reading the config file does not tell which wallets it cosigns for. The daemon re-encrypts them when that password changes, as this must not depend on a plugin being loaded. Setup fails without a unified password; if there is no wallet yet, the password chosen during setup becomes the password of the app. - transactions are prefixed with '2fa:', so that the app looks up the keys in its config file instead of the current wallet. It rebuilds the wallet scripts from the 3 xpubs, and displays outputs, amount and fee before broadcasting. The derivations found in the transaction are not trusted: an output counts as change only if it pays to the script we recompute for it. - the wizard has a 'Scan QR code' button when the device has no wallet.
- the signature of a non-segwit input does not commit to its amount, so a malicious transaction could make the cosigner burn coins as miner fees. QR codes do not carry previous transactions, so the mobile app fetches them from the network, and it refuses to sign a non-segwit input without one. Whether an input is segwit is decided by the script we recompute from the xpubs: txin.is_segwit() believes the witness field of the transaction. - refuse inputs that already carry a witness or a scriptSig. Those fields decide how an input is signed, hence which sighash our key commits to. - refuse non-default sighash flags: with SIGHASH_NONE or ANYONECANPAY our signature would not commit to the outputs, which could then be changed. - refuse to sign if the fee is unknown. The previous transactions are now fetched with ignore_network_issues=False, so that a transaction is never displayed with amounts we could not verify.
ecdsa
force-pushed
the
2fa_mobile_cosigner
branch
from
September 18, 2026 16:03
54fbfce to
bc284d7
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.