From 385b9225e7974a052241ba18ea86fd02c5747834 Mon Sep 17 00:00:00 2001 From: Titusz Pan Date: Sat, 11 Feb 2023 15:22:42 +0100 Subject: [PATCH 01/10] DRAFT - LUD-XX: pinLimit for withdrawRequest --- xx.md | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 xx.md diff --git a/xx.md b/xx.md new file mode 100644 index 0000000..1a55492 --- /dev/null +++ b/xx.md @@ -0,0 +1,51 @@ +LUD-XX: pinLimit for withdrawRequest +==================================== + +`author: titusz` `discussion: https://t.me/lnurl/34810` + +--- + +## Optional Second Factor for `withdrawRequest` Authorization + +Adding the optional `pinLimit` property to an LNURL-withdraw response allows a `SERVICE` to require a PIN to authorize a withdrawal above a given amount. + +```diff +{ + "tag": "withdrawRequest", + "callback": string, + "defaultDescription": string, + "minWithdrawable": number, + "maxWithdrawable": number, ++ "pinLimit": number +} +``` + +The `pinLimit` value must be a positive integer (including 0) with a maximum of 15 digits. If the `pinLimit` property is present and a `WALLET` (Point of Sale) intends to withdraw an amount equal to or greater than the `pinLimit` value (in millisatoshis) it must first acquire a PIN from the user (customer) and then add it as `pin=` to the query string of the callback URL to authorize the withdrawal. + +**Example callback:** + +`https:/ln-example.com?k1=&pr=&pin=` + +If the `pinLimit` property is used, the `SERVICE` must check for and validate the `pin` query parameter of the callback request according to its policy before paying the invoice. + +## Wallet Implementation Notes + +If an LNURL-withdraw response includes a `pinLimit` property a `WALLET` should not automatically propose the invoice amount based on the `minWithdrawable`, `maxWithdrawable` or `pinLimit` values. + +When acquiring a PIN from the user (customer) via a PIN entry screen a `WALLET` should show the invoice amount on that same screen. + +## Service Implementation Notes + +Other than the maximum length of 15 digits this document makes no assumptions about whether PINs are static (multiple-use) or one-time passwords (OTPs) or other PIN security schemes. + +A `SERVICE` may add the `pinLimit` property to its LNURL-withdraw response in accordance with its individual security policy. + +A `SERVICE` should protect against brute force attacks by invalidating LNURLw links after the first PIN authorization failure. + +## Security Considerations + +PIN support improves security in cases of lost or maliciously scanned NFC payment devices. + +Implementors should be aware that the PIN is leaked to the merchant point of sales device when entered by the customer. + +Depending on the implementation of a `SERVICE`, security can be improved by using one-time PINs or by appropriate privacy configuration of NFC payment devices (e.g., enabling Random-ID support). From 13b6446321e04a56b1eac7acdbc341dc545a7d95 Mon Sep 17 00:00:00 2001 From: Titusz Pan Date: Thu, 3 Aug 2023 11:48:06 +0200 Subject: [PATCH 02/10] Rename to LUD-21 --- xx.md => 21.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename xx.md => 21.md (98%) diff --git a/xx.md b/21.md similarity index 98% rename from xx.md rename to 21.md index 1a55492..f9ff8ce 100644 --- a/xx.md +++ b/21.md @@ -1,4 +1,4 @@ -LUD-XX: pinLimit for withdrawRequest +LUD-21: pinLimit for withdrawRequest ==================================== `author: titusz` `discussion: https://t.me/lnurl/34810` From 6882ab838e9b08d752b5f2dd5d25af5f43d77c81 Mon Sep 17 00:00:00 2001 From: Peter Rounce Date: Thu, 3 Aug 2023 12:13:44 +0100 Subject: [PATCH 03/10] add Bolt Card Wallet & Bolt Card PoS add Bolt Card Wallet & Bolt Card PoS with support for PIN LUD --- README.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index c84c67d..4385f67 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ These are all the individual documents describing each small piece of protocol t |----------|-------------------------------------------------------------|---------| | [01][01] | Base LNURL encoding and decoding. | _all the ones listed below_ | | [02][02] | `channelRequest` base spec. | [Balance of Satoshis][bos], [BitBanana][bitbanana], [Blixt][blixt], [Breez][breez], [cliché][cliche], [OBW][obw], [Zap Android][zap], [Zap Desktop][zap], [Zeus][zeus] | -| [03][03] | `withdrawRequest` base spec. | [Alby][alby], [Balance of Satoshis][bos], [BitBanana][bitbanana], [Blixt][blixt], [BlueWallet][bluewallet], [Breez][breez], [Clams][clams], [CoinCorner][coincorner], [coinos][coinos], [Fountain][fountain], [LifPay][lifpay], [LNbits][lnbits], [LightningTipBot][ltb], [Muun][muun], [Phoenix][phoenix], [Pouch.ph][pouchph], [ShockWallet][shockwallet], [OBW][obw], [ThunderHub][thunderhub], [Wallet of Satoshi][wos], [Zap Android][zap], [Zap Desktop][zap], [Zap iOS][zap], [ZBD Discord][zbd], [ZBD Extension][zbd], [ZBD Telegram][zbd], [ZEBEDEE][zbd], [Zeus][zeus] | +| [03][03] | `withdrawRequest` base spec. | [Alby][alby], [Balance of Satoshis][bos], [BitBanana][bitbanana], [Blixt][blixt], [BlueWallet][bluewallet], [Bolt Card Wallet][boltcardwallet], [Breez][breez], [Clams][clams], [CoinCorner][coincorner], [coinos][coinos], [Fountain][fountain], [LifPay][lifpay], [LNbits][lnbits], [LightningTipBot][ltb], [Muun][muun], [Phoenix][phoenix], [Pouch.ph][pouchph], [ShockWallet][shockwallet], [OBW][obw], [ThunderHub][thunderhub], [Wallet of Satoshi][wos], [Zap Android][zap], [Zap Desktop][zap], [Zap iOS][zap], [ZBD Discord][zbd], [ZBD Extension][zbd], [ZBD Telegram][zbd], [ZEBEDEE][zbd], [Zeus][zeus] | | [04][04] | Auth base spec. | [Alby][alby], [Balance of Satoshis][bos], [Blixt][blixt], [Breez][breez], [BlueWallet][bluewallet], [Clams][clams], [coinos][coinos], [Geyser][geyser], [LifPay][lifpay], [LNbits][lnbits], [LightningTipBot][ltb], [Phoenix][phoenix], [SeedAuth][seedauth], [SeedAuthExtension][sae], [OBW][obw], [Sparrow Wallet][sparrow], [ThunderHub][thunderhub], [Zap Desktop][zap], [Zeus][zeus] | | [05][05] | BIP32-based seed generation for auth protocol. | [Alby][alby], [coinos][coinos], [OBW][obw], [Phoenix][phoenix] | | [06][06] | `payRequest` base spec. | [Alby][alby], [Balance of Satoshis][bos], [BitBanana][bitbanana], [Blixt][blixt], [BlueWallet][bluewallet], [Breez][breez], [BTCPayServer][btcp], [Clams][clams], [cliché][cliche], [CoinCorner][coincorner], [coinos][coinos], [Electrum][electrum], [Fountain][fountain], [Galoy][galoy], [Geyser][geyser], [LifPay][lifpay], [LNbits][lnbits], [LNLink][lnlink], [LNPay.co][lnpay], [LightningTipBot][ltb], [Machankura][machankura], [Phoenix][phoenix], [Pouch.ph][pouchph], [ShockWallet][shockwallet], [OBW][obw], [ThunderHub][thunderhub], [Wallet of Satoshi][wos], [Zap Android][zap], [ZBD Discord][zbd], [ZBD Extension][zbd], [ZBD Telegram][zbd], [ZEBEDEE][zbd], [Zeus][zeus] | @@ -21,13 +21,15 @@ These are all the individual documents describing each small piece of protocol t | [14][14] | `balanceCheck`: reusable `withdrawRequest`s. | [Alby][alby], [Blixt][blixt], [LNbits][lnbits], | | [15][15] | `balanceNotify`: services hurrying up the withdraw process. | [LNbits][lnbits] | | [16][16] | Paying to static internet identifiers. | [Alby][alby], [Balance of Satoshis][bos], [BitBanana][bitbanana], [Blixt][blixt], [BTCPayServer][btcp], [Clams][clams], [cliché][cliche], [CoinCorner][coincorner], [coinos][coinos], [Fountain][fountain], [LifPay][lifpay], [LNbits][lnbits], [LNLink][lnlink], [LightningTipBot][ltb], [Machankura][machankura], [Phoenix][phoenix], [Pouch.ph][pouchph], [OBW][obw], [Zap Android][zap], [ZBD Discord][zbd], [ZBD Extension][zbd], [ZBD Telegram][zbd], [ZEBEDEE][zbd], [Zeus][zeus] | -| [17][17] | Scheme prefixes and raw (non bech32-encoded) URLs. | [Alby][alby], [BitBanana][bitbanana], [Blixt][blixt], [BTCPayServer][btcp], [Clams][clams], [cliché][cliche], [CoinCorner][coincorner], [ZBD Discord][zbd], [ZBD Telegram][zbd] | [Wallet of Satoshi][wos] | +| [17][17] | Scheme prefixes and raw (non bech32-encoded) URLs. | [Alby][alby], [BitBanana][bitbanana], [Blixt][blixt], [Bolt Card Wallet][boltcardwallet], [BTCPayServer][btcp], [Clams][clams], [cliché][cliche], [CoinCorner][coincorner], [ZBD Discord][zbd], [ZBD Telegram][zbd] | [Wallet of Satoshi][wos] | | [18][18] | Payer identity in `payRequest` protocol. | [Alby][alby], [BitBanana][bitbanana], [Blixt][blixt], [cliché][cliche], [OBW][obw], [ZBD Discord][zbd], [ZBD Telegram][zbd] | | [19][19] | Pay link discoverable from withdraw link. | [Blixt][blixt], [CoinCorner][coincorner], [OBW][obw] | | [20][20] | Long payment description for pay protocol. | [Alby][alby], [BitBanana][bitbanana], [Blixt][blixt], [Clams][clams], [cliché][cliche], [Phoenix][phoenix] | +| [21][21] | pinLimit for withdrawRequest | [Bolt Card Wallet][boltcardwallet] | [alby]: https://github.com/getAlby/lightning-browser-extension [bitbanana]: https://bitbanana.app +[boltcardwallet]: https://boltcardwallet.com [bos]: https://github.com/alexbosworth/balanceofsatoshis [blixt]: https://blixtwallet.github.io [bluewallet]: https://bluewallet.io @@ -74,6 +76,9 @@ Services | [Bitcoin Bounce](https://thndr.games/) | [01][01] [03][03] [08][08] | | [Bitrefill](https://bitrefill.com/) | [01][01] [02][02] [06][06] [16][16] | | [Blocktank](https://synonym.to/blocktank/) | [01][01] [02][02] | +| [Bolt Card PoS](https://github.com/boltcard/bolt-card-pos) | [03][03] [17][17] [19][19] | +| [Bolt Card Wallet](https://boltcardwallet.com) | [03][03] [17][17] [19][19] | +| [Blocktank](https://synonym.to/blocktank/) | [01][01] [02][02] | | [Bull Bitcoin](https://www.bullbitcoin.com/) | [01][01] [03][03] | | [CoinCorner](https://www.coincorner.com) | [01][01] [03][03] [06][06] [16][16] [17][17] [19][19] | | [Fountain Podcasts](https://fountain.fm) | [01][01] [03][03] [06][06] [09][09] [12][12] [16][16] | @@ -208,6 +213,7 @@ Tools for developers [18]: 18.md [19]: 19.md [20]: 20.md +[21]: 21.md Dependency Tree --------------- From c8fd4894e083a24a85c3d216f1d023f4b0b9f598 Mon Sep 17 00:00:00 2001 From: Titusz Pan Date: Mon, 7 Aug 2023 19:55:26 +0200 Subject: [PATCH 04/10] Reduce max pin length to 8 --- 21.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/21.md b/21.md index f9ff8ce..8a3f707 100644 --- a/21.md +++ b/21.md @@ -36,7 +36,7 @@ When acquiring a PIN from the user (customer) via a PIN entry screen a `WALLET` ## Service Implementation Notes -Other than the maximum length of 15 digits this document makes no assumptions about whether PINs are static (multiple-use) or one-time passwords (OTPs) or other PIN security schemes. +Other than a maximum length of 8 digits this document makes no assumptions about whether PINs are static (multiple-use) or one-time passwords (OTPs) or other digit based PIN security schemes. A `SERVICE` may add the `pinLimit` property to its LNURL-withdraw response in accordance with its individual security policy. From fc80d88e6403e4a5abad0a7861a2e14633da1914 Mon Sep 17 00:00:00 2001 From: Titusz Pan Date: Mon, 7 Aug 2023 19:57:09 +0200 Subject: [PATCH 05/10] Invalidate LNURLw links after 3 failures --- 21.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/21.md b/21.md index 8a3f707..514f9b1 100644 --- a/21.md +++ b/21.md @@ -40,7 +40,7 @@ Other than a maximum length of 8 digits this document makes no assumptions about A `SERVICE` may add the `pinLimit` property to its LNURL-withdraw response in accordance with its individual security policy. -A `SERVICE` should protect against brute force attacks by invalidating LNURLw links after the first PIN authorization failure. +A `SERVICE` should protect against brute force attacks by invalidating LNURLw links after the third PIN authorization failure. ## Security Considerations From deee7c49c0aa57181ccfaf58c4c570f2656b822d Mon Sep 17 00:00:00 2001 From: Titusz Date: Wed, 9 Aug 2023 13:09:03 +0200 Subject: [PATCH 06/10] Add missing forward slash in example callback URL Co-authored-by: Andrei <92177534+andrei-21@users.noreply.github.com> --- 21.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/21.md b/21.md index 514f9b1..4220a48 100644 --- a/21.md +++ b/21.md @@ -24,7 +24,7 @@ The `pinLimit` value must be a positive integer (including 0) with a maximum of **Example callback:** -`https:/ln-example.com?k1=&pr=&pin=` +`https://ln-example.com?k1=&pr=&pin=` If the `pinLimit` property is used, the `SERVICE` must check for and validate the `pin` query parameter of the callback request according to its policy before paying the invoice. From 08f4da82188999432fffd2925e0dcc62350617ce Mon Sep 17 00:00:00 2001 From: Titusz Date: Wed, 9 Aug 2023 13:20:28 +0200 Subject: [PATCH 07/10] Re-order LNURLw response fields in example. Co-authored-by: Andrei <92177534+andrei-21@users.noreply.github.com> --- 21.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/21.md b/21.md index 4220a48..6465da4 100644 --- a/21.md +++ b/21.md @@ -14,9 +14,9 @@ Adding the optional `pinLimit` property to an LNURL-withdraw response allows a ` "tag": "withdrawRequest", "callback": string, "defaultDescription": string, - "minWithdrawable": number, - "maxWithdrawable": number, -+ "pinLimit": number + "minWithdrawable": number, ++ "pinLimit": number, + "maxWithdrawable": number } ``` From 945029d3c745fa669b493dcaa6444c744883da10 Mon Sep 17 00:00:00 2001 From: Titusz Date: Tue, 19 Sep 2023 20:25:31 +0200 Subject: [PATCH 08/10] Add Bolt Card Pos as supporting LUD 21 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b8f982d..20c412c 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ These are all the individual documents describing each small piece of protocol t | [18][18] | Payer identity in `payRequest` protocol. | [Alby][alby], [BitBanana][bitbanana], [Blixt][blixt], [cliché][cliche], [OBW][obw], [ZBD Discord][zbd], [ZBD Telegram][zbd] | | [19][19] | Pay link discoverable from withdraw link. | [Blixt][blixt], [CoinCorner][coincorner], [OBW][obw] | | [20][20] | Long payment description for pay protocol. | [Alby][alby], [BitBanana][bitbanana], [Blixt][blixt], [Clams][clams], [cliché][cliche], [Mash][mash], [OneKey][onekey], [Phoenix][phoenix] | -| [21][21] | pinLimit for withdrawRequest | [Bolt Card Wallet][boltcardwallet] | +| [21][21] | pinLimit for withdrawRequest | [Bolt Card Wallet][boltcardwallet], [Bolt Card PoS][boltcardwallet] | [alby]: https://github.com/getAlby/lightning-browser-extension [bitbanana]: https://bitbanana.app From 959dc417c7f444b182e0faff06d27844a662f18a Mon Sep 17 00:00:00 2001 From: Titusz Date: Tue, 19 Sep 2023 20:39:55 +0200 Subject: [PATCH 09/10] Add requirement for a fixed length 6-digit PIN --- 21.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/21.md b/21.md index 6465da4..cc629c9 100644 --- a/21.md +++ b/21.md @@ -20,7 +20,7 @@ Adding the optional `pinLimit` property to an LNURL-withdraw response allows a ` } ``` -The `pinLimit` value must be a positive integer (including 0) with a maximum of 15 digits. If the `pinLimit` property is present and a `WALLET` (Point of Sale) intends to withdraw an amount equal to or greater than the `pinLimit` value (in millisatoshis) it must first acquire a PIN from the user (customer) and then add it as `pin=` to the query string of the callback URL to authorize the withdrawal. +The `pinLimit` value must be a positive integer (including 0) with a maximum of 15 digits. If the `pinLimit` property is present and a `WALLET` (Point of Sale) intends to withdraw an amount equal to or greater than the `pinLimit` value (in millisatoshis) it must first acquire a 6-digit PIN from the user (customer) and then add it as `pin=` to the query string of the callback URL to authorize the withdrawal. **Example callback:** @@ -32,11 +32,11 @@ If the `pinLimit` property is used, the `SERVICE` must check for and validate th If an LNURL-withdraw response includes a `pinLimit` property a `WALLET` should not automatically propose the invoice amount based on the `minWithdrawable`, `maxWithdrawable` or `pinLimit` values. -When acquiring a PIN from the user (customer) via a PIN entry screen a `WALLET` should show the invoice amount on that same screen. +When acquiring a 6-digit PIN from the user (customer) via a PIN entry screen a `WALLET` should show the invoice amount on that same screen. ## Service Implementation Notes -Other than a maximum length of 8 digits this document makes no assumptions about whether PINs are static (multiple-use) or one-time passwords (OTPs) or other digit based PIN security schemes. +Other than a fixed length of 6 digits this document makes no assumptions about whether PINs are static (multiple-use) or one-time passwords (OTPs) or other 6-digit based PIN security schemes. A `SERVICE` may add the `pinLimit` property to its LNURL-withdraw response in accordance with its individual security policy. From 1925de1c42122aae479e7fdc8c4c7098d6425c36 Mon Sep 17 00:00:00 2001 From: Titusz Date: Thu, 21 Sep 2023 17:57:12 +0200 Subject: [PATCH 10/10] Change PIN length to 4-digits fixed size --- 21.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/21.md b/21.md index cc629c9..80ae070 100644 --- a/21.md +++ b/21.md @@ -20,7 +20,7 @@ Adding the optional `pinLimit` property to an LNURL-withdraw response allows a ` } ``` -The `pinLimit` value must be a positive integer (including 0) with a maximum of 15 digits. If the `pinLimit` property is present and a `WALLET` (Point of Sale) intends to withdraw an amount equal to or greater than the `pinLimit` value (in millisatoshis) it must first acquire a 6-digit PIN from the user (customer) and then add it as `pin=` to the query string of the callback URL to authorize the withdrawal. +The `pinLimit` value must be a positive integer (including 0) with a maximum of 15 digits. If the `pinLimit` property is present and a `WALLET` (Point of Sale) intends to withdraw an amount equal to or greater than the `pinLimit` value (in millisatoshis) it must first acquire a 4-digit PIN from the user (customer) and then add it as `pin=` to the query string of the callback URL to authorize the withdrawal. **Example callback:** @@ -32,11 +32,11 @@ If the `pinLimit` property is used, the `SERVICE` must check for and validate th If an LNURL-withdraw response includes a `pinLimit` property a `WALLET` should not automatically propose the invoice amount based on the `minWithdrawable`, `maxWithdrawable` or `pinLimit` values. -When acquiring a 6-digit PIN from the user (customer) via a PIN entry screen a `WALLET` should show the invoice amount on that same screen. +When acquiring a 4-digit PIN from the user (customer) via a PIN entry screen a `WALLET` should show the invoice amount on that same screen. ## Service Implementation Notes -Other than a fixed length of 6 digits this document makes no assumptions about whether PINs are static (multiple-use) or one-time passwords (OTPs) or other 6-digit based PIN security schemes. +Other than a fixed length of 4 digits this document makes no assumptions about whether PINs are static (multiple-use) or one-time passwords (OTPs) or other PIN security schemes. A `SERVICE` may add the `pinLimit` property to its LNURL-withdraw response in accordance with its individual security policy.