Use NWC lud16 parameter as initial value for lightning addresses (#2564)

* Also check protocol name before setting address field

* Add comment why we remove the domain part if lud16Domain is set

* Refactor NWC url parsing

* Use NWC's lud16 parameter as initial value

* Select lnAddr form by default if lud16 was parsed
This commit is contained in:
ekzyis 2025-09-22 00:35:44 +02:00 committed by GitHub
parent fe160ef698
commit a544e3952d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 28 additions and 16 deletions

View File

@ -2,6 +2,7 @@ import { isTemplate, isWallet, protocolClientSchema, protocolFields, protocolFor
import { createContext, useContext, useEffect, useMemo, useCallback, useState } from 'react'
import { useWalletProtocolUpsert } from '@/wallets/client/hooks'
import { MultiStepForm, useFormState, useStep } from '@/components/multi-step-form'
import { parseNwcUrl } from '@/wallets/lib/validate'
export const Step = {
SEND: 'send',
@ -50,14 +51,21 @@ export function useWalletProtocols () {
export function useProtocol () {
const { protocol, setProtocol } = useContext(WalletMultiStepFormContext)
const protocols = useWalletProtocols()
const [lnAddrForm] = useProtocolForm({ name: 'LN_ADDR', send: false })
useEffect(() => {
// when we move between send and receive, we need to make sure that we've selected a protocol
// that actually exists, so if the protocol is not found, we set it to the first protocol
// this makes sure that we've always selected a protocol (that exists) when moving between send and receive
if (!protocol || !protocols.find(p => p.id === protocol.id)) {
setProtocol(protocols[0])
// we switch to the LN_ADDR protocol form if it exists and there's an initial value
// else we just select the first protocol.
const lnAddrProto = protocols.find(p => p.name === 'LN_ADDR')
if (lnAddrForm?.initial.address && lnAddrProto) {
setProtocol(lnAddrProto)
} else {
setProtocol(protocols[0])
}
}
}, [protocol, protocols, setProtocol])
}, [protocol, protocols, setProtocol, lnAddrForm])
// make sure we always have a protocol, even on first render before useEffect runs
return useMemo(() => [protocol ?? protocols[0], setProtocol], [protocol, protocols, setProtocol])
@ -77,6 +85,7 @@ function useProtocolFormState (protocol) {
export function useProtocolForm (protocol) {
const [formState, setFormState] = useProtocolFormState(protocol)
const [complementaryFormState] = useProtocolFormState({ name: protocol.name, send: !protocol.send })
const [nwcSendFormState] = useProtocolFormState({ name: 'NWC', send: true })
const wallet = useWallet()
const lud16Domain = walletLud16Domain(wallet.name)
const fields = protocolFields(protocol)
@ -89,8 +98,16 @@ export function useProtocolForm (protocol) {
value = complementaryFormState?.config?.[field.name]
}
if (field.name === 'address' && lud16Domain && value) {
value = value.split('@')[0]
if (protocol.name === 'LN_ADDR' && field.name === 'address') {
// automatically set lightning addresses from NWC urls if lud16 parameter is present
if (nwcSendFormState?.config?.url) {
const { lud16 } = parseNwcUrl(nwcSendFormState.config.url)
if (lud16?.split('@')[1] === lud16Domain) value = lud16
}
// remove domain part since we will append it automatically if lud16Domain is set
if (lud16Domain && value) {
value = value.split('@')[0]
}
}
return {

View File

@ -57,17 +57,12 @@ export function parseNwcUrl (walletConnectUrl) {
// See https://stackoverflow.com/questions/56804936/how-does-only-numbers-in-url-resolve-to-a-domain
// However, this seems to only get triggered if a wallet pubkey only contains digits so this is pretty improbable.
const url = new URL(walletConnectUrl)
const params = {}
params.walletPubkey = url.host
const secret = url.searchParams.get('secret')
const relayUrls = url.searchParams.getAll('relay')
if (secret) {
params.secret = secret
return {
walletPubkey: url.host,
secret: url.searchParams.get('secret'),
relayUrls: url.searchParams.getAll('relay'),
lud16: url.searchParams.get('lud16')
}
if (relayUrls) {
params.relayUrls = relayUrls
}
return params
}
export const socketValidator = (msg = 'invalid socket') =>