Enable WebLN wallet on 'webln:enabled' (#1385)

* Enable WebLN wallet on 'webln:enabled'

* Optimistically use WebLN for login with lightning

* Don't scope WebLN config to user

* Rename var to wallet
This commit is contained in:
ekzyis 2024-09-10 18:13:39 +02:00 committed by GitHub
parent f0e49c160a
commit ec5241ad29
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 70 additions and 23 deletions

View File

@ -27,6 +27,18 @@ function QrAuth ({ k1, encodedUrl, callbackUrl }) {
} }
}, [data?.lnAuth]) }, [data?.lnAuth])
useEffect(() => {
if (typeof window.webln === 'undefined') return
// optimistically use WebLN for authentication
async function effect () {
// this will also enable our WebLN wallet
await window.webln.enable()
await window.webln.lnurl(encodedUrl)
}
effect()
}, [encodedUrl])
// output pubkey and k1 // output pubkey and k1
return ( return (
<Qr value={encodedUrl} status='waiting for you' /> <Qr value={encodedUrl} status='waiting for you' />

View File

@ -17,6 +17,9 @@
"@/components/*": [ "@/components/*": [
"components/*" "components/*"
], ],
"@/wallets/*": [
"wallets/*"
],
"@/styles/*": [ "@/styles/*": [
"styles/*" "styles/*"
], ],

View File

@ -21,6 +21,7 @@ import { WalletLoggerProvider } from '@/components/wallet-logger'
import { ChainFeeProvider } from '@/components/chain-fee.js' import { ChainFeeProvider } from '@/components/chain-fee.js'
import dynamic from 'next/dynamic' import dynamic from 'next/dynamic'
import { HasNewNotesProvider } from '@/components/use-has-new-notes' import { HasNewNotesProvider } from '@/components/use-has-new-notes'
import WebLnProvider from '@/wallets/webln'
const PWAPrompt = dynamic(() => import('react-ios-pwa-prompt'), { ssr: false }) const PWAPrompt = dynamic(() => import('react-ios-pwa-prompt'), { ssr: false })
@ -106,6 +107,7 @@ export default function MyApp ({ Component, pageProps: { ...props } }) {
<HasNewNotesProvider> <HasNewNotesProvider>
<LoggerProvider> <LoggerProvider>
<WalletLoggerProvider> <WalletLoggerProvider>
<WebLnProvider>
<ServiceWorkerProvider> <ServiceWorkerProvider>
<PriceProvider price={price}> <PriceProvider price={price}>
<LightningProvider> <LightningProvider>
@ -124,6 +126,7 @@ export default function MyApp ({ Component, pageProps: { ...props } }) {
</LightningProvider> </LightningProvider>
</PriceProvider> </PriceProvider>
</ServiceWorkerProvider> </ServiceWorkerProvider>
</WebLnProvider>
</WalletLoggerProvider> </WalletLoggerProvider>
</LoggerProvider> </LoggerProvider>
</HasNewNotesProvider> </HasNewNotesProvider>

View File

@ -412,24 +412,26 @@ export function useWallets () {
function getStorageKey (name, me) { function getStorageKey (name, me) {
let storageKey = `wallet:${name}` let storageKey = `wallet:${name}`
if (me) {
// WebLN has no credentials we need to scope to users
// so we can use the same storage key for all users
if (me && name !== 'webln') {
storageKey = `${storageKey}:${me.id}` storageKey = `${storageKey}:${me.id}`
} }
return storageKey return storageKey
} }
function enableWallet (name, me) { function enableWallet (name, me) {
const key = getStorageKey(name, me) const key = getStorageKey(name, me)
const config = JSON.parse(window.localStorage.getItem(key)) const config = JSON.parse(window.localStorage.getItem(key)) || {}
if (!config) return
config.enabled = true config.enabled = true
window.localStorage.setItem(key, JSON.stringify(config)) window.localStorage.setItem(key, JSON.stringify(config))
} }
function disableWallet (name, me) { function disableWallet (name, me) {
const key = getStorageKey(name, me) const key = getStorageKey(name, me)
const config = JSON.parse(window.localStorage.getItem(key)) const config = JSON.parse(window.localStorage.getItem(key)) || {}
if (!config) return
config.enabled = false config.enabled = false
window.localStorage.setItem(key, JSON.stringify(config)) window.localStorage.setItem(key, JSON.stringify(config))
} }

View File

@ -1,3 +1,6 @@
import { useEffect } from 'react'
import { useWallet } from 'wallets'
export const name = 'webln' export const name = 'webln'
export const fields = [] export const fields = []
@ -19,3 +22,27 @@ export const card = {
subtitle: 'use a [WebLN provider](https://www.webln.guide/ressources/webln-providers) for payments', subtitle: 'use a [WebLN provider](https://www.webln.guide/ressources/webln-providers) for payments',
badges: ['send only'] badges: ['send only']
} }
export default function WebLnProvider ({ children }) {
const wallet = useWallet(name)
useEffect(() => {
const onEnable = () => {
wallet.enablePayments()
}
const onDisable = () => {
wallet.disablePayments()
}
window.addEventListener('webln:enabled', onEnable)
// event is not fired by Alby browser extension but added here for sake of completeness
window.addEventListener('webln:disabled', onDisable)
return () => {
window.removeEventListener('webln:enabled', onEnable)
window.removeEventListener('webln:disabled', onDisable)
}
}, [])
return children
}