diff --git a/uma/test/uma_test.go b/uma/test/uma_test.go index 868c851..432edf7 100644 --- a/uma/test/uma_test.go +++ b/uma/test/uma_test.go @@ -117,6 +117,20 @@ func TestSignAndVerifyLnurlpRequest(t *testing.T) { require.NoError(t, err) } +func TestSignAndVerifyLnurlpRequestReplacingDomain(t *testing.T) { + privateKey, err := secp256k1.GeneratePrivateKey() + require.NoError(t, err) + queryUrl, err := uma.GetSignedLnurlpRequestUrl(privateKey.Serialize(), "$bob@vasp3.com", "vasp1.com", true, nil) + require.NoError(t, err) + queryUrl.Host = "vasp2.com" + query, err := uma.ParseLnurlpRequestWithReceiverDomain(*queryUrl, "vasp3.com") + require.NoError(t, err) + require.Equal(t, *query.UmaVersion, uma.UmaProtocolVersion) + require.Equal(t, query.ReceiverAddress, "$bob@vasp3.com") + err = uma.VerifyUmaLnurlpQuerySignature(*query.AsUmaRequest(), getPubKeyResponse(privateKey), getNonceCache()) + require.NoError(t, err) +} + func TestParseLnurlpRequestUnsupportedVersion(t *testing.T) { privateKey, err := secp256k1.GeneratePrivateKey() require.NoError(t, err) diff --git a/uma/uma.go b/uma/uma.go index ea9aa24..fb5eab0 100644 --- a/uma/uma.go +++ b/uma/uma.go @@ -264,6 +264,18 @@ func IsUmaLnurlpQuery(url url.URL) bool { // // url: the full URL of the uma request. func ParseLnurlpRequest(url url.URL) (*protocol.LnurlpRequest, error) { + return ParseLnurlpRequestWithReceiverDomain(url, url.Host) +} + +// ParseLnurlpRequestWithReceiverDomain Parses the message into an LnurlpRequest object using an overridden receiver UMA domain. +// +// This is useful for cases where the receiver domain is not the same as the incoming request Host, for example when the +// request is being proxied to another internal service. +// Args: +// +// url: the full URL of the uma request. +// receiverDomain: the domain of the receiver UMA of the payment. This is used to override the domain in the URL. +func ParseLnurlpRequestWithReceiverDomain(url url.URL, receiverDomain string) (*protocol.LnurlpRequest, error) { query := url.Query() signature := query.Get("signature") vaspDomain := query.Get("vaspDomain") @@ -292,7 +304,7 @@ func ParseLnurlpRequest(url url.URL) (*protocol.LnurlpRequest, error) { if len(pathParts) != 4 || pathParts[1] != ".well-known" || pathParts[2] != "lnurlp" { return nil, errors.New("invalid uma request path") } - receiverAddress := pathParts[3] + "@" + url.Host + receiverAddress := pathParts[3] + "@" + receiverDomain nilIfEmpty := func(s string) *string { if s == "" {