From ec5241ad29b614c1987c841ca39de2d311aa3e13 Mon Sep 17 00:00:00 2001 From: ekzyis Date: Tue, 10 Sep 2024 18:13:39 +0200 Subject: [PATCH] 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 --- components/lightning-auth.js | 12 +++++++++++ jsconfig.json | 3 +++ pages/_app.js | 39 +++++++++++++++++++----------------- wallets/index.js | 12 ++++++----- wallets/webln/index.js | 27 +++++++++++++++++++++++++ 5 files changed, 70 insertions(+), 23 deletions(-) diff --git a/components/lightning-auth.js b/components/lightning-auth.js index 5efddc4c..4e6c1dbe 100644 --- a/components/lightning-auth.js +++ b/components/lightning-auth.js @@ -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 ( diff --git a/jsconfig.json b/jsconfig.json index bb96307c..9b5c18ac 100644 --- a/jsconfig.json +++ b/jsconfig.json @@ -17,6 +17,9 @@ "@/components/*": [ "components/*" ], + "@/wallets/*": [ + "wallets/*" + ], "@/styles/*": [ "styles/*" ], diff --git a/pages/_app.js b/pages/_app.js index 9161017e..c018094b 100644 --- a/pages/_app.js +++ b/pages/_app.js @@ -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 } }) { - - - - - - - - - - {!router?.query?.disablePrompt && } - - - - - - - - + + + + + + + + + + + {!router?.query?.disablePrompt && } + + + + + + + + + diff --git a/wallets/index.js b/wallets/index.js index 5a910f44..4d1cbf8f 100644 --- a/wallets/index.js +++ b/wallets/index.js @@ -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)) } diff --git a/wallets/webln/index.js b/wallets/webln/index.js index f1d970af..6bfb26d5 100644 --- a/wallets/webln/index.js +++ b/wallets/webln/index.js @@ -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 +}