Package: lnurl
LNURL implementation for PythonA collection of helpers for buildingLNURLsupport into wallets and services.ConfigurationDevelopers can force strict RFC3986 validation for the URLs that the library encodes/decodes, using this env var:LNURL_STRICT_RFC3986 = "0" by default (False)Basic usage>>>importlnurl>>>lnurl.encode('https://service.io/?q=3fc3645b439ce8e7')Lnurl('LNURL1DP68GURN8GHJ7UM9WFMXJCM99E5K7TELWY7NXENRXVMRGDTZXSENJCM98PJNWXQ96S9',bech32=Bech32('LNURL1DP68GURN8GHJ7UM9WFMXJCM99E5K7TELWY7NXENRXVMRGDTZXSENJCM98PJNWXQ96S9',hrp='lnurl',data=[13,1,26,7,8,28,3,19,7,8,23,18,30,28,27,5,14,9,27,6,18,24,27,5,5,25,20,22,30,11,25,31,14,4,30,19,6,25,19,3,6,12,27,3,8,13,11,2,6,16,25,19,18,24,27,5,7,1,18,19,14]),url=WebUrl('https://service.io/?q=3fc3645b439ce8e7',scheme='https',host='service.io',tld='io',host_type='domain',path='/',query='q=3fc3645b439ce8e7'))>>>lnurl.decode('LNURL1DP68GURN8GHJ7UM9WFMXJCM99E5K7TELWY7NXENRXVMRGDTZXSENJCM98PJNWXQ96S9')WebUrl('https://service.io/?q=3fc3645b439ce8e7',scheme='https',host='service.io',tld='io',host_type='domain',path='/',query='q=3fc3645b439ce8e7')TheLnurlobject wraps a bech32 LNURL to provide some extra utilities.fromlnurlimportLnurllnurl=Lnurl("LNURL1DP68GURN8GHJ7UM9WFMXJCM99E5K7TELWY7NXENRXVMRGDTZXSENJCM98PJNWXQ96S9")lnurl.bech32# "LNURL1DP68GURN8GHJ7UM9WFMXJCM99E5K7TELWY7NXENRXVMRGDTZXSENJCM98PJNWXQ96S9"lnurl.bech32.hrp# "lnurl"lnurl.url# "https://service.io/?q=3fc3645b439ce8e7"lnurl.url.host# "service.io"lnurl.url.base# "https://service.io/"lnurl.url.query# "q=3fc3645b439ce8e7"lnurl.url.query_params# {"q": "3fc3645b439ce8e7"}Parsing LNURL responsesYou can use aLnurlResponseto wrap responses you get from a LNURL.
The different types of responses defined in theLNURL spechave a different model
with different properties (seemodels.py):importrequestsfromlnurlimportLnurl,LnurlResponselnurl=Lnurl('LNURL1DP68GURN8GHJ7MRWW4EXCTNZD9NHXATW9EU8J730D3H82UNV94MKJARGV3EXZAELWDJHXUMFDAHR6WFHXQERSVPCA649RV')r=requests.get(lnurl.url)res=LnurlResponse.from_dict(r.json())# LnurlPayResponseres.ok# boolres.max_sendable# intres.max_sats# intres.callback.base# strres.callback.query_params# dictres.metadata# strres.metadata.list()# listres.metadata.text# strres.metadata.images# listIf you have alreadyrequestsinstalled, you can also use the.handle()function directly.
It will return the appropriate response for a LNURL.>>>importlnurl>>>lnurl.handle('lightning:LNURL1DP68GURN8GHJ7MRWW4EXCTNZD9NHXATW9EU8J730D3H82UNV94CXZ7FLWDJHXUMFDAHR6V33XCUNSVE38QV6UF')LnurlPayResponse(tag='payRequest',callback=WebUrl('https://lnurl.bigsun.xyz/lnurl-pay/callback/2169831',scheme='https',host='lnurl.bigsun.xyz',tld='xyz',host_type='domain',path='/lnurl-pay/callback/2169831'),min_sendable=10000,max_sendable=10000,metadata=LnurlPayMetadata('[["text/plain","NgHaEyaZNDnW iI DsFYdkI"],["image/png;base64","iVBOR...uQmCC"]]'))Building your own LNURL responsesFor LNURL services, thelnurlpackage can be used to buildvalidresponses.fromlnurlimportLnurlWithdrawResponseres=LnurlWithdrawResponse(callback="https://lnurl.bigsun.xyz/lnurl-withdraw/callback/9702808",k1="38d304051c1b76dcd8c5ee17ee15ff0ebc02090c0afbc6c98100adfa3f920874",min_withdrawable=551000,max_withdrawable=551000,default_description="sample withdraw",)res.json()# strres.dict()# dictAll responses arepydanticmodels, so the information you provide will be validated and you have
access to.json()and.dict()methods to export the data.Data is exported using :camel: camelCase keys by default, as per spec.You can also use camelCases when you parse the data, and it will be converted to snake_case to make your
Python code nicer.If you want to export the data using :snake: snake_case (in your Python code, for example), you can change
theby_aliasparameter:res.dict(by_alias=False)(it isTrueby default).CLI$poetryrunlnurlUsage: lnurl [OPTIONS] COMMAND [ARGS]...Python CLI for LNURL decode and encode lnurlsOptions:--help  Show this message and exit.Commands:decode           decode a LNURLencode           encode a URLhandle           handle a LNURLpayment-request  make a payment_request