Sending crypto to someone who has never installed a wallet is a surprisingly hard UX problem. You need their address, they need to pick the right network, and on chains like TRON or BNB Chain they also need a little native coin (TRX or BNB) just to move the token later.
One pattern that solves this is the claimable link: the sender creates a URL, shares it in WhatsApp or email, and whoever opens it can claim the funds. Here is how that works at the protocol level, and why the secret part of the link sits after the #.
1. An ephemeral wallet per link
When the sender creates a link, the app generates a fresh random private key on the device (32 bytes from a CSPRNG). That key controls a brand-new, single-use address on the target chain.
The sender then funds that address with:
- the transfer amount (for example USDT), and
- a small fee reserve, so the claim transaction can pay its own gas.
On BNB Chain the reserve is a bit of BNB. On TRON it is a little TRX to activate the account plus enough to cover energy for the USDT transfer. The key point: the sender pays the fees up front, so the receiver gets the full amount and never needs to hold a native coin.
2. The key travels in the URL fragment
The link looks roughly like this:
https://example.com/r/<link-id>#k=<key-material>
Everything after # is the fragment. Browsers never send the fragment to the server in the HTTP request. That gives a nice property: the backend can store the link ID, the ephemeral address, the amount and the expiry, while never seeing the key that can spend the funds.
The claim page reads location.hash in JavaScript, entirely client-side.
3. Claiming = signing on the receiver's device
When the receiver opens the link and chooses where to receive (a new wallet created on the spot, or an address they already own):
- The page or app reconstructs the ephemeral key from the fragment.
- It builds a transfer from the ephemeral address to the receiver's address.
- It signs locally and hands the signed transaction to the server.
- The server verifies it matches the link (right amount, right destination rules, not expired, not already claimed) and broadcasts it.
The server is a relay and a bookkeeper, not a custodian.
4. An optional second factor
A link in a chat is a bearer token: whoever has it can claim. To reduce the risk of a forwarded or leaked link, the fragment can carry the key XOR-ed with a value that is only released after the receiver enters a short security code. The sender shares that code over a different channel (a call, SMS, another app).
5. Expiry and refunds
Unclaimed links should not lock funds forever. After an expiry window (for example 7 days), the sender can sweep the ephemeral address back to their own wallet. Since the sender's device also kept the key, this needs no cooperation from the server beyond broadcasting.
Threat model in one table
| Risk | Mitigation |
|---|---|
| Server breach | Server never stores the spending key |
| Link forwarded to the wrong person | Optional security code on a second channel |
| Receiver has no gas | Fee reserve pre-funded by the sender |
| Link never opened | Expiry + sender refund |
| Link posted publicly | Nothing technical helps: treat it like cash |
Real-world example
This is the design behind send-by-link in Taccoin Wallet, the wallet I work on: USDT on TRON and BNB Chain, sender-paid fees, key in the #k= fragment, optional code, 7-day expiry with refund. There is a short write-up here: wallet.taccoin.com/en/features/send-by-link.
If you have built something similar (or found holes in this model), I would like to hear about it in the comments.
Disclosure: I work on Taccoin Wallet. This post was generated with AI tools. It is educational and not financial advice.

Top comments (1)
Useful write-up. One operational angle: treat on-chain settlement and off-chain reserve attestation as two different trust planes. If either plane fails silently, users only notice at redemption time. Continuous proofs plus a clear redeem SLA beat a prettier explorer UI.
iin1005h0028