Initial LNURLP Request

The first request from the sending VASP (VASP1) to the receiving VASP (VASP2) is an lnurlp request corresponding to the Lightning Address (LUD-16) specification, but with some additional query parameters.
If $alice@vasp1.com is paying $bob@vasp2.com, the request looks like:
GET vasp2.com/.well-known/lnurlp/$bob?umaVersion=1.0&nonce=1234&vaspDomain=vasp1.com&signature=abcd&isSubjectToTravelRule=true&timestamp=12345678
  • umaVersion is the UMA standard version supported by VASP1. See the versioning section below.
  • isSubjectToTravelRule indicates vasp1 is a financial institution that is subject to the Travel Rule.
  • nonce is a random unique string generated by the SDK that is used to prevent replay attacks.
  • timestamp is the unix timestamp in seconds (number of seconds since epoch).
  • signature is vasp1's signature over hash("$bob@vasp2.com" + nonce + timestamp). Signatures are always hex-encoded strings for UMA.
This request can be easily created using the UMA SDK:
lnurlp_request_url = uma.create_uma_lnurlp_request_url(
    signing_private_key=signing_private_key,
    receiver_address="$bob@vasp2.com",
    sender_vasp_domain="vasp1.com",
    is_subject_to_travel_rule=True,
)
The first parameter to this function is your signing private key so that the SDK can sign the request for you. Details on keys and how to generate them can be found in the previous section. Now that you have a signed request URL, you can send the request using your preferred request framework:
import requests
  
response = requests.get(lnurlp_request_url)
if response.status_code != 200:
    # Handle error
The receiving VASP can parse the incoming lnurlp request using the SDK:
lnurlp_request = uma.parse_lnurlp_request(request_url)
The parsed request object has the structure:
@dataclass
class LnurlpRequest:
    receiver_address: str
    """
    The UMA or Lightning address of the receiver.
    """

    nonce: Optional[str]
    """
    A random string included in the signature payload to prevent replay attacks.
    """

    signature: Optional[str]
    """
    DER-encoded signature from the sending VASP.
    """

    is_subject_to_travel_rule: Optional[bool]
    """
    Whether the sending VASP is subject to travel rule regulations.
    """

    vasp_domain: Optional[str]
    """
    The domain of the sending VASP.
    """

    timestamp: Optional[datetime]
    """
    The time at which the request was made.
    """

    uma_version: Optional[str]
    """
    The version of the UMA protocol that the sender is using.
    """
Next, the receiving VASP needs to verify the signature of the sending VASP in the LnurlpRequest object.