1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
|
import { g, s } from "$lib/db";
import { l, warn } from "$lib/logging";
import { bail, getUser, fail } from "$lib/utils";
import { v4 } from "uuid";
import got from "got";
import { generate } from "$lib/invoices";
import { bech32 } from "bech32";
import { fields, pick } from "$lib/utils";
import { types } from "$lib/payments";
import crypto from "crypto";
import config from "$config";
let { admin, classic } = config;
let { URL } = process.env;
let host = URL.split("/").at(-1);
export default {
async encode({ query: { address } }, res) {
let [name, domain] = address.split("@");
let url = `https://${domain}/.well-known/lnurlp/${name}`;
try {
let r = await got(url).json();
if (r.tag !== "payRequest") fail("not an ln address");
} catch (e) {
let m = `failed to lookup lightning address ${address}`;
warn(m);
return bail(res, m);
}
let enc = bech32.encode("lnurl", bech32.toWords(Buffer.from(url)), 20000);
res.send(enc);
},
async decode({ query: { text } }, res) {
try {
let url = Buffer.from(
bech32.fromWords(bech32.decode(text, 20000).words)
).toString();
res.send(await got(url).json());
} catch (e) {
bail(res, e.message);
}
},
async lnurlp({ params: { username } }, res) {
try {
let { id: uid } = await getUser(username);
if (!uid) {
let u = await got(`${classic}/admin/migrate/${username}?zero=true`, {
headers: { authorization: `Bearer ${admin}` }
}).json();
if (!u) fail("user not found");
let { balance, pubkey } = u;
uid = u.uuid;
u = { id: uid, about: u.address, ...pick(u, fields) };
delete u.address;
await s(`user:${username.replace(/\s/g, "").toLowerCase()}`, uid);
await s(`user:${uid}`, u);
await s(`balance:${uid}`, balance);
l("added missing user", username);
}
let metadata = JSON.stringify([
["text/plain", `Paying ${username}@${host}`],
["text/identifier", `${username}@${host}`]
]);
let id = v4();
await s(`lnurl:${id}`, uid);
res.send({
minSendable: 1000,
maxSendable: 100000000000,
metadata,
callback: `${URL}/api/lnurl/${id}`,
tag: "payRequest"
});
} catch (e) {
warn("problem generating lnurlp request", e.message);
bail(res, e.message);
}
},
async lnurlw({ params: { k1, pr } }, res) {
},
async lnurl({ params: { id }, query: { amount } }, res) {
let pr = await g(`lnurlp:${id}`);
if (!pr) {
let uid = await g(`lnurl:${id}`);
let user = await g(`user:${uid}`);
let { username } = user;
username = username.replace(/\s/g, "").toLowerCase();
let metadata = JSON.stringify([
["text/plain", `Paying ${username}@${host}`],
["text/identifier", `${username}@${host}`]
]);
({ text: pr } = await generate({
invoice: {
amount: Math.round(amount / 1000),
type: types.lightning
},
memo: metadata,
user
}));
await s(`lnurlp:${id}`, pr);
}
res.send({ pr, routes: [] });
}
};
|