lnurl package - github.com/Elenpay/go-lnurl - Go Packages

lnurl

package module
v0.0.0-...-e8869e7 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 4, 2026 License: MIT Imports: 25 Imported by: 0

README

lnurl

A bunch of helpers for building lnurl support into services.

See GoDoc.

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	FALSE *bool = &f
	TRUE  *bool = &t
)
View Source
var Client = &http.Client{
	Timeout: 5 * time.Second,
}
View Source
var TorClient *http.Client

Functions

func AESCipher

func AESCipher(key, plaintext []byte) (ciphertext []byte, iv []byte, err error)

func AESDecipher

func AESDecipher(key, ciphertext, iv []byte) (plaintext []byte, err error)

func Encode

func Encode(s string) (string, error)

func FindLNURLInText

func FindLNURLInText(text string) (lnurl string, ok bool)

FindLNURLInText uses a Regular Expression to find a bech32-encoded lnurl string in a blob of text.

func IsDomainName

func IsDomainName(s string) bool

IsDomainName (from net package) checks if a string is a presentation-format domain name (currently restricted to hostname-compatible "preferred name" LDH labels and SRV-like "underscore labels"; see golang.org/issue/12421).

func LNURLDecode

func LNURLDecode(code string) (string, error)

LNURLDecode takes a bech32-encoded lnurl string and returns a plain-text https URL.

func LNURLDecodeStrict

func LNURLDecodeStrict(code string) (string, error)

LNURLDecodeStrict takes a string and returns a valid lnurl, if possible. code can be

func LNURLEncode

func LNURLEncode(actualurl string) (lnurl string, err error)

LNURLEncode takes a plain-text https URL and returns a bech32-encoded uppercased lnurl string.

func LNURLEncodeStrict

func LNURLEncodeStrict(actualurl string) (string, error)

LNURLEncodeStrict will encode the actualurl to lnurl. based on the input url, it will determine whether bech32 encoding / url manipulation is necessary

func ParseInternetIdentifier

func ParseInternetIdentifier(text string) (name, domain string, ok bool)

ParseInternetIdentifier extracts name and domain from an email-like string like username@example.com

func RandomK1

func RandomK1() string

RandomK1 returns a 32-byte random hex-encoded string for usage as k1 in lnurl-auth and anywhere else.

func VerifySignature

func VerifySignature(k1, sig, key string) (ok bool, err error)

VerifySignature takes the hex-encoded parameters passed to an lnurl-login endpoint and verifies the signature against the key and challenge.

Types

type LNURLAuthParams

type LNURLAuthParams struct {
	Tag         string   `json:"tag"`
	K1          string   `json:"k1"`
	Callback    string   `json:"callback"`
	CallbackURL *url.URL `json:"-"`
	Host        string   `json:"host"`
}

func (LNURLAuthParams) LNURLKind

func (LNURLAuthParams) LNURLKind() string

type LNURLChannelResponse

type LNURLChannelResponse struct {
	LNURLResponse
	Tag         string   `json:"tag"`
	K1          string   `json:"k1"`
	Callback    string   `json:"callback"`
	CallbackURL *url.URL `json:"-"`
	URI         string   `json:"uri"`
}

func (LNURLChannelResponse) LNURLKind

func (_ LNURLChannelResponse) LNURLKind() string

type LNURLClient

type LNURLClient struct {
	// contains filtered or unexported fields
}

LNURLClient makes LNURL requests using the provided HTTP client. Use New for production (SSRF-safe) or NewWithClient/NewWithDefaultClient for dev/test.

func New

func New(opts ...Option) (*LNURLClient, error)

New returns an LNURLClient with an SSRF-safe HTTP transport that blocks connections to private/reserved IP ranges via net.Dialer.Control and disables proxy forwarding to prevent proxy-based bypass. Hosts passed to WithAllowedHosts are exempt from the private/reserved IP check. .onion addresses are routed through TorClient when set.

func NewWithClient

func NewWithClient(httpClient *http.Client, opts ...Option) *LNURLClient

NewWithClient returns an LNURLClient using the provided http.Client. The caller is responsible for any transport-level security (e.g. SSRF protection).

func NewWithDefaultClient

func NewWithDefaultClient(opts ...Option) *LNURLClient

NewWithDefaultClient returns an LNURLClient using OnioncapableTransport, preserving .onion routing behaviour. No SSRF protection — use only in dev/test.

func (*LNURLClient) Call

func (c *LNURLClient) Call(
	params LNURLPayParams,
	msats int64,
	comment string,
	payerdata *PayerDataValues,
) (int, *LNURLPayValues, error)

func (*LNURLClient) CallPay

func (c *LNURLClient) CallPay(
	metadata string,
	callback *url.URL,
	msats int64,
	comment string,
	payerdata *PayerDataValues,
) (int, *LNURLPayValues, error)

CallPay performs the LNURL-pay callback request using the client's HTTP client. It returns the HTTP status code alongside the pay values so callers can distinguish server errors (5xx) from protocol errors (invalid JSON, wrong amount, etc.).

func (*LNURLClient) HTTPClient

func (c *LNURLClient) HTTPClient() *http.Client

HTTPClient returns the underlying *http.Client. It is intended for use by wrappers that need to share the same transport (e.g. for direct HTTP calls). Do not mutate the returned client's transport.

func (*LNURLClient) HandleLNURL

func (c *LNURLClient) HandleLNURL(rawlnurl string) (string, LNURLParams, error)

HandleLNURL takes a bech32-encoded lnurl and either gets its parameters from the query- string or calls the URL to get the parameters. Returns a different struct for each of the lnurl subprotocols, the .LNURLKind() method of which should be checked next to see how the wallet is going to proceed.

func (*LNURLClient) HandlePay

func (c *LNURLClient) HandlePay(raw []byte) (*LNURLPayParams, error)

HandlePay parses and normalises a raw LNURL-pay params response body. It does not use the client's HTTP client — the method receiver exists for API symmetry so callers interact with all LNURL operations through one type.

type LNURLErrorResponse

type LNURLErrorResponse struct {
	Status string   `json:"status,omitempty"`
	Reason string   `json:"reason,omitempty"`
	URL    *url.URL `json:"-"`
}

func ErrorResponse

func ErrorResponse(reason string) LNURLErrorResponse

func (LNURLErrorResponse) Error

func (r LNURLErrorResponse) Error() string

type LNURLParams

type LNURLParams interface {
	LNURLKind() string
}

func HandleAuth

func HandleAuth(rawurl string, parsed *url.URL, query url.Values) (LNURLParams, error)

func HandleChannel

func HandleChannel(raw []byte) (LNURLParams, error)

func HandleFastWithdraw

func HandleFastWithdraw(query url.Values) (LNURLParams, bool)

func HandleWithdraw

func HandleWithdraw(raw []byte) (LNURLParams, error)

type LNURLPayParams

type LNURLPayParams struct {
	LNURLResponse
	Callback        string         `json:"callback"`
	Tag             string         `json:"tag"`
	MaxSendable     int64          `json:"maxSendable"`
	MinSendable     int64          `json:"minSendable"`
	EncodedMetadata string         `json:"metadata"`
	CommentAllowed  int64          `json:"commentAllowed"`
	PayerData       *PayerDataSpec `json:"payerData,omitempty"`

	Metadata Metadata `json:"-"`
}

func (LNURLPayParams) CallbackURL

func (params LNURLPayParams) CallbackURL() *url.URL

func (LNURLPayParams) LNURLKind

func (LNURLPayParams) LNURLKind() string

func (LNURLPayParams) MetadataEncoded

func (params LNURLPayParams) MetadataEncoded() string

func (*LNURLPayParams) Normalize

func (params *LNURLPayParams) Normalize() error

type LNURLPayValues

type LNURLPayValues struct {
	LNURLResponse
	SuccessAction *SuccessAction `json:"successAction"`
	Routes        interface{}    `json:"routes"` // ignored
	PR            string         `json:"pr"`
	Disposable    *bool          `json:"disposable,omitempty"`

	ParsedInvoice decodepay.Bolt11 `json:"-"`
	PayerDataJSON string           `json:"-"`
}

type LNURLResponse

type LNURLResponse struct {
	Status string `json:"status,omitempty"`
	Reason string `json:"reason,omitempty"`
}

The base response for all lnurl calls.

func OkResponse

func OkResponse() LNURLResponse

type LNURLWithdrawResponse

type LNURLWithdrawResponse struct {
	LNURLResponse
	Tag                string   `json:"tag"`
	K1                 string   `json:"k1"`
	Callback           string   `json:"callback"`
	CallbackURL        *url.URL `json:"-"`
	MaxWithdrawable    int64    `json:"maxWithdrawable"`
	MinWithdrawable    int64    `json:"minWithdrawable"`
	DefaultDescription string   `json:"defaultDescription"`
	BalanceCheck       string   `json:"balanceCheck,omitempty"`
	PayLink            string   `json:"payLink,omitempty"`
}

func (LNURLWithdrawResponse) LNURLKind

func (_ LNURLWithdrawResponse) LNURLKind() string

type Metadata

type Metadata struct {
	Description     string
	LongDescription string
	Image           struct {
		DataURI string
		Bytes   []byte
		Ext     string
	}
	LightningAddress string
	IsEmail          bool
}

func (Metadata) Encode

func (metadata Metadata) Encode() string

type Option

type Option func(*LNURLClient)

Option configures an LNURLClient.

func WithAllowedHosts

func WithAllowedHosts(hosts ...string) Option

WithAllowedHosts exempts the given hostnames from the private/reserved IP check performed by the SSRF-safe transport built by New. Use it only for hosts you control that legitimately resolve to internal addresses (e.g. a test lightning address server running in-cluster), and never in production. Matching is case-insensitive on the hostname only, port excluded.

func WithLogger

func WithLogger(handler slog.Handler) Option

WithLogger sets a custom slog handler for the client. By default slog.Default() is used.

type PayerDataItemSpec

type PayerDataItemSpec struct {
	Mandatory bool `json:"mandatory"`
}

type PayerDataKeyAuthSpec

type PayerDataKeyAuthSpec struct {
	Mandatory bool   `json:"mandatory"`
	K1        string `json:"k1"`
}

type PayerDataKeyAuthValues

type PayerDataKeyAuthValues struct {
	K1  string `json:"k1"`
	Sig string `json:"sig"`
	Key string `json:"key"`
}

type PayerDataSpec

type PayerDataSpec struct {
	FreeName         *PayerDataItemSpec    `json:"name"`
	PubKey           *PayerDataItemSpec    `json:"pubkey"`
	LightningAddress *PayerDataItemSpec    `json:"identifier"`
	Email            *PayerDataItemSpec    `json:"email"`
	KeyAuth          *PayerDataKeyAuthSpec `json:"auth"`
}

func (PayerDataSpec) Exists

func (s PayerDataSpec) Exists() bool

type PayerDataValues

type PayerDataValues struct {
	FreeName         string                  `json:"name,omitempty"`
	PubKey           string                  `json:"pubkey,omitempty"`
	LightningAddress string                  `json:"identifier,omitempty"`
	Email            string                  `json:"email,omitempty"`
	KeyAuth          *PayerDataKeyAuthValues `json:"auth,omitempty"`
}

type SuccessAction

type SuccessAction struct {
	Tag         string `json:"tag"`
	Description string `json:"description,omitempty"`
	URL         string `json:"url,omitempty"`
	Message     string `json:"message,omitempty"`
	Ciphertext  string `json:"ciphertext,omitempty"`
	IV          string `json:"iv,omitempty"`
}

func AESAction

func AESAction(description string, preimage []byte, content string) (*SuccessAction, error)

func Action

func Action(text string, url string) *SuccessAction

func (*SuccessAction) Decipher

func (sa *SuccessAction) Decipher(preimage []byte) (content string, err error)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL