Parsing inputs
The SDK provides a versatile and extensible parsing module designed to process a wide range of input strings and return parsed data in various standardized formats.
Natively supported formats include: BOLT11 invoices, BOLT12 offers, LNURLs of different types, Bitcoin addresses, and others. For the complete list, consult the API documentation.
let input = "an input to be parsed...";
match sdk.parse(input).await? {
InputType::BitcoinAddress { address } => {
println!("Input is Bitcoin address {}", address.address);
}
InputType::Bolt11 { invoice } => {
println!(
"Input is BOLT11 invoice for {} msats",
invoice
.amount_msat
.map_or("unknown".to_string(), |a| a.to_string())
);
}
InputType::LnUrlPay { data } => {
println!(
"Input is LNURL-Pay/Lightning address accepting min/max {}/{} msats",
data.min_sendable, data.max_sendable
);
}
InputType::LnUrlWithdraw { data } => {
println!(
"Input is LNURL-Withdraw for min/max {}/{} msats",
data.min_withdrawable, data.max_withdrawable
);
}
// Other input types are available
_ => {}
}
let input = "an input to be parsed..."
do {
let inputType = try sdk.parse(input: input)
switch inputType {
case .bitcoinAddress(let address):
print("Input is Bitcoin address \(address.address)")
case .bolt11(let invoice):
let amount = invoice.amountMsat.map { String($0) } ?? "unknown"
print("Input is BOLT11 invoice for \(amount) msats")
case .lnUrlPay(let data):
print("Input is LNURL-Pay/Lightning address accepting min/max \(data.minSendable)/\(data.maxSendable) msats")
case .lnUrlWithdraw(let data):
print("Input is LNURL-Withdraw for min/max \(data.minWithdrawable)/\(data.maxWithdrawable) msats")
default:
break // Other input types are available
}
} catch {
print("Failed to parse input: \(error)")
}
val input = "an input to be parsed..."
try {
val inputType = sdk.parse(input)
when (inputType) {
is InputType.BitcoinAddress -> {
println("Input is Bitcoin address ${inputType.address.address}")
}
is InputType.Bolt11 -> {
val amountStr = inputType.invoice.amountMsat?.toString() ?: "unknown"
println("Input is BOLT11 invoice for $amountStr msats")
}
is InputType.LnUrlPay -> {
println("Input is LNURL-Pay/Lightning address accepting min/max " +
"${inputType.data.minSendable}/${inputType.data.maxSendable} msats")
}
is InputType.LnUrlWithdraw -> {
println("Input is LNURL-Withdraw for min/max " +
"${inputType.data.minWithdrawable}/${inputType.data.maxWithdrawable} msats")
}
else -> {
// Handle other input types
}
}
} catch (e: Exception) {
// handle error
}
const input = 'an input to be parsed...'
const parsed = await parse(input)
switch (parsed.type) {
case InputTypeVariant.BITCOIN_ADDRESS:
console.log(`Input is Bitcoin address ${parsed.address.address}`)
break
case InputTypeVariant.BOLT11:
console.log(
`Input is BOLT11 invoice for ${
parsed.invoice.amountMsat != null
? parsed.invoice.amountMsat.toString()
: 'unknown'
} msats`
)
break
case InputTypeVariant.LN_URL_PAY:
console.log(
`Input is LNURL-Pay/Lightning address accepting min/max ${parsed.data.minSendable}/${parsed.data.maxSendable} msats`
)
break
case InputTypeVariant.LN_URL_WITHDRAW:
console.log(
`Input is LNURL-Withdraw for min/max ${parsed.data.minWithdrawable}/${parsed.data.maxWithdrawable} msats`
)
break
default:
// Other input types are available
break
}
String input = "an input to be parsed...";
InputType inputType = await breezSDKLiquid.instance!.parse(input: input);
if (inputType is InputType_BitcoinAddress) {
print("Input is Bitcoin address ${inputType.address.address}");
} else if (inputType is InputType_Bolt11) {
String amountStr = inputType.invoice.amountMsat != null
? inputType.invoice.amountMsat.toString()
: "unknown";
print("Input is BOLT11 invoice for $amountStr msats");
} else if (inputType is InputType_LnUrlPay) {
print(
"Input is LNURL-Pay/Lightning address accepting min/max ${inputType.data.minSendable}/${inputType.data.maxSendable} msats");
} else if (inputType is InputType_LnUrlWithdraw) {
print(
"Input is LNURL-Withdraw for min/max ${inputType.data.minWithdrawable}/${inputType.data.maxWithdrawable} msats");
} else {
// Other input types are available
}
input = "an input to be parsed..."
try:
parsed_input = sdk.parse(input)
if parsed_input.type == InputType.BITCOIN_ADDRESS:
logging.debug(f"Input is Bitcoin address {parsed_input.address.address}")
elif parsed_input.type == InputType.BOLT11:
amount = "unknown"
if parsed_input.invoice.amount_msat:
amount = str(parsed_input.invoice.amount_msat)
logging.debug(f"Input is BOLT11 invoice for {amount} msats")
elif parsed_input.type == InputType.LN_URL_PAY:
logging.debug(f"Input is LNURL-Pay/Lightning address accepting min/max {parsed_input.data.min_sendable}/{parsed_input.data.max_sendable} msats")
elif parsed_input.type == InputType.LN_URL_WITHDRAW:
logging.debug(f"Input is LNURL-Withdraw for min/max {parsed_input.data.min_withdrawable}/{parsed_input.data.max_withdrawable} msats")
# Other input types are available
except Exception as error:
logging.error(error)
raise
input := "an input to be parsed..."
if input, err := sdk.Parse(input); err == nil {
switch inputType := input.(type) {
case breez_sdk_liquid.InputTypeBitcoinAddress:
log.Printf("Input is Bitcoin address %s", inputType.Address.Address)
case breez_sdk_liquid.InputTypeBolt11:
amount := "unknown"
if inputType.Invoice.AmountMsat != nil {
amount = strconv.FormatUint(*inputType.Invoice.AmountMsat, 10)
}
log.Printf("Input is BOLT11 invoice for %s msats", amount)
case breez_sdk_liquid.InputTypeLnUrlPay:
log.Printf("Input is LNURL-Pay/Lightning address accepting min/max %d/%d msats",
inputType.Data.MinSendable, inputType.Data.MaxSendable)
case breez_sdk_liquid.InputTypeLnUrlWithdraw:
log.Printf("Input is LNURL-Withdraw for min/max %d/%d msats",
inputType.Data.MinWithdrawable, inputType.Data.MaxWithdrawable)
default:
// Other input types are available
}
}
var input = "an input to be parsed...";
try
{
var parsed = sdk.Parse(input);
switch (parsed)
{
case InputType.BitcoinAddress bitcoinAddress:
Console.WriteLine($"Input is Bitcoin address {bitcoinAddress.address}");
break;
case InputType.Bolt11 bolt11:
var amount = bolt11.invoice.amountMsat.HasValue
? bolt11.invoice.amountMsat.Value.ToString()
: "unknown";
Console.WriteLine($"Input is BOLT11 invoice for {amount} msats");
break;
case InputType.LnUrlPay lnUrlPay:
Console.WriteLine(
$"Input is LNURL-Pay/Lightning address accepting min/max {lnUrlPay.data.minSendable}/{lnUrlPay.data.maxSendable} msats"
);
break;
case InputType.LnUrlWithdraw lnUrlWithdraw:
Console.WriteLine(
$"Input is LNURL-Withdraw for min/max {lnUrlWithdraw.data.minWithdrawable}/{lnUrlWithdraw.data.maxWithdrawable} msats"
);
break;
default:
// Other input types are available
break;
}
}
catch (Exception)
{
// Handle error
}
Supporting other input formats
The parsing module can be extended using external input parsers provided in the SDK configuration. These will be used when the input is not recognized.
You can implement and provide your own parsers, or use existing public ones.
Configuring external parsers
Configuring external parsers can only be done before connecting and the config cannot be changed through the lifetime of the connection.
Multiple parsers can be configured, and each one is defined by:
- Provider ID: an arbitrary id to identify the provider input type
- Input regex: a regex pattern that should reliably match all inputs that this parser can process, even if it may also match some invalid inputs
- Parser URL: a URL containing the placeholder
<input>
When parsing an input that isn't recognized as one of the native input types, the SDK will check if the input conforms to any of the external parsers regex expressions. If so, it will make an HTTP GET
request to the provided URL, replacing the placeholder with the input. If the input is recognized, the response should include in its body a string that can be parsed into one of the natively supported types.
let mnemonic = Mnemonic::generate_in(Language::English, 12)?;
// Create the default config, providing your Breez API key
let mut config = LiquidSdk::default_config(
LiquidNetwork::Mainnet,
Some("<your-Breez-API-key>".to_string()),
)?;
// Configure external parsers
config.external_input_parsers = Some(vec![
ExternalInputParser {
provider_id: "provider_a".to_string(),
input_regex: "^provider_a".to_string(),
parser_url: "https://parser-domain.com/parser?input=<input>".to_string(),
},
ExternalInputParser {
provider_id: "provider_b".to_string(),
input_regex: "^provider_b".to_string(),
parser_url: "https://parser-domain.com/parser?input=<input>".to_string(),
},
]);
let connect_request = ConnectRequest {
mnemonic: mnemonic.to_string(),
config,
};
let sdk = LiquidSdk::connect(connect_request).await?;
let mnemonic = "<mnemonic words>"
// Create the default config, providing your Breez API key
var config = try defaultConfig(network: LiquidNetwork.mainnet, breezApiKey: "<your-Breez-API-key>")
// Configure external parsers
config.externalInputParsers = [
ExternalInputParser(
providerId: "provider_a",
inputRegex: "^provider_a",
parserUrl: "https://parser-domain.com/parser?input=<input>"
),
ExternalInputParser(
providerId: "provider_b",
inputRegex: "^provider_b",
parserUrl: "https://parser-domain.com/parser?input=<input>"
)
]
let connectRequest = ConnectRequest(config: config, mnemonic: mnemonic)
let sdk = try? connect(req: connectRequest)
val mnemonic = "<mnemonic words>"
// Create the default config, providing your Breez API key
val config : Config = defaultConfig(LiquidNetwork.MAINNET, "<your Breez API key>")
// Configure external parsers
config.externalInputParsers = listOf(
ExternalInputParser(
providerId = "provider_a",
inputRegex = "^provider_a",
parserUrl = "https://parser-domain.com/parser?input=<input>"
),
ExternalInputParser(
providerId = "provider_b",
inputRegex = "^provider_b",
parserUrl = "https://parser-domain.com/parser?input=<input>"
)
)
try {
val connectRequest = ConnectRequest(config, mnemonic)
val sdk = connect(connectRequest)
} catch (e: Exception) {
// handle error
}
const mnemonic = '<mnemonics words>'
// Create the default config, providing your Breez API key
const config = await defaultConfig(
LiquidNetwork.MAINNET,
'<your-Breez-API-key>'
)
// Configure external parsers
config.externalInputParsers = [
{
providerId: 'provider_a',
inputRegex: '^provider_a',
parserUrl: 'https://parser-domain.com/parser?input=<input>'
},
{
providerId: 'provider_b',
inputRegex: '^provider_b',
parserUrl: 'https://parser-domain.com/parser?input=<input>'
}
]
await connect({ mnemonic, config })
// Create the default config
String mnemonic = "<mnemonic words>";
// Create the default config, providing your Breez API key
Config config = defaultConfig(
network: LiquidNetwork.mainnet,
breezApiKey: "<your-Breez-API-key>"
);
// Configure external parsers
config = config.copyWith(
externalInputParsers: [
ExternalInputParser(
providerId: "provider_a",
inputRegex: "^provider_a",
parserUrl: "https://parser-domain.com/parser?input=<input>",
),
ExternalInputParser(
providerId: "provider_b",
inputRegex: "^provider_b",
parserUrl: "https://parser-domain.com/parser?input=<input>",
),
],
);
ConnectRequest connectRequest = ConnectRequest(mnemonic: mnemonic, config: config);
await breezSDKLiquid.connect(req: connectRequest);
mnemonic = "<mnemonic words>"
# Create the default config, providing your Breez API key
config = default_config(network=LiquidNetwork.MAINNET, breez_api_key="<your-Breez-API-key>")
# Configure external parsers
config.external_input_parsers = [
ExternalInputParser(
provider_id="provider_a",
input_regex="^provider_a",
parser_url="https://parser-domain.com/parser?input=<input>"
),
ExternalInputParser(
provider_id="provider_b",
input_regex="^provider_b",
parser_url="https://parser-domain.com/parser?input=<input>"
)
]
try:
connect_request = ConnectRequest(config, mnemonic)
sdk = connect(connect_request)
return sdk
except Exception as error:
logging.error(error)
raise
mnemonic := "<mnemonic words>"
// Create the default config, providing your Breez API key
breezApiKey := "<your-Breez-API-key>"
config, err := breez_sdk_liquid.DefaultConfig(breez_sdk_liquid.LiquidNetworkMainnet, &breezApiKey)
if err != nil {
return nil, err
}
// Configure external parsers
parsers := []breez_sdk_liquid.ExternalInputParser{
{
ProviderId: "provider_a",
InputRegex: "^provider_a",
ParserUrl: "https://parser-domain.com/parser?input=<input>",
},
{
ProviderId: "provider_b",
InputRegex: "^provider_b",
ParserUrl: "https://parser-domain.com/parser?input=<input>",
},
}
config.ExternalInputParsers = &parsers
connectRequest := breez_sdk_liquid.ConnectRequest{
Config: config,
Mnemonic: mnemonic,
}
sdk, err := breez_sdk_liquid.Connect(connectRequest)
return sdk, err
var mnemonic = "<mnemonic words>";
// Create the default config, providing your Breez API key
var config = BreezSdkLiquidMethods.DefaultConfig(
LiquidNetwork.Mainnet,
"<your-Breez-API-key>"
) with
{
// Configure external parsers
externalInputParsers = new List<ExternalInputParser>
{
new(
providerId: "provider_a",
inputRegex: "^provider_a",
parserUrl: "https://parser-domain.com/parser?input=<input>"
),
new(
providerId: "provider_b",
inputRegex: "^provider_b",
parserUrl: "https://parser-domain.com/parser?input=<input>"
)
}
};
try
{
var connectRequest = new ConnectRequest(config, mnemonic);
var sdk = BreezSdkLiquidMethods.Connect(connectRequest);
}
catch (Exception)
{
// Handle error
}
Public external parsers
- PicknPay QRs
- Maintainer: MoneyBadger
- Regex:
(.*)(za.co.electrum.picknpay)(.*)
- URL:
https://staging.cryptoqr.net/.well-known/lnurlp/<input>
Default external parsers
The SDK ships with some embedded default external parsers. If you prefer not to use them, you can disable them in the SDK's configuration. See the available default parsers in the API Documentation by checking the source of the constant.