BIP128: Timelock-Recovery Storage Format #2068
pull oren-z0 wants to merge 17 commits into bitcoin:master from oren-z0:new-bip-timelock-recovery-storage-format changing 2 files +273 −0-
oren-z0 commented at 8:51 am on December 29, 2025: noneThis simple BIP explains what Timelock-Recovery plans are, and how they to store them In a standard JSON format, that services could parse and then monitor/execute.
-
oren-z0 force-pushed on Dec 29, 2025
-
oren-z0 force-pushed on Dec 29, 2025
-
oren-z0 force-pushed on Dec 29, 2025
-
bitcoin deleted a comment on Dec 30, 2025
-
oren-z0 force-pushed on Jan 2, 2026
-
murchandamus renamed this:
New BIP: Timelock Recovery storage format
BIP Draft: Timelock-Recovery Storage Format
on Jan 2, 2026 -
murchandamus added the label New BIP on Jan 2, 2026
-
oren-z0 force-pushed on Jan 2, 2026
-
oren-z0 force-pushed on Jan 2, 2026
-
oren-z0 force-pushed on Jan 2, 2026
-
oren-z0 force-pushed on Jan 2, 2026
-
oren-z0 force-pushed on Jan 2, 2026
-
murchandamus requested review from murchandamus on Jan 2, 2026
-
oren-z0 force-pushed on Jan 3, 2026
-
oren-z0 force-pushed on Jan 3, 2026
-
in bip-timelock-recovery-storage-format.mediawiki:7 in d3a4845dbb
0@@ -0,0 +1,246 @@ 1+<pre> 2+ BIP: ? 3+ Layer: Applications 4+ Title: Timelock-Recovery storage format 5+ Author: Oren <orenz0@protonmail.com> 6+ Status: Draft 7+ Type: Process
murchandamus commented at 10:13 pm on January 16, 2026:This should be a Specification BIP: Process BIPs are BIPs about BIPs or other network processes.
0 Type: Specificationin bip-timelock-recovery-storage-format.mediawiki:5 in d3a4845dbb outdated
0@@ -0,0 +1,246 @@ 1+<pre> 2+ BIP: ? 3+ Layer: Applications 4+ Title: Timelock-Recovery storage format 5+ Author: Oren <orenz0@protonmail.com>
murchandamus commented at 2:05 am on January 27, 2026:0 Authors: Oren <orenz0@protonmail.com>in bip-timelock-recovery-storage-format.mediawiki:60 in d3a4845dbb outdated
55+ 56+However, script-based wallets have some disadvantages over a sequence of 57+pre-signed transactions: 58+ 59+* Script-based wallets are harder to implement correctly by hardware wallets, and harder to backup properly (i.e. users may forget to backup wallet-descriptors even for basic multisig wallets). 60+* As of the time of writing, scripts can limit when secondary-keys can be used, but not how they can be used: if the user doesn't touch the wallets' UTXOs for long-enough time, the secondary key will eventually become useable and could move the funds anywhere. This is true whether we measure the time in absolute terms (OP_CHECKLOCKTIMEVERIFY) or relative terms compared to when the wallets' UTXOs were created (OP_CHECKSEQUENCEVERIFY). This means that even in the happy-flow scenario of an untouched wallet, where no recovery is needed, the user must periodically "renew" the recovery-mechanism by spending the UTXO to a new wallet/address. This may be inconvenient in ultra-cold-storage scenarios (i.e. multisig with main keys hidden in different geographic locations). New opcode suggestions, such as OP_CHECKTEMPLATEVERIFY ([[bip-0119.mediawiki|BIP-119]]) and OP_VAULT ([[bip-0345.mediawiki|BIP-345]]), discuss possible recovery-mechanisms in which in order for a secondary key to have full control over the funds, some onchain operations must be performed, with a required time-gap between them - giving the user enough time to revoke the whole process and move the funds elsewhere (assuming they still have the main key and the recovery-mechanism was triggered unintentionally). However, these suggestions are still in the discussion phase and even if ever implemented, their adoption may be slow.
murchandamus commented at 2:11 am on January 27, 2026:OP_VAULT was withdrawn, but the author endorsed BIP 443: OP_CHECKCONTRACTVERIFY as a spiritual successor.
oren-z0 commented at 9:12 pm on January 27, 2026:Replaced with OP_CHECKCONTRACTVERIFYin bip-timelock-recovery-storage-format.mediawiki:68 in d3a4845dbb outdated
62+ 63+== Specification == 64+ 65+A ''Timelock-Recovery plan'' consists of two transactions: 66+ 67+* ''Alert Transaction'': A mostly-consolidation transaction that keeps most funds in the original wallet, except for a fee and a small fixed amount that goes to ''anchor-addresses'' - addresses which can be used to accelerate the ''Alert Transaction'' via CPFP. The majority of funds should remain on the original wallet, in a new previously-unused address which we call the ''alert-address''. We use the term ''Alert Transaction'' because it should alert the user that the recovery-plan has been triggered, giving them a limited time to prevent the majority of the funds from moving to the secondary wallets.
murchandamus commented at 2:14 am on January 27, 2026:When you write “anchor-addresses”, do you mean a BIP 433: Pay to Anchor output?
oren-z0 commented at 9:34 pm on January 27, 2026:Not necessarily. This could be any address for the purpose of CPFP acceleration. Currently I would recommend users to simply pick addresses from the secondary wallets, whose purpose is to receive the larger amount in the second Recovery Transaction. If the users/inheritors have access to the keys of the secondary wallets at the time the Alert Transaction is broadcast - they could easily apply the CPFP on the Alert Transaction. If they don’t have access to the keys of the secondary wallets (i.e. it was broadcast by accident or by a malicious actor) - what’s the point of accelerating the process?
I like the P2A concept and it could be useful here in case there are many secondary wallets (instead of wasting fees on many addresses). However P2A is currently only a draft, and its adoption might take time. I prefer not to recommend using it at the moment, since less-technical might find it hard to accelerate such transactions.
Do you want me to mention that by using the term “anchor-addresses” I do not refer specifically to BIP 433?
murchandamus commented at 9:43 pm on January 27, 2026:It would make sense to clarify that, given that the term might also make other people wonder.
oren-z0 commented at 1:23 pm on January 28, 2026:donein bip-timelock-recovery-storage-format.mediawiki:72 in d3a4845dbb outdated
67+* ''Alert Transaction'': A mostly-consolidation transaction that keeps most funds in the original wallet, except for a fee and a small fixed amount that goes to ''anchor-addresses'' - addresses which can be used to accelerate the ''Alert Transaction'' via CPFP. The majority of funds should remain on the original wallet, in a new previously-unused address which we call the ''alert-address''. We use the term ''Alert Transaction'' because it should alert the user that the recovery-plan has been triggered, giving them a limited time to prevent the majority of the funds from moving to the secondary wallets. 68+* ''Recovery Transaction'': The transaction that moves the funds from the alert-address UTXO from the ''Alert Transaction'' to one or more addresses of secondary wallets (each may receive a different amount). This transaction should have a special <code>nSequence</code> relative-locktime according to the size of cancellation-period requested by the user, following the rules of [[bip-0068.mediawiki|BIP-68]]. 69+ 70+Both transactions are expected to have an <code>nVersion</code> of at least 2, and an 71+<code>nLocktime</code> not higher than the current block height. 72+Both transactions should be non-malleable, as defined in [[bip-0062.mediawiki|BIP-62]].
murchandamus commented at 2:22 am on January 27, 2026:Since the Recovery Transaction appears to spend an output from the Alert Transaction, the Alert transaction is required to be non-malleable. Transactions with non-segwit inputs are always third-party malleable. It therefore seems clear that the Alert Transaction must only have segwit inputs. It’s not clear to me why non-malleability would be necessary for the Recovery Transaction.
Please note that BIP 62 was withdrawn in 2015 and therefore might not be the best choice to express the requirements for the transactions. Either way, it seems to me that it would be useful to be more specific here what exactly the requirements of the transactions are.
oren-z0 commented at 10:03 pm on January 27, 2026:Fixed, with a reference to BIP 140 instead of BIP 62.in bip-0128.mediawiki:117 in d3a4845dbb outdated
106+* wallet_version (mandatory): The version of the wallet that generated the plan. A string of up to 100 characters. 107+* wallet_name (mandatory): The human-readable name of the wallet app that generated the plan. A string of up to 100 characters. 108+* wallet_kind (mandatory): The internal name of the wallet app that generated the plan. A string of up to 100 characters. 109+* timelock_days (mandatory): The cancellation period in whole days. A number between 2 and 388. 110+* anchor_amount_sats (mandatory): The amount in satoshis sent to each anchor address in the <code>Alert Transaction</code>. We recommend using 600 sats, which is above the dust limit. 111+* anchor_addresses (mandatory): An array of up to 10,000 Bitcoin addresses that receive the anchor amount in the <code>Alert Transaction</code>. Each address is a string of up to 100 characters.
murchandamus commented at 2:26 am on January 27, 2026:I would recommend checking out P2A as mentioned above.
oren-z0 commented at 10:09 pm on January 27, 2026:See previous comments.in bip-timelock-recovery-storage-format.mediawiki:119 in d3a4845dbb outdated
108+* wallet_kind (mandatory): The internal name of the wallet app that generated the plan. A string of up to 100 characters. 109+* timelock_days (mandatory): The cancellation period in whole days. A number between 2 and 388. 110+* anchor_amount_sats (mandatory): The amount in satoshis sent to each anchor address in the <code>Alert Transaction</code>. We recommend using 600 sats, which is above the dust limit. 111+* anchor_addresses (mandatory): An array of up to 10,000 Bitcoin addresses that receive the anchor amount in the <code>Alert Transaction</code>. Each address is a string of up to 100 characters. 112+* alert_address (mandatory): The Bitcoin address (mainnet) that receives the majority of funds in the <code>Alert Transaction</code>. A string of up to 100 characters. 113+* alert_inputs (mandatory): An array of up to 10,000 inputs spent by the <code>Alert Transaction</code>. Each input is a string in the format "txid:vout" where txid is a 64-character lowercase hexadecimal string and vout is a decimal number of up to 6 digits.
murchandamus commented at 2:28 am on January 27, 2026:Any UTXO type will make a transaction with 10'000 inputs non-standard due to being larger than the standard transaction weight limit. Is there a specific reason why such a large limit is chosen?
oren-z0 commented at 10:18 pm on January 27, 2026:There is no specific reason. It’s just an over-estimation for server implementations which need to parse such files - if the array is longer than 10,000, reject the file immediately.
Do you have a more exact number?
murchandamus commented at 9:59 pm on January 29, 2026:Since inputs must reference the outpoint of the UTXO they’re spending, include a sequence, and provide the length of the input script, it’s impossible for inputs to take less than 41 bytes. Assuming a standard transaction weight of 400,000 weight units, a transaction cannot have more than 2439 inputs. Making a higher limit might make sense to be future-proof, if you anticipate that the standard transaction weight limit will be lifted in the future, but at least at this time, 10'000 inputs is at least 4× of what’s possible to fit into a standard transaction.
I was mostly wondering whether it is intentional that this Specification allows larger transactions than will be reliably propagated on the network.
oren-z0 commented at 12:13 pm on January 30, 2026:I will reduce the requirement to 2439, because we want to prevent users from creating recovery-plans that might not propagate. As I explain in “Monitoring Timelock-Recovery Plans”, a monitoring service that accepts such JSON file should run
testmempoolaccepton the Alert Transaction, which will fail if there are too many inputs. But yes, if there are more than 2439 inputs (which is very unlikely anyways), we want to stop the creation of the JSON file right away, even before the user tries to upload it to any service.P.S. You misspelled “400'000 weight units” 😅
in bip-0128.mediawiki:10 in d3a4845dbb outdated
0@@ -0,0 +1,246 @@ 1+<pre> 2+ BIP: ? 3+ Layer: Applications 4+ Title: Timelock-Recovery storage format 5+ Author: Oren <orenz0@protonmail.com> 6+ Status: Draft 7+ Type: Process 8+ Assigned: ? 9+ License: BSD-2-Clause
murchandamus commented at 2:33 am on January 27, 2026:Has this been submitted to the mailing list? If so, could you please add a Discussion header with the URL to the discussion?
oren-z0 commented at 10:24 pm on January 27, 2026:Yes, here: https://groups.google.com/g/bitcoindev/c/K1NpJp9_BYk Added the link to a “Discussion” header (even though I did not see a similar Discussion header in other bips).
murchandamus commented at 10:00 pm on January 29, 2026:While it’s only present on some 30ish BIPs, it’s a header that we have been pushing more for lately.in bip-timelock-recovery-storage-format.mediawiki:121 in d3a4845dbb outdated
116+* alert_fee (mandatory): The total fee paid by the <code>Alert Transaction</code> in satoshis. A non-negative integer. 117+* alert_weight (mandatory): The weight of the <code>Alert Transaction</code>. A positive integer. 118+* recovery_tx (mandatory): The raw <code>Recovery Transaction</code> in uppercase hexadecimal format. A string of up to 800,000 characters. 119+* recovery_txid (mandatory): The transaction ID of the <code>Recovery Transaction</code>. A 64-character lowercase hexadecimal string. 120+* recovery_fee (mandatory): The total fee paid by the <code>Recovery Transaction</code> in satoshis. A non-negative integer. 121+* recovery_weight (mandatory): The weight of the <code>Recovery Transaction</code>. A positive integer.
murchandamus commented at 2:35 am on January 27, 2026:Should the weight perhaps be limited to the standard transaction weight limit?
oren-z0 commented at 10:31 pm on January 27, 2026:Yes, I have added a requirement that the weights will be up to 400,000 wu. It’s important to prevent users from creating/uploading recovery-plans with transactions that won’t propagate when needed.murchandamus commented at 2:40 am on January 27, 2026: memberHi Oren, thanks for your submission. I did a first quick pass. From the formatting, this seems already a good start. I left a few comments and questions.oren-z0 force-pushed on Jan 27, 2026murchandamus added the label PR Author action required on Jan 27, 2026oren-z0 requested review from murchandamus on Jan 27, 2026new bip: timelock recovery storage format b76f390a94Comparison with Script-Based Wallets ccb0dd838ef1fe10e847Type is Specification
Co-authored-by: Mark "Murch" Erhardt <murch@murch.one>
a581d404d7Change Authors to a single Author
Co-authored-by: Mark "Murch" Erhardt <murch@murch.one>
Replace OP_VAULT mention with OP_CHECKCONTRACTVERIFY fe83fc5a16Only the Alert Transaction needs to be non-malleable f5743f58dfAdding discussion link 76bca314e24cbfb1e024limiting the transactions weight
This is important in order to prevent users from creating recovery-plans that are hard to propagate.
oren-z0 force-pushed on Jan 27, 2026Explain anchor-addresses a18dd7373bin bip-timelock-recovery-storage-format.mediawiki:82 in a18dd7373b
76@@ -77,6 +77,12 @@ making the ''Recovery Transaction'' invalid (pointing to a non-existent UTXO). 77 The <code>nLocktime</code> of both transactions should not be higher than the current 78 block height. 79 80+The ''anchor-addresses'' mentioned above, which are used for CPFP acceleration, could possibly 81+be P2A addresses (described in [[bip-0433.mediawiki|BIP-433]]), or other addresses under the 82+particapents' control (i.e. addresses from the secondary wallets).
murchandamus commented at 6:35 pm on January 28, 2026:0participants' control (i.e. addresses from the secondary wallets).in bip-timelock-recovery-storage-format.mediawiki:68 in a18dd7373b outdated
63+ 64+== Specification == 65+ 66+A ''Timelock-Recovery plan'' consists of two transactions: 67+ 68+* ''Alert Transaction'': A mostly-consolidation transaction that keeps most funds in the original wallet, except for a fee and a small fixed amount that goes to ''anchor-addresses'' - addresses which can be used to accelerate the ''Alert Transaction'' via CPFP. The majority of funds should remain on the original wallet, in a new previously-unused address which we call the ''alert-address''. We use the term ''Alert Transaction'' because it should alert the user that the recovery-plan has been triggered, giving them a limited time to prevent the majority of the funds from moving to the secondary wallets.
murchandamus commented at 6:43 pm on January 28, 2026:Not speaking as an editor, but just as a reviewer, I am a bit on the fence regarding the idea of using an on-chain transaction to notify the user that their recovery transaction will reach maturity soon. Something has to broadcast that alert transaction upon maturity for it to be mined. For the user to see that notification, the user would need to actively monitor the wallet that is paid by the alert transaction. Under those two assumptions, why wouldn’t the daemon/service that broadcasts the alert transaction or the receiving app notify the user by a notification on their phone or send an email?
Perhaps you could expand your Rationale on why a transaction was chosen over other ways to notify the user.
oren-z0 commented at 10:16 pm on January 29, 2026:Monitoring the blockchain and looking for the alert-transaction is intended for unintentional broadcast, either by accident or by a malicious hacker. I’ve added a new line to explain that using a reliable tool to monitor the blockchain and search for the alert transaction - users can keep one or more online backups of the presigned transactions (unlike seed phrases which should never go online). Someone hacked the online backup and broadcast the Alert Transaction? Not a big deal, you have many days (depending on the Recovery Transaction nSeqeunce) to prevent the majority of funds from moving to the secondary wallet. An nSequence of ~90 days means that you can even monitor the blockchain manually, by setting a monthly reminder to check https://mempool.space/tx/<alert_txid>
Check our https://timelockrecovery.com for a list of services that can do the monitoring (plus I’m working on a new Android app + service that will let you create the presigned transactions and monitor them).
2396392a62fix typo
Co-authored-by: Mark "Murch" Erhardt <murch@murch.one>
add surname initial to author name 5538fb42f7oren-z0 requested review from murchandamus on Jan 29, 2026oren-z0 force-pushed on Jan 29, 2026oren-z0 force-pushed on Jan 29, 2026Explain unintentional initiation of rrecovery-plan. 38acc9dd31oren-z0 force-pushed on Jan 29, 2026limit alert_inputs length to 2439 dc80bae422murchandamus commented at 8:07 pm on February 3, 2026: memberI just looked this over again. From an editorial perspective this looks like it’s getting close to publication. Please consider whether your document introduces any potential incompabilities, and if so, add a Backwards Compatibility section.
Other than that, what are the next steps from your perspective? Are you working with any Bitcoin projects that are working on implementing this scheme? Are you expecting any other reviewers to take a look?
murchandamus removed the label PR Author action required on Feb 3, 2026murchandamus added the label Needs number assignment on Feb 3, 2026oren-z0 commented at 10:03 pm on February 3, 2026: noneI just looked this over again. From an editorial perspective this looks like it’s getting close to publication. Please consider whether your document introduces any potential incompabilities, and if so, add a Backwards Compatibility section.
Other than that, what are the next steps from your perspective? Are you working with any Bitcoin projects that are working on implementing this scheme? Are you expecting any other reviewers to take a look?
Thanks again for the thorough review. The current implementation in Electrum matches the BIP description. I also developed a similar plugin for Specter Desktop here, which I don’t think matches exactly the BIP - but AFAIK Specter Desktop is not being maintained anymore (except for bug fixes).
A friend and I founded https://ritrek.com based exactly on the BIP idea, and soon we’ll release our Android app where users could create/upload recovery-plans and later initiate them, monitor them (get push-notifications on their status, or if the wallet “double-spent” them), and set a dead-man-switch to initiate them automatically after X months if the app hasn’t been opened. I think we have a small market of less-technical Bitcoiners who don’t want to switch to a multisig wallet and use one of the “collaborative custody” solutions. It’s also more secure in my opinion (no 3rd party key that could leak), but with the downside of not being able to touch that wallet (without re-signing new transactions).
I think the BIP is fine as is and doesn’t need more reviewers. I have a small doubt whether we should add the Alert Transaction’s inputs’ amounts - and allow validating the segwit transaction without querying those UTXOs. On the other hand, any service that accepts such JSON should call
testmempoolacceptanyways.In any case, if there will be major changes in the future to the json format, we can always add a “version” field, or change the “kind” from “timelock-recovery-plan” to “timelock-recovery-plan-v2”.
murchandamus commented at 6:24 pm on February 5, 2026: memberAssigned BIP 128. Please update the BIP and Assigned headers, the file name of the document, and add a table entry to the README for your BIP.murchandamus renamed this:
BIP Draft: Timelock-Recovery Storage Format
BIP128: Timelock-Recovery Storage Format
on Feb 5, 2026murchandamus removed the label Needs number assignment on Feb 5, 2026updating bip number to 128 6f9a3ffcf8rename to bip-0128.mediawiki 767e172739BIP 128: Timelock-Recovery storage format 9b2af3823boren-z0 commented at 9:47 pm on February 5, 2026: none@murchandamus Pushed the changes. BIP 2^7 🤓fix field order, change title to uppercase 6ce8e77e0aoren-z0 force-pushed on Feb 5, 2026murchandamus commented at 0:30 am on February 6, 2026: memberThanks for the quick turnaround. I propose leaving this open for a few more days as often a number assignment will spur some additional review. Please feel free to remind me to take another look on 2026-02-12 or later, if this hasn’t gotten more review or been merged.Labels
New BIP
github-metadata-mirror
This is a metadata mirror of the GitHub repository bitcoin/bips. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2026-02-10 16:10 UTC
This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me