Compare commits

...

9 Commits

Author SHA1 Message Date
ekzyis
7e1c62fdcb
Fix provider default setting (#1183) 2024-05-17 20:27:57 -05:00
ekzyis
91192025e5
Remove NWC script (#1182) 2024-05-17 20:27:47 -05:00
ekzyis
7119c2ef0b
Fix QR rerender on WebLN payment (#1181) 2024-05-17 20:27:34 -05:00
Keyan
cf995d0a9f
Update awards.csv 2024-05-17 10:50:01 -05:00
Tom Smith
2b2f2d589c
Show Alert Message on Settings Page (#1179)
* Show alert message

* Add extra line

* Use css var

* Restore lightning in filter

* Show alert at top of page
2024-05-17 10:47:06 -05:00
keyan
9dfdfe7329 update awards.csv payouts 2024-05-17 10:20:08 -05:00
Keyan
4aa3c67527
Update awards.csv 2024-05-17 08:41:22 -05:00
keyan
a71b9be03f fix subscription check on mute (#1177) 2024-05-17 08:30:14 -05:00
ekzyis
a585ba7f0a
Allow HTTP and HTTPS over Tor for LNbits (#1176) 2024-05-16 08:41:49 -05:00
13 changed files with 78 additions and 49 deletions

View File

@ -749,7 +749,7 @@ export default {
}
}
})
if (subscription.postsSubscribedAt || subscription.commentsSubscribedAt) {
if (subscription?.postsSubscribedAt || subscription?.commentsSubscribedAt) {
throw new GraphQLError("you can't mute a stacker to whom you've subscribed", { extensions: { code: 'BAD_INPUT' } })
}
await models.mute.create({ data: { ...lookupData } })

View File

@ -74,23 +74,25 @@ SatsAllDay,issue,#1137,#1125,good-first-issue,,,,2k,weareallsatoshi@getalby.com,
SatsAllDay,helpfulness,#1137,#1125,good-first-issue,,,,2k,weareallsatoshi@getalby.com,2024-05-04
itsrealfake,pr,#1138,#995,good-first-issue,,,,20k,itsrealfake2@stacker.news,2024-05-06
SouthKoreaLN,issue,#1138,#995,good-first-issue,,,,2k,south_korea_ln@stacker.news,2024-05-04
mateusdeap,helpfulness,#1138,#995,good-first-issue,,,,1k,mateusdeap@stacker.news,???
mateusdeap,helpfulness,#1138,#995,good-first-issue,,,,1k,mateusdeap@stacker.news,2024-05-17
felipebueno,pr,#1094,,,,2,,80k,felipebueno@getalby.com,2024-05-06
benalleng,helpfulness,#1127,#927,good-first-issue,,,,2k,benalleng@mutiny.plus,2024-05-04
itsrealfake,pr,#1135,#1016,good-first-issue,,,nonideal solution,10k,itsrealfake2@stacker.news,2024-05-06
SatsAllDay,issue,#1135,#1016,good-first-issue,,,,1k,weareallsatoshi@getalby.com,2024-05-04
s373nZ,issue,#1136,#1107,medium,high,,,50k,se7enz@minibits.cash,2024-05-05
abhiShandy,pr,#1123,#624,good-first-issue,,,,20k,abhishandy@stacker.news,???
hkarani,pr,#1147,#1143,good-first-issue,,,,20k,asterisk32@stacker.news,???
benalleng,helpfulness,#1147,#1143,good-first-issue,,,,2k,benalleng@mutiny.plus,???
abhiShandy,pr,#1157,#1148,good-first-issue,,,,20k,abhishandy@stacker.news,???
SatsAllDay,issue,#1157,#1148,good-first-issue,,,,2k,weareallsatoshi@getalby.com,???
abhiShandy,pr,#1158,#1139,good-first-issue,,,,20k,abhishandy@stacker.news,???
SatsAllDay,issue,#1158,#1139,good-first-issue,,,,2k,weareallsatoshi@getalby.com,???
SatsAllDay,pr,#1145,#717,medium,,,,250k,weareallsatoshi@getalby.com,???
benalleng,pr,#1129,#491,good-first-issue,,,paid for advice out of band,20k,benalleng@mutiny.plus,???
benalleng,pr,#1129,#1045,easy,,2,post-humously upgraded to easy,80k,benalleng@mutiny.plus,???
SouthKoreaLN,issue,#1129,#1045,easy,,,,8k,south_korea_ln@stacker.news,???
tsmith123,pr,#1171,#1124,good-first-issue,,,bonus for refactor,40k,stickymarch60@walletofsatoshi.com,???
SatsAllDay,issue,#1171,#1124,good-first-issue,,,,4k,weareallsatoshi@getalby.com,???
felipebueno,pr,#1162,,,,2,,200k,felipebueno@getalby.com,???
abhiShandy,pr,#1123,#624,good-first-issue,,,,20k,abhishandy@stacker.news,2024-05-17
hkarani,pr,#1147,#1143,good-first-issue,,,,20k,asterisk32@stacker.news,2024-05-17
benalleng,helpfulness,#1147,#1143,good-first-issue,,,,2k,benalleng@mutiny.plus,2024-05-17
abhiShandy,pr,#1157,#1148,good-first-issue,,,,20k,abhishandy@stacker.news,2024-05-17
SatsAllDay,issue,#1157,#1148,good-first-issue,,,,2k,weareallsatoshi@getalby.com,2024-05-17
abhiShandy,pr,#1158,#1139,good-first-issue,,,,20k,abhishandy@stacker.news,2024-05-17
SatsAllDay,issue,#1158,#1139,good-first-issue,,,,2k,weareallsatoshi@getalby.com,2024-05-17
SatsAllDay,pr,#1145,#717,medium,,,,250k,weareallsatoshi@getalby.com,2024-05-17
benalleng,pr,#1129,#491,good-first-issue,,,paid for advice out of band,20k,benalleng@mutiny.plus,2024-05-17
benalleng,pr,#1129,#1045,easy,,2,post-humously upgraded to easy,80k,benalleng@mutiny.plus,2024-05-17
SouthKoreaLN,issue,#1129,#1045,easy,,,,8k,south_korea_ln@stacker.news,2024-05-17
tsmith123,pr,#1171,#1124,good-first-issue,,,bonus for refactor,40k,stickymarch60@walletofsatoshi.com,2024-05-17
SatsAllDay,issue,#1171,#1124,good-first-issue,,,,4k,weareallsatoshi@getalby.com,2024-05-17
felipebueno,pr,#1162,,,,2,,200k,felipebueno@getalby.com,2024-05-17
Radentor,issue,,#1177,easy,,,,10k,Radentor@stacker.news,2024-05-17
tsmith123,pr,#1179,#790,good-first-issue,high,,,40k,stickymarch60@walletofsatoshi.com,2024-05-17

1 name type pr id issue ids difficulty priority changes requested notes amount receive method date paid
74 SatsAllDay helpfulness #1137 #1125 good-first-issue 2k weareallsatoshi@getalby.com 2024-05-04
75 itsrealfake pr #1138 #995 good-first-issue 20k itsrealfake2@stacker.news 2024-05-06
76 SouthKoreaLN issue #1138 #995 good-first-issue 2k south_korea_ln@stacker.news 2024-05-04
77 mateusdeap helpfulness #1138 #995 good-first-issue 1k mateusdeap@stacker.news ??? 2024-05-17
78 felipebueno pr #1094 2 80k felipebueno@getalby.com 2024-05-06
79 benalleng helpfulness #1127 #927 good-first-issue 2k benalleng@mutiny.plus 2024-05-04
80 itsrealfake pr #1135 #1016 good-first-issue nonideal solution 10k itsrealfake2@stacker.news 2024-05-06
81 SatsAllDay issue #1135 #1016 good-first-issue 1k weareallsatoshi@getalby.com 2024-05-04
82 s373nZ issue #1136 #1107 medium high 50k se7enz@minibits.cash 2024-05-05
83 abhiShandy pr #1123 #624 good-first-issue 20k abhishandy@stacker.news ??? 2024-05-17
84 hkarani pr #1147 #1143 good-first-issue 20k asterisk32@stacker.news ??? 2024-05-17
85 benalleng helpfulness #1147 #1143 good-first-issue 2k benalleng@mutiny.plus ??? 2024-05-17
86 abhiShandy pr #1157 #1148 good-first-issue 20k abhishandy@stacker.news ??? 2024-05-17
87 SatsAllDay issue #1157 #1148 good-first-issue 2k weareallsatoshi@getalby.com ??? 2024-05-17
88 abhiShandy pr #1158 #1139 good-first-issue 20k abhishandy@stacker.news ??? 2024-05-17
89 SatsAllDay issue #1158 #1139 good-first-issue 2k weareallsatoshi@getalby.com ??? 2024-05-17
90 SatsAllDay pr #1145 #717 medium 250k weareallsatoshi@getalby.com ??? 2024-05-17
91 benalleng pr #1129 #491 good-first-issue paid for advice out of band 20k benalleng@mutiny.plus ??? 2024-05-17
92 benalleng pr #1129 #1045 easy 2 post-humously upgraded to easy 80k benalleng@mutiny.plus ??? 2024-05-17
93 SouthKoreaLN issue #1129 #1045 easy 8k south_korea_ln@stacker.news ??? 2024-05-17
94 tsmith123 pr #1171 #1124 good-first-issue bonus for refactor 40k stickymarch60@walletofsatoshi.com ??? 2024-05-17
95 SatsAllDay issue #1171 #1124 good-first-issue 4k weareallsatoshi@getalby.com ??? 2024-05-17
96 felipebueno pr #1162 2 200k felipebueno@getalby.com ??? 2024-05-17
97 Radentor issue #1177 easy 10k Radentor@stacker.news 2024-05-17
98 tsmith123 pr #1179 #790 good-first-issue high 40k stickymarch60@walletofsatoshi.com 2024-05-17

View File

@ -1,7 +1,7 @@
import QRCode from 'qrcode.react'
import { CopyInput, InputSkeleton } from './form'
import InvoiceStatus from './invoice-status'
import { useEffect, useRef } from 'react'
import { useEffect } from 'react'
import { useWebLN } from './webln'
import SimpleCountdown from './countdown'
import Bolt11Info from './bolt11-info'
@ -9,13 +9,10 @@ import Bolt11Info from './bolt11-info'
export default function Qr ({ asIs, value, webLn, statusVariant, description, status }) {
const qrValue = asIs ? value : 'lightning:' + value.toUpperCase()
const provider = useWebLN()
// XXX antipattern ... we shouldn't be getting multiple renders
const sendPayment = useRef(false)
useEffect(() => {
async function effect () {
if (webLn && provider && !sendPayment.current) {
sendPayment.current = true
if (webLn && provider) {
try {
await provider.sendPayment({ bolt11: value })
} catch (e) {

View File

@ -63,7 +63,7 @@ function RawWebLNProvider ({ children }) {
return null
})
})
}, [...availableProviders])
}, [])
// keep list in sync with underlying providers
useEffect(() => {
@ -130,7 +130,7 @@ function RawWebLNProvider ({ children }) {
}, [])
return (
<WebLNContext.Provider value={{ provider: isEnabled(provider) ? { sendPayment: sendPaymentWithToast } : null, enabledProviders, setProvider, clearConfig }}>
<WebLNContext.Provider value={{ provider: isEnabled(provider) ? { name: provider.name, sendPayment: sendPaymentWithToast } : null, enabledProviders, setProvider, clearConfig }}>
{children}
</WebLNContext.Provider>
)

View File

@ -1,4 +1,4 @@
import { createContext, useCallback, useContext, useEffect, useState } from 'react'
import { createContext, useCallback, useContext, useEffect, useMemo, useState } from 'react'
import { useWalletLogger } from '../logger'
import { Status, migrateLocalStorage } from '.'
import { bolt11Tags } from '@/lib/bolt11'
@ -72,7 +72,6 @@ export function LNbitsProvider ({ children }) {
const [status, setStatus] = useState()
const { logger } = useWalletLogger(Wallet.LNbits)
const name = 'LNbits'
let storageKey = 'webln:provider:lnbits'
if (me) {
storageKey = `${storageKey}:${me.id}`
@ -196,7 +195,9 @@ export function LNbitsProvider ({ children }) {
loadConfig().catch(console.error)
}, [])
const value = { name, url, adminKey, status, saveConfig, clearConfig, getInfo, sendPayment }
const value = useMemo(
() => ({ name: 'LNbits', url, adminKey, status, saveConfig, clearConfig, getInfo, sendPayment }),
[url, adminKey, status, saveConfig, clearConfig, getInfo, sendPayment])
return (
<LNbitsContext.Provider value={value}>
{children}

View File

@ -1,4 +1,4 @@
import { createContext, useCallback, useContext, useEffect, useState } from 'react'
import { createContext, useCallback, useContext, useEffect, useMemo, useState } from 'react'
import { useWalletLogger } from '../logger'
import LNC from '@lightninglabs/lnc-web'
import { Status, migrateLocalStorage } from '.'
@ -191,8 +191,11 @@ export function LNCProvider ({ children }) {
})()
}, [me, setStatus, setConfig, logger])
const value = useMemo(
() => ({ name: 'lnc', status, unlock, getInfo, sendPayment, config, saveConfig, clearConfig }),
[status, unlock, getInfo, sendPayment, config, saveConfig, clearConfig])
return (
<LNCContext.Provider value={{ name: 'lnc', status, unlock, getInfo, sendPayment, config, saveConfig, clearConfig }}>
<LNCContext.Provider value={value}>
{children}
{modal}
</LNCContext.Provider>

View File

@ -1,6 +1,6 @@
// https://github.com/getAlby/js-sdk/blob/master/src/webln/NostrWeblnProvider.ts
import { createContext, useCallback, useContext, useEffect, useState } from 'react'
import { createContext, useCallback, useContext, useEffect, useMemo, useState } from 'react'
import { Relay, finalizeEvent, nip04 } from 'nostr-tools'
import { parseNwcUrl } from '@/lib/url'
import { useWalletLogger } from '../logger'
@ -20,7 +20,6 @@ export function NWCProvider ({ children }) {
const [status, setStatus] = useState()
const { logger } = useWalletLogger(Wallet.NWC)
const name = 'NWC'
let storageKey = 'webln:provider:nwc'
if (me) {
storageKey = `${storageKey}:${me.id}`
@ -273,7 +272,9 @@ export function NWCProvider ({ children }) {
loadConfig().catch(err => logger.error(err.message || err.toString?.()))
}, [])
const value = { name, nwcUrl, relayUrl, walletPubkey, secret, status, saveConfig, clearConfig, getInfo, sendPayment }
const value = useMemo(
() => ({ name: 'NWC', nwcUrl, relayUrl, walletPubkey, secret, status, saveConfig, clearConfig, getInfo, sendPayment }),
[nwcUrl, relayUrl, walletPubkey, secret, status, saveConfig, clearConfig, getInfo, sendPayment])
return (
<NWCContext.Provider value={value}>
{children}

View File

@ -2,11 +2,12 @@ import fetch from 'cross-fetch'
import https from 'https'
import crypto from 'crypto'
import { HttpProxyAgent, HttpsProxyAgent } from '@/lib/proxy'
import { TOR_REGEXP } from '@/lib/url'
export const createInvoice = async ({ socket, rune, cert, label, description, msats, expiry }) => {
let protocol, agent
const httpsAgentOptions = { ca: cert ? Buffer.from(cert, 'base64') : undefined }
const isOnion = /\.onion(:[0-9]+)?$/.test(socket)
const isOnion = TOR_REGEXP.test(socket)
if (isOnion) {
// we support HTTP and HTTPS over Tor
protocol = cert ? 'https:' : 'http:'

View File

@ -93,3 +93,5 @@ export const MEDIA_DOMAIN_REGEXP = new RegExp(`^https?://${process.env.NEXT_PUBL
// this regex is not a bullet proof way of checking if a url points to an image. to be sure, fetch the url and check the mimetype
export const IMG_URL_REGEXP = /^(https?:\/\/.*\.(?:png|jpg|jpeg|gif))$/
export const TOR_REGEXP = /\.onion(:[0-9]+)?$/

View File

@ -10,7 +10,7 @@ import { msatsToSats, numWithUnits, abbrNum, ensureB64, B64_URL_REGEX } from './
import * as usersFragments from '@/fragments/users'
import * as subsFragments from '@/fragments/subs'
import { isInvoicableMacaroon, isInvoiceMacaroon } from './macaroon'
import { parseNwcUrl } from './url'
import { TOR_REGEXP, parseNwcUrl } from './url'
import { datePivot } from './time'
import { decodeRune } from '@/lib/cln'
import bip39Words from './bip39-words'
@ -601,11 +601,27 @@ export const lnAddrSchema = ({ payerData, min, max, commentAllowed } = {}) =>
}, {})))
export const lnbitsSchema = object({
url: process.env.NODE_ENV === 'development'
url: process.env.NODE_ENV !== 'development'
? string()
.or([string().matches(/^(http:\/\/)?localhost:\d+$/), string().url()], 'invalid url')
.required('required').trim()
: string().url().required('required').trim().https(),
: string().url().required('required').trim()
.test(async (url, context) => {
if (TOR_REGEXP.test(url)) {
// allow HTTP and HTTPS over Tor
if (!/^https?:\/\//.test(url)) {
return context.createError({ message: 'http or https required' })
}
return true
}
try {
// force HTTPS over clearnet
await string().https().validate(url)
} catch (err) {
return context.createError({ message: err.message })
}
return true
}),
adminKey: string().length(32)
})

View File

@ -38,6 +38,19 @@ function bech32encode (hexString) {
return bech32.encode('npub', bech32.toWords(Buffer.from(hexString, 'hex')))
}
// sort to prevent hydration mismatch
const getProviders = (authMethods) =>
Object.keys(authMethods).filter(k => k !== '__typename' && k !== 'apiKey').sort()
// Show alert message if user only has one auth method activated
// as users are losing access to their accounts
const hasOnlyOneAuthMethod = (authMethods) => {
const activatedAuths = getProviders(authMethods)
.filter(provider => !!authMethods[provider])
return activatedAuths.length === 1
}
export function SettingsHeader () {
const router = useRouter()
const pathParts = router.asPath.split('/').filter(segment => !!segment)
@ -94,6 +107,7 @@ export default function Settings ({ ssrData }) {
return (
<Layout>
<div className='pb-3 w-100 mt-2' style={{ maxWidth: '600px' }}>
{hasOnlyOneAuthMethod(settings?.authMethods) && <div className={styles.alert}>Please add a second auth method to avoid losing access to your account.</div>}
<SettingsHeader />
<Form
initial={{
@ -673,8 +687,7 @@ function AuthMethods ({ methods, apiKeyEnabled }) {
}
)
// sort to prevent hydration mismatch
const providers = Object.keys(methods).filter(k => k !== '__typename' && k !== 'apiKey').sort()
const providers = getProviders(methods)
const unlink = async type => {
// if there's only one auth method left

View File

@ -15,3 +15,8 @@
.nav :global .active {
border-bottom: 2px solid var(--bs-primary);
}
.alert {
color: var(--bs-danger);
margin-bottom: 10px;
}

View File

@ -1,12 +0,0 @@
#!/usr/bin/env bash
# https://github.com/benthecarman/nostr-wallet-connect-lnd
LND_HOST="${STACKER_LND_HOST:-localhost}"
LND_PORT="${STACKER_LND_GRPC_PORT:-10010}"
RUST_LOG=info nostr-wallet-connect-lnd \
--relay wss://relay.damus.io \
--lnd-host $LND_HOST --lnd-port $LND_PORT \
--macaroon-file docker/lnd/stacker/regtest/admin.macaroon --cert-file docker/lnd/stacker/tls.cert \
--keys-file scripts/nwc-keys.json