mirror of
https://github.com/AustinKelsay/plebdevs.git
synced 2025-04-19 10:51:20 +00:00
Add nip05 and lnaddress endpoints
This commit is contained in:
parent
365b54c498
commit
ff3e907677
@ -14,6 +14,10 @@ module.exports = removeImports({
|
||||
source: '/api/cron',
|
||||
destination: '/api/cron',
|
||||
},
|
||||
{
|
||||
source: "/.well-known/nostr.json",
|
||||
destination: "/api/nip05",
|
||||
}
|
||||
];
|
||||
},
|
||||
});
|
65
src/pages/api/lightning-address/callback/[slug].js
Normal file
65
src/pages/api/lightning-address/callback/[slug].js
Normal file
@ -0,0 +1,65 @@
|
||||
import axios from "axios";
|
||||
import crypto from "crypto";
|
||||
import { runMiddleware, corsMiddleware } from "../../../utils/middleware";
|
||||
import { verifyEvent } from 'nostr-tools/pure';
|
||||
|
||||
const BACKEND_URL = process.env.BACKEND_URL;
|
||||
const RELAY_PUBKEY = process.env.RELAY_PUBKEY;
|
||||
|
||||
export default async function handler(req, res) {
|
||||
await runMiddleware(req, res, corsMiddleware);
|
||||
const { slug, ...queryParams } = req.query;
|
||||
|
||||
if (slug === 'austin') {
|
||||
if (queryParams.amount) {
|
||||
const amount = parseInt(queryParams.amount);
|
||||
let metadata, metadataString, hash, descriptionHash;
|
||||
|
||||
if (queryParams.nostr) {
|
||||
// This is a zap request
|
||||
const zapRequest = JSON.parse(decodeURIComponent(queryParams.nostr));
|
||||
|
||||
// Verify the zap request
|
||||
if (!verifyEvent(zapRequest)) {
|
||||
res.status(400).json({ error: 'Invalid zap request' });
|
||||
return;
|
||||
}
|
||||
|
||||
// Validate zap request
|
||||
if (zapRequest.kind !== 9734) {
|
||||
res.status(400).json({ error: 'Invalid zap request' });
|
||||
return;
|
||||
}
|
||||
|
||||
metadataString = JSON.stringify(zapRequest);
|
||||
hash = crypto.createHash('sha256').update(metadataString).digest('hex');
|
||||
descriptionHash = Buffer.from(hash, 'hex').toString('base64');
|
||||
} else {
|
||||
// This is a regular lnurl-pay request
|
||||
metadata = [
|
||||
["text/plain", "PlebDevs LNURL endpoint, CHEERS!"]
|
||||
];
|
||||
metadataString = JSON.stringify(metadata);
|
||||
hash = crypto.createHash('sha256').update(metadataString).digest('hex');
|
||||
descriptionHash = Buffer.from(hash, 'hex').toString('base64');
|
||||
}
|
||||
|
||||
// Convert amount from millisatoshis to satoshis
|
||||
const value = amount / 1000;
|
||||
if (value < 1) {
|
||||
res.status(400).json({ error: 'Amount too low' });
|
||||
return;
|
||||
} else {
|
||||
try {
|
||||
const response = await axios.post(`${BACKEND_URL}/api/lnd`, { amount: value, description_hash: descriptionHash });
|
||||
res.status(200).json({ pr: response.data });
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
res.status(500).json({ error: 'Failed to generate invoice' });
|
||||
}
|
||||
}
|
||||
} else {
|
||||
res.status(400).json({ error: 'Amount not specified' });
|
||||
}
|
||||
}
|
||||
}
|
50
src/pages/api/lightning-address/lnd.js
Normal file
50
src/pages/api/lightning-address/lnd.js
Normal file
@ -0,0 +1,50 @@
|
||||
import axios from "axios";
|
||||
import { finalizeEvent } from 'nostr-tools/pure';
|
||||
import { SimplePool } from 'nostr-tools/pool';
|
||||
|
||||
const LND_HOST = process.env.LND_HOST;
|
||||
const LND_MACAROON = process.env.LND_MACAROON;
|
||||
const RELAY_PRIVKEY = process.env.RELAY_PRIVKEY;
|
||||
|
||||
export default async function handler(req, res) {
|
||||
try {
|
||||
const response = await axios.post(`https://${LND_HOST}/v1/invoices`, {
|
||||
value: req.body.amount,
|
||||
description_hash: req.body.description_hash
|
||||
}, {
|
||||
headers: {
|
||||
'Grpc-Metadata-macaroon': LND_MACAROON,
|
||||
}
|
||||
});
|
||||
|
||||
const invoice = response.data.payment_request;
|
||||
|
||||
// If this is a zap, publish a zap receipt
|
||||
if (req.body.zap_request) {
|
||||
const zapRequest = JSON.parse(req.body.zap_request);
|
||||
const zapReceipt = {
|
||||
kind: 9735,
|
||||
created_at: Math.floor(Date.now() / 1000),
|
||||
content: '',
|
||||
tags: [
|
||||
['p', zapRequest.pubkey],
|
||||
['e', zapRequest.id],
|
||||
['bolt11', invoice],
|
||||
['description', JSON.stringify(zapRequest)]
|
||||
]
|
||||
};
|
||||
|
||||
const signedZapReceipt = finalizeEvent(zapReceipt, RELAY_PRIVKEY);
|
||||
|
||||
// Publish zap receipt to relays
|
||||
const pool = new SimplePool();
|
||||
const relays = zapRequest.tags.find(tag => tag[0] === 'relays')?.[1] || [];
|
||||
await pool.publish(relays, signedZapReceipt);
|
||||
}
|
||||
|
||||
res.status(200).json(invoice);
|
||||
} catch (error) {
|
||||
console.error('Error (server) fetching data from LND:', error.message);
|
||||
res.status(500).json({ message: 'Error fetching data' });
|
||||
}
|
||||
}
|
32
src/pages/api/lightning-address/lnurlp/[slug].js
Normal file
32
src/pages/api/lightning-address/lnurlp/[slug].js
Normal file
@ -0,0 +1,32 @@
|
||||
import { runMiddleware, corsMiddleware } from "../../../utils/middleware"
|
||||
|
||||
const BACKEND_URL = process.env.BACKEND_URL
|
||||
const RELAY_PUBKEY = process.env.RELAY_PUBKEY
|
||||
|
||||
export default async function handler(req, res) {
|
||||
await runMiddleware(req, res, corsMiddleware);
|
||||
|
||||
const { slug } = req.query
|
||||
|
||||
if (!slug || slug === 'undefined') {
|
||||
res.status(404).json({ error: 'Not found' })
|
||||
return
|
||||
}
|
||||
|
||||
if (slug === 'austin') {
|
||||
const metadata = [
|
||||
["text/plain", "PlebDevs LNURL endpoint, CHEERS!"]
|
||||
];
|
||||
|
||||
res.status(200).json({
|
||||
callback: `${BACKEND_URL}/api/callback/austin`,
|
||||
maxSendable: 10000000000,
|
||||
minSendable: 1000,
|
||||
metadata: JSON.stringify(metadata),
|
||||
tag: 'payRequest',
|
||||
allowsNostr: true,
|
||||
nostrPubkey: RELAY_PUBKEY
|
||||
})
|
||||
return
|
||||
}
|
||||
}
|
10
src/pages/api/nip05.js
Normal file
10
src/pages/api/nip05.js
Normal file
@ -0,0 +1,10 @@
|
||||
const nostrData = {
|
||||
names: {
|
||||
plebdevs:
|
||||
"f33c8a9617cb15f705fc70cd461cfd6eaf22f9e24c33eabad981648e5ec6f741",
|
||||
},
|
||||
};
|
||||
|
||||
export default async function Nip05(req, res) {
|
||||
return res.status(200).json(nostrData);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user