Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable WebLN wallet on 'webln:enabled' #1385

Merged
merged 4 commits into from
Sep 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions components/lightning-auth.js
Original file line number Diff line number Diff line change
Expand Up @@ -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' />
Expand Down
3 changes: 3 additions & 0 deletions jsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@
"@/components/*": [
"components/*"
],
"@/wallets/*": [
"wallets/*"
],
"@/styles/*": [
"styles/*"
],
Expand Down
39 changes: 21 additions & 18 deletions pages/_app.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 })

Expand Down Expand Up @@ -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>
Expand Down
12 changes: 7 additions & 5 deletions wallets/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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))
}
27 changes: 27 additions & 0 deletions wallets/webln/index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import { useEffect } from 'react'
import { useWallet } from 'wallets'

export const name = 'webln'

export const fields = []
Expand All @@ -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
}
Loading