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])
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
return (
<Qr value={encodedUrl} status='waiting for you' />

View File

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

View File

@ -21,6 +21,7 @@ import { WalletLoggerProvider } from '@/components/wallet-logger'
import { ChainFeeProvider } from '@/components/chain-fee.js'
import dynamic from 'next/dynamic'
import { HasNewNotesProvider } from '@/components/use-has-new-notes'
import WebLnProvider from '@/wallets/webln'
const PWAPrompt = dynamic(() => import('react-ios-pwa-prompt'), { ssr: false })
@ -106,24 +107,26 @@ export default function MyApp ({ Component, pageProps: { ...props } }) {
<HasNewNotesProvider>
<LoggerProvider>
<WalletLoggerProvider>
<ServiceWorkerProvider>
<PriceProvider price={price}>
<LightningProvider>
<ToastProvider>
<ShowModalProvider>
<BlockHeightProvider blockHeight={blockHeight}>
<ChainFeeProvider chainFee={chainFee}>
<ErrorBoundary>
<Component ssrData={ssrData} {...otherProps} />
{!router?.query?.disablePrompt && <PWAPrompt copyBody='This website has app functionality. Add it to your home screen to use it in fullscreen and receive notifications. In Safari:' promptOnVisit={2} />}
</ErrorBoundary>
</ChainFeeProvider>
</BlockHeightProvider>
</ShowModalProvider>
</ToastProvider>
</LightningProvider>
</PriceProvider>
</ServiceWorkerProvider>
<WebLnProvider>
<ServiceWorkerProvider>
<PriceProvider price={price}>
<LightningProvider>
<ToastProvider>
<ShowModalProvider>
<BlockHeightProvider blockHeight={blockHeight}>
<ChainFeeProvider chainFee={chainFee}>
<ErrorBoundary>
<Component ssrData={ssrData} {...otherProps} />
{!router?.query?.disablePrompt && <PWAPrompt copyBody='This website has app functionality. Add it to your home screen to use it in fullscreen and receive notifications. In Safari:' promptOnVisit={2} />}
</ErrorBoundary>
</ChainFeeProvider>
</BlockHeightProvider>
</ShowModalProvider>
</ToastProvider>
</LightningProvider>
</PriceProvider>
</ServiceWorkerProvider>
</WebLnProvider>
</WalletLoggerProvider>
</LoggerProvider>
</HasNewNotesProvider>

View File

@ -412,24 +412,26 @@ export function useWallets () {
function getStorageKey (name, me) {
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}`
}
return storageKey
}
function enableWallet (name, me) {
const key = getStorageKey(name, me)
const config = JSON.parse(window.localStorage.getItem(key))
if (!config) return
const config = JSON.parse(window.localStorage.getItem(key)) || {}
config.enabled = true
window.localStorage.setItem(key, JSON.stringify(config))
}
function disableWallet (name, me) {
const key = getStorageKey(name, me)
const config = JSON.parse(window.localStorage.getItem(key))
if (!config) return
const config = JSON.parse(window.localStorage.getItem(key)) || {}
config.enabled = false
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 fields = []
@ -19,3 +22,27 @@ export const card = {
subtitle: 'use a [WebLN provider](https://www.webln.guide/ressources/webln-providers) for payments',
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
}