Compare commits

...

5 Commits

Author SHA1 Message Date
Keyan 3af43d74d3
Update awards.csv 2024-08-27 11:22:34 -05:00
ekzyis 4cec369005
Support Tor for LNbits recv (#1336)
* Add tor support to LNbits recv

* Only return agent
2024-08-27 11:16:02 -05:00
ekzyis d09f7c5427
Fix websocket leaks (#1334) 2024-08-27 11:15:00 -05:00
ekzyis ec6124ca62
NWC hardcoded keys (#1335)
* Include keys.json in NWC container image

* Update NWC ATTACH.md
2024-08-27 11:14:35 -05:00
ekzyis 9f194c5d8e
Fix preimage undefined in wallet logs (#1337)
* Fix preimage undefined in NWC wallet logs

* Return preimage as string
2024-08-27 11:13:52 -05:00
15 changed files with 72 additions and 40 deletions

View File

@ -122,3 +122,5 @@ Gudnessuche,issue,#1264,#1226,good-first-issue,,,,2k,everythingsatoshi@getalby.c
aniskhalfallah,pr,#1289,,easy,,,,100k,aniskhalfallah@blink.sv,2024-08-12
riccardobl,pr,#1293,#1142,medium,high,,,500k,rblb@getalby.com,2024-08-18
tsmith123,pr,#1306,#832,medium,,,,250k,stickymarch60@walletofsatoshi.com,2024-08-20
riccardobl,pr,#1311,#864,medium,high,,pending unrelated refactor,500k,rblb@getalby.com,2024-08-27
brugeman,issue,#1311,#864,medium,high,,,50k,brugeman@stacker.news,2024-08-27

1 name type pr id issue ids difficulty priority changes requested notes amount receive method date paid
122 aniskhalfallah pr #1289 easy 100k aniskhalfallah@blink.sv 2024-08-12
123 riccardobl pr #1293 #1142 medium high 500k rblb@getalby.com 2024-08-18
124 tsmith123 pr #1306 #832 medium 250k stickymarch60@walletofsatoshi.com 2024-08-20
125 riccardobl pr #1311 #864 medium high pending unrelated refactor 500k rblb@getalby.com 2024-08-27
126 brugeman issue #1311 #864 medium high 50k brugeman@stacker.news 2024-08-27

View File

@ -10,3 +10,5 @@ RUN apt-get update -y \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
RUN cargo build --release && cargo install --path .
COPY keys.json .

1
docker/nwc/keys.json Normal file
View File

@ -0,0 +1 @@
{"server_key":"4463b828d1950885de82b518efbfbe3dd6c35278e8ee5f6389721515b4c5e021","user_key":"0d1ef06059c9b1acf8c424cfe357c5ffe2d5f3594b9081695771a363ee716b67","sent_info":true}

View File

@ -1,30 +1,11 @@
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'
import { getAgent } from '@/lib/proxy'
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 = TOR_REGEXP.test(socket)
if (isOnion) {
// we support HTTP and HTTPS over Tor
protocol = cert ? 'https:' : 'http:'
// we need to use our Tor proxy to resolve onion addresses
const proxyOptions = { proxy: process.env.TOR_PROXY }
agent = protocol === 'https:'
? new HttpsProxyAgent({ ...proxyOptions, ...httpsAgentOptions, rejectUnauthorized: false })
: new HttpProxyAgent(proxyOptions)
} else if (process.env.NODE_ENV === 'development' && !cert) {
protocol = 'http:'
} else {
// we only support HTTPS over clearnet
agent = new https.Agent(httpsAgentOptions)
protocol = 'https:'
}
const agent = getAgent({ hostname: socket, cert })
const url = `${protocol}//${socket}/v1/invoice`
const url = `${agent.protocol}//${socket}/v1/invoice`
const res = await fetch(url, {
method: 'POST',
headers: {

View File

@ -69,6 +69,9 @@ export class Relay {
try {
return await withTimeout(checkPromise, timeout)
} catch (err) {
this.close()
throw err
} finally {
clearInterval(interval)
}
@ -187,7 +190,11 @@ export function nostrZapDetails (zap) {
async function publishNostrEvent (signedEvent, relayUrl) {
const timeout = 3000
const relay = await Relay.connect(relayUrl, { timeout })
await relay.publish(signedEvent, { timeout })
try {
await relay.publish(signedEvent, { timeout })
} finally {
relay.close()
}
}
export async function crosspost (event, relays = DEFAULT_CROSSPOSTING_RELAYS) {

View File

@ -1,5 +1,6 @@
import http from 'http'
import https from 'https'
import { TOR_REGEXP } from '@/lib/url'
// from https://github.com/delvedor/hpagent
@ -118,3 +119,28 @@ export class HttpsProxyAgent extends https.Agent {
request.end()
}
}
export function getAgent ({ hostname, cert }) {
let agent
const httpsAgentOptions = { ca: cert ? Buffer.from(cert, 'base64') : undefined }
const isOnion = TOR_REGEXP.test(hostname)
if (isOnion) {
// we support HTTP and HTTPS over Tor
const protocol = cert ? 'https:' : 'http:'
// we need to use our Tor proxy to resolve onion addresses
const proxyOptions = { proxy: process.env.TOR_PROXY }
agent = protocol === 'https:'
? new HttpsProxyAgent({ ...proxyOptions, ...httpsAgentOptions, rejectUnauthorized: false })
: new HttpProxyAgent(proxyOptions)
return agent
}
if (process.env.NODE_ENV === 'development' && !cert) {
return new http.Agent()
}
// we only support HTTPS over clearnet
return new https.Agent(httpsAgentOptions)
}

View File

@ -163,11 +163,11 @@ This function must throw an error if the configuration was found to be invalid.
The `context` argument is an object. It makes the wallet logger for this wallet as returned by `useWalletLogger` available under `context.logger`. See [components/wallet-logger.js](../components/wallet-logger.js).
- `sendPayment: async (bolt11: string, config, context) => Promise<{ preimage: string }>`
- `sendPayment: async (bolt11: string, config, context) => Promise<string>`
`sendPayment` will be called if a payment is required. Therefore, this function should implement the code to pay invoices from this wallet.
The first argument is the [BOLT11 payment request](https://github.com/lightning/bolts/blob/master/11-payment-encoding.md). The `config` argument is the current configuration of this wallet (that was validated before). The `context` argument is the same as for `testSendPayment`.
The first argument is the [BOLT11 payment request](https://github.com/lightning/bolts/blob/master/11-payment-encoding.md). The `config` argument is the current configuration of this wallet (that was validated before). The `context` argument is the same as for `testSendPayment`. The function should return the preimage on payment success.
> [!IMPORTANT]
> As mentioned above, this file must exist for every wallet and at least reexport everything in index.js so make sure that the following line is included:

View File

@ -10,8 +10,7 @@ export async function testSendPayment ({ apiKey, currency }, { logger }) {
export async function sendPayment (bolt11, { apiKey, currency }) {
const wallet = await getWallet(apiKey, currency)
const preImage = await payInvoice(apiKey, wallet, bolt11)
return { preImage }
return await payInvoice(apiKey, wallet, bolt11)
}
async function payInvoice (authToken, wallet, invoice) {

View File

@ -59,7 +59,7 @@ export function useWallet (name) {
const hash = bolt11Tags(bolt11).payment_hash
logger.info('sending payment:', `payment_hash=${hash}`)
try {
const { preimage } = await wallet.sendPayment(bolt11, config, { me, logger, status, showModal })
const preimage = await wallet.sendPayment(bolt11, config, { me, logger, status, showModal })
logger.ok('payment successful:', `payment_hash=${hash}`, `preimage=${preimage}`)
} catch (err) {
const message = err.message || err.toString?.()

View File

@ -19,8 +19,7 @@ export async function sendPayment (bolt11, { url, adminKey }) {
throw new Error('No preimage')
}
const preimage = checkResponse.preimage
return { preimage }
return checkResponse.preimage
}
async function getWallet ({ url, adminKey, invoiceKey }) {

View File

@ -1,4 +1,5 @@
import { msatsToSats } from '@/lib/format'
import { getAgent } from '@/lib/proxy'
export * from 'wallets/lnbits'
@ -27,7 +28,15 @@ export async function createInvoice (
out: false
})
const res = await fetch(url + path, { method: 'POST', headers, body })
const hostname = url.replace(/^https?:\/\//, '')
const agent = getAgent({ hostname })
const res = await fetch(`${agent.protocol}//${hostname}${path}`, {
method: 'POST',
headers,
agent,
body
})
if (!res.ok) {
const errBody = await res.json()
throw new Error(errBody.detail)

View File

@ -67,7 +67,7 @@ export async function sendPayment (bolt11, credentials, { logger }) {
if (paymentError) throw new Error(paymentError)
if (!preimage) throw new Error('No preimage in response')
return { preimage }
return preimage
} catch (err) {
const msg = err.message || err.toString?.()
if (msg.includes('invoice expired')) {

View File

@ -1,7 +1,9 @@
The nwc string is printed in the nwc container logs on startup ...
Use this NWC string to attach the wallet for payments:
Open the nwc container logs like this:
```bash
$ sndev logs nwc
```
nostr+walletconnect://5224c44600696216595a70982ee7387a04bd66248b97fefb803f4ed6d4af1972?relay=wss%3A%2F%2Frelay.damus.io&secret=0d1ef06059c9b1acf8c424cfe357c5ffe2d5f3594b9081695771a363ee716b67
```
This won't work for receives since it allows `pay_invoice`.
TODO: generate NWC string with only `make_invoice` as permission

View File

@ -35,5 +35,5 @@ export async function sendPayment (bolt11, { url, primaryPassword }) {
throw new Error(payment.reason)
}
return payment.paymentPreimage
return preimage
}

View File

@ -54,7 +54,11 @@ export async function nip57 ({ data: { hash }, boss, lnd, models }) {
relays.map(async r => {
const timeout = 1000
const relay = await Relay.connect(r, { timeout })
await relay.publish(e, { timeout })
try {
await relay.publish(e, { timeout })
} finally {
relay.close()
}
})
)
} catch (e) {