lightninglabs / lightninglabs/taproot-assets
Improve recovery UX when courier delivery fails after confirmed receive
Nobody has claimed this yet.
- Dominant language
- Go
- Stars
- 525
- Forks
- 150
- Avg merge
- 2d 15h
- Merged PRs (30d)
- 31
Description
## No obvious recovery path when proof courier delivery fails after confirmed receive
## Background
While testing a local Alice -> Bob Taproot Asset transfer on regtest, the transfer confirmed on-chain, but Bob never received/imported the proof.
The generated Bob address used the default proof courier:
```text
hashmail://mailbox.terminal.lightning.today:443
```
That courier failed, so proof delivery stayed pending. The bigger issue is that I could manually export and verify the correct proof, but I could not find a way to register/import it into Bob's wallet. Bob remained stuck with `has_proof=false` and no asset balance.
## Environment
```json
{
"version": "0.7.99-alpha commit=",
"lnd_version": "0.20.99-beta",
"network": "regtest"
}
```
Both Alice and Bob were local `lnd`/`tapd` regtest nodes.
## Steps to reproduce
1. Start local Alice and Bob regtest nodes.
2. Mint and finalize an asset on Alice.
3. Sync Bob with Alice's issuance universe:
```sh
./bob-tapd.sh universe sync \
--universe_host 127.0.0.1:10029 \
--asset_id "$ASSET_ID" \
--proof_type issuance
```
4. Bob creates a receive address:
```sh
BOB_ADDR=$(./bob-tapd.sh newaddr "$ASSET_ID" 100 | jq -r .encoded)
```
The generated address contains:
```json
{
"proof_courier_addr": "hashmail://mailbox.terminal.lightning.today:443"
}
```
5. Alice sends to Bob:
```sh
./alice-tapd.sh send "$BOB_ADDR"
```
6. Mine confirmations.
## Actual behavior
Alice's transfer confirms, but proof delivery remains pending:
```json
{
"amount": "100",
"output_type": "OUTPUT_TYPE_SIMPLE",
"script_key_is_local": false,
"proof_delivery_status": "PROOF_DELIVERY_STATUS_PENDING",
"proof_courier_addr": "hashmail://mailbox.terminal.lightning.today:443"
}
```
Bob detects the confirmed receive outpoint, but has no proof:
```json
{
"status": "ADDR_EVENT_STATUS_TRANSACTION_CONFIRMED",
"outpoint": "43be5fa32abecbecbf91995515dfcb626d68923b149bb554452e57877c24e7ae:1",
"confirmation_height": 126,
"has_proof": false
}
```
Bob's balance remains empty:
```json
{
"asset_balances": {},
"asset_group_balances": {},
"unconfirmed_transfers": "0"
}
```
## Manual proof verification works, but does not recover the receive
I exported the proof from Alice for Bob's script key:
```sh
BOB_SCRIPT_KEY=$(
./bob-tapd.sh raw addrs receives \
| jq -r '.events[-1].addr.script_key'
)
./alice-tapd.sh raw proofs export \
--asset_id "$ASSET_ID" \
--script_key "$BOB_SCRIPT_KEY" \
--proof_file /tmp/bob-asset-proof.tap
```
Then verified it with Bob:
```sh
./bob-tapd.sh raw proofs verify \
--proof_file /tmp/bob-asset-proof.tap
```
Bob returned:
```json
{
"valid": true
}
```
So the proof itself appears valid and corresponds to Bob's receive output, but verifying it does not register/import the asset into Bob's wallet.
I also could not find an obvious CLI path to manually import/register that valid proof after courier delivery failed.
## Logs
Alice repeatedly fails to deliver through the default hashmail courier:
```text
PROF: Backing off: proof transfer failed
addr=hashmail://mailbox.terminal.lightning.today:443
transfer_type=send
err="failed to initialize mailboxes: failed to init sender stream mailbox:
rpc error: code = Unavailable desc = connection error:
desc = \"transport: authentication handshake failed: credentials: cannot check peer:
missing selected ALPN property...\""
```
Bob logs show the same issue while trying to receive the proof:
```text
GRDN: Unable to receive proof ... unable to receive proof using courier:
rpc error: code = Unavailable desc = connection error:
desc = "transport: authentication handshake failed: credentials: cannot check peer:
missing selected ALPN property..."
```
## Expected behavior
If courier delivery fails after the receiver detects a confirmed address event, there should be a clear recovery path.
For example:
1. `proofs verify` could optionally register/import the proof when it matches a local receive address;
2. there could be a documented CLI command to manually register/import a valid proof;
3. the receiver could retry proof retrieval from a configurable/local courier;
4. or the address creation flow could make it clearer that using the default public courier may leave local regtest receives unrecoverable without additional setup.
## Actual problem
The receiver reaches this state:
```text
ADDR_EVENT_STATUS_TRANSACTION_CONFIRMED
has_proof=false
```
and even though a valid proof can be exported by the sender and verified by the receiver, there is no obvious way to move Bob's wallet into the received state.
## Question
What is the expected recovery path after proof courier delivery fails?
Is there a supported way to manually register/import a valid proof for a local receive address?
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the CLI entry points described in the issue: raw addrs receives, raw proofs export, and raw proofs verify, then trace the proof courier receive and registration flow. Define a supported recovery path for a confirmed address with has_proof=false, and verify it using the regtest reproduction and the exported proof scenario.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go
- Domain
- backend, cli
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Needs clarification
- Newbie friendliness
- 35/100