mirror of
https://github.com/alexbosworth/balanceofsatoshis.git
synced 2026-08-13 12:33:37 +02:00
merge changes
This commit is contained in:
parent
a3192e2f97
commit
7dc460eba0
2 changed files with 27 additions and 57 deletions
|
|
@ -1,26 +1,30 @@
|
|||
const {bech32} = require('bech32');
|
||||
|
||||
const {decode} = bech32;
|
||||
const asLnurl = n => n.substring(n.startsWith('lightning:') ? 10 : 0);
|
||||
const bech32CharLimit = 2000;
|
||||
const emailPattern = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/;
|
||||
const isOnion = n => /onion/.test(n);
|
||||
const {decode} = bech32;
|
||||
const isEmail = n => /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/.test(n);
|
||||
const isOnion = n => /.onion$/.test(n);
|
||||
const isUsername = n => /^[a-z0-9_.]*$/.test(n);
|
||||
const join = arr => arr.join('');
|
||||
const parseEmail = email => email.split('@');
|
||||
const prefix = 'lnurl';
|
||||
const sslProtocol = 'https://';
|
||||
const testEmail = n => emailPattern.test(n);
|
||||
const testUsername = n => /^[a-z0-9_.]*$/.test(n);
|
||||
const urlString = '/.well-known/lnurlp/';
|
||||
const wordsAsUtf8 = n => Buffer.from(bech32.fromWords(n)).toString('utf8');
|
||||
|
||||
/** Parse lnurl or lightning address
|
||||
/** Parse lnurl or LUD-16 lightning address
|
||||
|
||||
{
|
||||
url: <Lnurl or Lightning Address String>
|
||||
}
|
||||
|
||||
@throws
|
||||
<Error>
|
||||
|
||||
@returns
|
||||
{
|
||||
url: <Callback Url>
|
||||
url: <Callback Url String>
|
||||
}
|
||||
*/
|
||||
module.exports = ({url}) => {
|
||||
|
|
@ -28,42 +32,28 @@ module.exports = ({url}) => {
|
|||
throw new Error('ExpectedLnurlOrLightningAddressToParse');
|
||||
}
|
||||
|
||||
// Check if its a valid email address
|
||||
if (!!testEmail(url)) {
|
||||
const [username, domain] = url.split('@');
|
||||
// Exit early when the URL looks like an email, indicating lightning address
|
||||
if (!!isEmail(url)) {
|
||||
const [username, domain] = parseEmail(url);
|
||||
|
||||
// Check if the user name is valid
|
||||
if (!testUsername(username)) {
|
||||
if (!isUsername(username)) {
|
||||
throw new Error('ExpectedValidUsernameInLightningAddress');
|
||||
}
|
||||
|
||||
// Because of restrictions on the HTTP request library, disallow onion URLs
|
||||
if (!!isOnion(domain)) {
|
||||
throw new Error('ExpectedValidClearnetLightningAddress');
|
||||
throw new Error('LnurlOnionUrlsCurrentlyUnsupported');
|
||||
}
|
||||
|
||||
const callbackUrl = [
|
||||
sslProtocol,
|
||||
domain,
|
||||
urlString,
|
||||
username,
|
||||
];
|
||||
|
||||
return callbackUrl.join('');
|
||||
return {url: join([sslProtocol, domain, urlString, username])};
|
||||
}
|
||||
|
||||
// Check for lnurl is valid
|
||||
try {
|
||||
decode(asLnurl(url), bech32CharLimit);
|
||||
} catch (err) {
|
||||
throw new Error(400, 'FailedToDecodeLnurl', {err});
|
||||
}
|
||||
|
||||
|
||||
if (decode(asLnurl(url), bech32CharLimit).prefix !== prefix) {
|
||||
throw new Error(400, 'ExpectedLnUrlPrefix');
|
||||
throw new Error('ExpectedLnurlPrefix');
|
||||
}
|
||||
|
||||
const {words} = decode(asLnurl(url), bech32CharLimit);
|
||||
|
||||
return wordsAsUtf8(words);
|
||||
}
|
||||
return {url: wordsAsUtf8(words)};
|
||||
};
|
||||
|
|
|
|||
32
lnurl/pay.js
32
lnurl/pay.js
|
|
@ -1,7 +1,6 @@
|
|||
const {createHash} = require('crypto');
|
||||
|
||||
const asyncAuto = require('async/auto');
|
||||
const {bech32} = require('bech32');
|
||||
const {getNodeAlias} = require('ln-sync');
|
||||
const moment = require('moment');
|
||||
const {returnResult} = require('asyncjs-util');
|
||||
|
|
@ -10,10 +9,6 @@ const {parsePaymentRequest} = require('ln-service');
|
|||
const parseUrl = require('./parse_url');
|
||||
const {pay} = require('./../network');
|
||||
|
||||
const asLnurl = n => n.substring(n.startsWith('lightning:') ? 10 : 0);
|
||||
const bech32CharLimit = 2000;
|
||||
const {decode} = bech32;
|
||||
const emailPattern = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/;
|
||||
const errorStatus = 'ERROR';
|
||||
const {isArray} = Array;
|
||||
const isNumber = n => !isNaN(n);
|
||||
|
|
@ -24,11 +19,9 @@ const minMinSendable = 1;
|
|||
const mtokensAsTokens = n => Math.floor(n / 1000);
|
||||
const {parse} = JSON;
|
||||
const payRequestTag = 'payRequest';
|
||||
const prefix = 'lnurl';
|
||||
const {round} = Math;
|
||||
const sha256 = n => createHash('sha256').update(n).digest().toString('hex');
|
||||
const sslProtocol = 'https:';
|
||||
const testEmail = n => emailPattern.test(n);
|
||||
const textPlain = 'text/plain';
|
||||
const tokensAsBigUnit = tokens => (tokens / 1e8).toFixed(8);
|
||||
const tokensAsMillitokens = n => n * 1000;
|
||||
|
|
@ -64,16 +57,10 @@ module.exports = (args, cbk) => {
|
|||
return cbk([400, 'ExpectedUrlToGetPaymentRequestFromLnurl']);
|
||||
}
|
||||
|
||||
if (!testEmail(args.lnurl)) {
|
||||
try {
|
||||
decode(asLnurl(args.lnurl), bech32CharLimit);
|
||||
} catch (err) {
|
||||
return cbk([400, 'FailedToDecodeLnurlOrLightningAddressToPay']);
|
||||
}
|
||||
}
|
||||
|
||||
if (!testEmail(args.lnurl) && decode(asLnurl(args.lnurl), bech32CharLimit).prefix !== prefix) {
|
||||
return cbk([400, 'ExpectedLnUrlPrefixToPay']);
|
||||
try {
|
||||
parseUrl({url: args.lnurl});
|
||||
} catch (err) {
|
||||
return cbk([400, err.message]);
|
||||
}
|
||||
|
||||
if (!args.lnd) {
|
||||
|
|
@ -103,16 +90,9 @@ module.exports = (args, cbk) => {
|
|||
return cbk();
|
||||
},
|
||||
|
||||
// Get the call back url
|
||||
getCallBackUrl: ['validate', ({}, cbk) => {
|
||||
const url = parseUrl({url: args.lnurl});
|
||||
|
||||
return cbk(null, url);
|
||||
}],
|
||||
|
||||
// Get accepted terms from the encoded url
|
||||
getTerms: ['getCallBackUrl', ({getCallBackUrl}, cbk) => {
|
||||
const url = getCallBackUrl;
|
||||
getTerms: ['validate', ({}, cbk) => {
|
||||
const {url} = parseUrl({url: args.lnurl});
|
||||
|
||||
return args.request({url, json: true}, (err, r, json) => {
|
||||
if (!!err) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue