Skip to content

LNURL: Atomic lightning address transfer#829

Open
dangeross wants to merge 2 commits into
mainfrom
savage-lnurl-transfer
Open

LNURL: Atomic lightning address transfer#829
dangeross wants to merge 2 commits into
mainfrom
savage-lnurl-transfer

Conversation

@dangeross
Copy link
Copy Markdown
Collaborator

@dangeross dangeross commented Apr 24, 2026

Adds atomic Lightning address username transfer between pubkeys. A user can now hand a registered username from one pubkey to another in a single server-side transaction — closing the race window where today's delete-then-reregister flow could let a third party snipe the name.

How it works

  1. Current owner (A) calls accept_lightning_address_transfer with the new owner's identity_pubkey. The method returns a LightningAddressTransfer containing pubkey and signature, which is the authorization that grants B the right to take over the username.
  2. New owner (B) calls register_lightning_address with the new optional transfer: Some({ pubkey, signature }) field populated. The SDK routes to the server's new POST /lnurlpay/{to_pubkey}/transfer endpoint, which verifies both signatures and swaps ownership in one DB transaction (SELECT … FOR UPDATEDELETE source → INSERT … ON CONFLICT DO UPDATE target).

Copy link
Copy Markdown
Collaborator

@JssDWt JssDWt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep that will work! I like how both parties agree on the transfer this way.

_ => return Err(LnurlRepositoryError::SourceNotOwner),
}

sqlx::query("DELETE FROM users WHERE domain = $1 AND pubkey = $2")
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DELETE has a RETURNING option. We could do RETURNING name, use that as the source_name, and error if source not owner. It will work because the tx is not committed then.


The flow has two steps, run on two different SDKs:

**Step 1 — current owner (pubkey A):** produce a transfer authorization by signing a fixed message of the form `transfer:{pubkey_a}-{username}-{pubkey_b}`. Use {{#name sign_message}} on the SDK that currently owns the username. `pubkey_b` is the {{#name identity_pubkey}} of the receiving pubkey (available via {{#name get_info}}). The `username` must be the sanitized (lowercased and trimmed) form.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we add an sdk function accept_lightning_address_transfer, returning the needed info for the transfer field? This is not the worst DX, but not the best either.


{{#tabs lightning_address:get-lightning-address}}

### Transferring a Lightning address
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's worth a note that your existing payments are not transferred to the new owner. Only the address.

@dangeross dangeross force-pushed the savage-lnurl-transfer branch from 2fa8bff to 45263f1 Compare April 24, 2026 20:15
@dangeross dangeross requested a review from JssDWt April 24, 2026 20:32
Copy link
Copy Markdown
Collaborator

@JssDWt JssDWt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Maybe the rtsync integration test error is related though:
Error: SparkSdkError: Service error: service provider error: serialization error: Json error: expected value at line 1 column 1

@dangeross
Copy link
Copy Markdown
Collaborator Author

Maybe the rtsync integration test error is related though

Isn't it an SSP error?

@JssDWt
Copy link
Copy Markdown
Collaborator

JssDWt commented Apr 25, 2026

Isn't it an SSP error?

Ah yes it is

@dangeross dangeross force-pushed the savage-lnurl-transfer branch from 45263f1 to 0c01658 Compare May 8, 2026 06:40
@dangeross dangeross force-pushed the savage-lnurl-transfer branch from 0c01658 to ea8eb1f Compare May 8, 2026 09:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants