Every self custody guide starts from the same assumption. Somewhere, a private key exists, and your whole job is to protect it.
Seed on steel. Seed in a safe. Seed split into shares. Hardware wallet in a drawer. It’s all the same game: a secret exists, and you try to make sure only you can use it.
This article is about a different move. What if, for one specific pile of sats, the key simply stopped existing?
Not hidden. Not encrypted. Gone.
It sounds like the fastest way to lose your bitcoin. It isn’t, if you do one thing first. Before destroying the key, you use it exactly once to sign a single transaction that sends the whole amount to a wallet you control. You don’t broadcast it. You keep it. The coins stay where they are on chain, and the only thing in the universe that can ever move them is that one signed transaction.
A one way door, built in advance.
Let’s look at how it works, what it really protects you from and, more importantly, what it doesn’t.
What a presigned transaction actually is
A Bitcoin transaction is just data. Which coins you’re spending (inputs), where they go (outputs), how much, plus a signature proving the owner of the input authorised it.
Normally you create, sign and broadcast in one click. But nothing forces those steps to happen together. You can sign today and broadcast in five years. The network doesn’t care when the signature was made, only that it’s valid and that the input hasn’t been spent yet.
Why the signature freezes everything
With the default signature type, SIGHASH_ALL, the signature commits to all inputs and all outputs. Change one byte, the destination, the amount or the fee, and the signature is invalid.
That’s the whole point. Once signed, the transaction is immutable. Once the key is deleted, it’s also the only possible spending path for that UTXO. Nobody can create an alternative, including you.
This idea has a pedigree
This isn’t a trick someone invented on a forum. In August 2019 Bryan Bishop proposed “pre-signed vaults” on the bitcoin dev mailing list, built around what he called the delete the key presigned transaction concept. Sign exactly one transaction, delete the key, and you’ve emulated a covenant. You’ve enforced a specific outcome without any soft fork.
Bishop’s design is far more elaborate, with delays, clawbacks and multisig. What we’re doing here is the simplest possible version of the same primitive. One input, one output, one allowed future.
The workflow, step by step
Do the whole thing on signet or testnet first. Seriously. It costs nothing and you’ll discover your mistakes when they’re free.
1. Create the single key wallet
Generate a standalone key: private key, public key, WIF and a single address. Use a native SegWit address, the ones starting with bc1q. Get your entropy from a source you trust: dice, or an offline generator you’ve audited. You can use whatever tool you prefer, even Papergen if you want (an open source project that enables creation of secrets from mic or camera noise on a distro like tails).
Import it into Electrum as a single key wallet. Go to File, then New/Restore, then choose “Import Bitcoin addresses or private keys”. For a native SegWit address you put the script type in front of the WIF: p2wpkh: for bc1q addresses, p2wpkh-p2sh: for addresses starting with 3.
One gotcha. SegWit addresses require compressed keys. A WIF starting with 5 is uncompressed and will give you a different address than you expect. Compressed WIFs start with K or L.
2. Prepare the destination
Create a separate HD wallet with a 12 or 24 word seed, backed up properly. Pick a fresh receiving address from it, never used, never shared. Ideally one of the first receiving addresses, so a future restore will find it without fiddling with gap limits.
2b. Fund the UTXO
Then send the bitcoin you want to lock up to the single key address. Wait for confirmations.
3. Build and sign, but don’t broadcast
In Electrum, create a transaction from the single key wallet that spends 100% of the UTXO to the destination address. One input, one output, no change. Set the fee manually. Sign it.
Don’t press broadcast. Export the signed transaction as raw hex and copy it out.
If you prefer to stay entirely inside Bitcoin Core, the toolbox section at the end shows how to build and sign the same transaction from the command line.
4. Verify before you destroy anything
This is the step people rush. Don’t.
You need to confirm four things: the input is your UTXO, the single output is your destination address, the amount is what you expect, and the transaction would be accepted by the mempool today. The toolbox section lists exactly where and how to check each of these, with a node or without one.
Keep in mind what these tests prove. The transaction is valid under today’s policy. Not the policy of 2031.
Also write down the transaction’s wtxid, the hash field in the decoded output. It’s a free checksum. If your stored hex ever decodes to a different hash, you know it’s been corrupted.
5. Delete the key, properly
Deleting means more than closing the Electrum window. The key may still live in the Electrum wallet file and its backups, in your clipboard history, in your shell history if you touched it on the command line, in swap or a cloud synced folder, and on the paper or file you generated it on.
The cleanest approach is to do steps 1 to 5 on an air gapped, amnesic system, a live USB with no persistence. When you power off, the key is gone with the session.
Be honest with yourself here. You can’t prove deletion. You can only make it very likely. That’s still a big improvement over a key sitting on a hard drive for years.
6. Store the hex
The signed transaction is a few hundred characters of hex. It contains no secret that lets anyone redirect the funds, so it can live in places you’d never put a seed: a password manager (a command line one like pass works nicely), an encrypted note, a printed QR code, several copies in several places.
Store it with the wtxid next to it. Make at least two copies. A single missing character makes it worthless.
7. Redeem
When you want the coins, broadcast the hex, from your own node or from one of the web tools listed below. Once it confirms, the coins are in your HD wallet and behave like any other UTXO.
What you actually gain, and what you don’t
The version you’ll often hear is “no private key, no theft risk”. That’s too simple. Let’s be precise.
The risk doesn’t disappear. It moves.
What you eliminate is the source key. There is no longer any key that can send those coins anywhere except your destination. Malware, a leaked backup, a coerced signature: none of that can redirect them.
But the destination seed now carries 100% of the security. And there’s a nasty edge case. If that seed is ever compromised, you’re stuck. You can’t broadcast the hex, because the moment the coins land, whoever has the seed can sweep them. You also can’t redirect them, because the key that could sign an alternative no longer exists. The coins are frozen at best.
So the real security model is this: an attacker needs both the hex, to move the coins, and the destination seed, to spend them afterwards. Store the two separately. If they sit in the same password vault, you’ve gained almost nothing.
The hex is not a bearer instrument
Someone who finds your hex can broadcast it. They can’t steal anything, because the coins go to your address. But they can move your coins earlier than you planned, and they learn the amount, the source UTXO and the destination address.
Treat the hex as confidential, not secret. Leaking it is a privacy problem and a timing problem, not a theft.
Other honest limitations
Immutable parameters. Destination, amount and fee are frozen forever.
Lose the destination seed, lose everything. There’s no second path.
Corruption kills it. One wrong character and the signature fails.
Policy drift. Relay rules are node policy, not consensus, and they do change. A transaction that passes today should still be consensus valid years from now, but nobody can guarantee every relay rule will stay as permissive. Simple single input, single output SegWit spends are about as boring and future proof as it gets, which is exactly why you want them.
The fee problem, and why recent releases changed it
This is where the strategy used to be fragile, and where recent Bitcoin Core releases made it much more robust.
CPFP needs the parent to reach a mempool
The classic answer to “my presigned fee is too low” is Child Pays For Parent. The destination output belongs to your HD wallet, so you spend it in a new transaction with a high fee. Miners want the child, and to get it they have to mine the parent too.
The catch: for years, if the parent’s fee rate was below what nodes accepted into their mempool, the parent simply didn’t propagate. And if the parent doesn’t propagate, the child is an orphan with nothing to pay for. In a fee spike, your carefully stored transaction could be stuck on your own node.
Package relay: the fix that makes this practical
Bitcoin Core 28.0 (2024) introduced limited package relay for one parent, one child packages, called 1P1C. A low fee parent can get into the mempool regardless of the dynamic mempool minimum fee rate, as long as a single child pays for it. You can submit the pair to your own node with the submitpackage RPC.
Bitcoin Core 31.0 (April 2026) went further. In 1P1C package relay the parent can now pay less than the minimum relay fee, even zero, and this is no longer limited to TRUC transactions.
Separately, Bitcoin Core 29.1 (September 2025) lowered the default minimum relay fee from 1 sat/vB to 0.1 sat/vB.
What this means for us: a presigned transaction with a fee that looks ridiculously low in a future fee spike is no longer a dead end. Build the child in your HD wallet, submit parent and child together as a package, and let the child carry the fee.
Two caveats. The 28.0 release notes state this P2P feature is not yet reliable under adversarial conditions. And it only helps if the nodes you’re connected to run versions that support it. Adoption of new releases is gradual.
A fee ladder: sign more than once
Here’s a simple improvement to the basic workflow. Before deleting the key, sign several versions of the transaction: same input, same destination, different fees. Say low, medium and high. Store all of them.
Only one can ever confirm, because they all spend the same UTXO. At redemption time you broadcast the one that matches the fee market. CPFP becomes the backup plan, not the only plan.
Variants worth knowing
A time capsule with nLockTime
If you set the transaction’s nLockTime to a future block height or date, nodes will reject it until that point. Combined with a deleted key, you get a time lock without any script. The coins literally cannot move before that block, by anyone, including you.
Useful for self imposed “don’t touch this” savings. Dangerous if you think you might need the money before then. In Bitcoin Core, createrawtransaction accepts a locktime parameter (see the toolbox). If you use another wallet, check whether it exposes the field before relying on it.
Inheritance and gifting
This is where the idea gets genuinely interesting. You can hand someone a presigned transaction that pays to their wallet. It can’t be redirected to anything else, and it contains no key that needs a secure backup. It’s a gift envelope that only opens one way.
Same caveats apply. They need to protect their own seed, and they need to understand what the hex is so they don’t throw it away during a cleanup.
Privacy at broadcast time
When you broadcast through a public website, that service sees your IP address next to the transaction. For a one time, possibly large movement of coins, that’s not great.
Your options, from good to better: use the Tor onion version of mempool.space, broadcast from your own Bitcoin Core node, or on Bitcoin Core 31.0 and later enable privatebroadcast. With that option your node sends your own transactions only via Tor or I2P, using a separate connection per transaction, so two unrelated broadcasts can’t be linked to each other.
Toolbox: where to preview, test and broadcast
Web tools
Use the mainnet URLs below. For signet or testnet, insert /signet or /testnet after the domain, for example https://mempool.space/signet/tx/push.
Preview and decode: https://mempool.space/tx/preview
Paste the raw hex (or a PSBT) and it decodes the transaction before you broadcast. It has an offline mode that skips fetching previous outputs, useful if you don’t want to reveal which UTXO you’re looking at, though some fee calculations won’t be available.
Test against mempool policy: https://mempool.space/tx/test
Runs the equivalent of testmempoolaccept. Accepts up to 25 comma separated raw transactions, so you can test a whole fee ladder in one go.
Broadcast: https://mempool.space/tx/push
Broadcast via API: send an HTTP POST with the raw hex as the body, content type text/plain, to https://mempool.space/api/tx:
curl -X POST -H “Content-Type: text/plain” \
--data “<hex>” https://mempool.space/api/txDecode, look up and broadcast: https://apps.txid.uk/en/tx-builder/ (app at https://tx.txid.uk)
Shows version, inputs, outputs, witness data, locktime and vsize, lets you check fee rates, and broadcasts through the mempool.space API.
For privacy, prefer the onion address published by mempool.space itself, reached through Tor Browser, over the clearnet URLs.
Bitcoin Core commands
All commands below work on mainnet. Add -signet or -testnet to run them on a test network.
Check the UTXO is funded and still unspent (before signing, and periodically afterwards):
bitcoin-cli gettxout <funding_txid> <vout>It returns the output’s value and script. It returns nothing if the output doesn’t exist or has already been spent.
Build the transaction in Bitcoin Core instead of Electrum (optional, on the offline machine):
# one input, one output, optional locktime as last argument
bitcoin-cli createrawtransaction \
‘[{”txid”:”<funding_txid>”,”vout”:<vout>}]’ \
‘[{”<destination_address>”:<amount_minus_fee>}]’ \
<locktime>
# sign with the single key; for SegWit the previous output’s amount is required
bitcoin-cli signrawtransactionwithkey “<unsigned_hex>” \
‘[”<WIF>”]’ \
‘[{”txid”:”<funding_txid>”,”vout”:<vout>,”scriptPubKey”:”<script_hex>”,”amount”:<utxo_amount>}]’The scriptPubKey comes from the gettxout output. Leave out the locktime argument (or use 0) if you don’t want a time capsule. Remember that typing the WIF on the command line leaves it in shell history, one more reason to do this on an amnesic system.
Decode and inspect:
bitcoin-cli decoderawtransaction <hex>
Check inputs, outputs, amount, vsize and locktime. The hash field is the wtxid to store as a checksum.
Test against mempool policy without broadcasting:
bitcoin-cli testmempoolaccept ‘[”<hex>”]’You want "allowed": true. A reject reason tells you what to fix before deleting the key.
Broadcast:
bitcoin-cli sendrawtransaction <hex>Check it’s in your mempool after broadcasting:
bitcoin-cli getmempoolentry <txid>Fee bump with a package (CPFP): create the child in your destination wallet, spending the unconfirmed output of the presigned transaction with a high fee, and export its raw hex. Then test and submit parent and child together, parent first:
bitcoin-cli testmempoolaccept ‘[”<parent_hex>”,”<child_hex>”]’
bitcoin-cli submitpackage ‘[”<parent_hex>”,”<child_hex>”]’Private broadcast (Bitcoin Core 31.0 and later, with Tor or I2P configured), in bitcoin.conf:
privatebroadcast=1Your safety Checklist
Tested the full flow on signet or testnet first
Native SegWit address, compressed key
Destination is a fresh, unused address from a backed up HD wallet
One input, one output, no change
Decoded and checked: input, output, amount, fee
Mempool test returned allowed: true
Optional: signed a fee ladder (low, medium, high)
Recorded the wtxid as a checksum
Key generated and deleted on an amnesic, offline system
Hex stored in at least two places, separately from the destination seed
You know how to fee bump with a package if fees spike
Take
Most self custody advice is about protecting a secret. This strategy is about removing one.
It’s not magic. You trade flexibility for finality. The destination, amount and fee are set in stone, and the destination seed becomes the single point everything rests on. But for a specific use case, coins you want to park, gift or pass on with no hot key lying around, it’s an elegant, fully native tool. No soft fork, no custodian, no special software. Just a signature and a delete key.
And thanks to package relay in recent Bitcoin Core releases, the weakest part of the idea, being stuck with a fee you chose years ago, is much less of a problem than it used to be.
Try it on signet this week. Break it on purpose. Then decide whether it earns a place in your setup.
If you want more pieces like this, Bitcoin mechanics explained by someone who actually runs the nodes, subscribe, and tell me in the comments which variant you’d use: time capsule, inheritance, or cold parking.
Friends’ Links:


