Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
beforeEach(() => {
// boltwall sets up authenticated client when it boots up
// need to stub this to avoid connection errors and speed up tests
lndGrpcStub = getLnStub('authenticatedLndGrpc', { lnd: {} })
// keep known session secret so we can decode macaroons
sessionSecret = 'my super secret'
envStub = getEnvStub(sessionSecret)
const request = parsePaymentRequest({ request: invoice.payreq })
// stubbed response for invoice related requests made through ln-service
invoiceResponse = {
request: invoice.payreq,
is_confirmed: true,
id: request.id,
secret: invoice.secret,
tokens: 30,
created_at: '2016-08-29T09:12:33.001Z',
description: request.description,
}
builder = getTestBuilder(sessionSecret)
getInvStub = getLnStub('getInvoice', invoiceResponse)
createInvStub = getLnStub('createInvoice', {
// check if we're looking at the invoice challenge
if (!invoice.length && c.indexOf(invoiceChallenge) > -1) {
const split = c.split('=')
assert(split.length === 2, 'Incorrectly encoded invoice challenge')
invoice = split[split.length - 1].trim()
}
// if there are other challenges but we have mac and invoice then we can break
// as they are not LSAT relevant anyway
if (invoice.length && macaroon.length) break
}
assert(
invoice.length && macaroon.length,
'Expected base64 encoded challenge with macaroon and invoice data'
)
const request = parsePaymentRequest({ request: invoice })
const paymentHash = request.id
const { identifier } = MacaroonsBuilder.deserialize(macaroon)
return new this({
id: identifier,
baseMacaroon: macaroon,
paymentHash,
invoice: invoice,
})
}
beforeEach(() => {
expiration = Date.now() + 1000
const caveat = new Caveat({ condition: 'expiration', value: expiration })
const request = parsePaymentRequest({ request: invoice.payreq })
paymentHash = request.id
paymentPreimage = invoice.secret
const builder = getTestBuilder('secret')
macaroon = builder
.add_first_party_caveat(caveat.encode())
.getMacaroon()
.serialize()
challenge = `macaroon=${macaroon}, invoice=${invoice.payreq}`
challenge = Buffer.from(challenge, 'utf8').toString('base64')
challengeWithSpace = `macaroon=${macaroon} invoice=${invoice.payreq}`
challengeWithSpace = Buffer.from(challengeWithSpace, 'utf8').toString(
'base64'
)
version: 'version',
uris: [''],
}
nodeInfo.uris = [`${nodeInfo.public_key}@127.0.0.1:19735`]
export const invoice = {
payreq:
'lntb10u1pw7kfm8pp50nhe8uk9r2n9yz97c9z8lsu0ckxehnsnwkjn9mdsmnf' +
'fpgkrxzhqdq5w3jhxapqd9h8vmmfvdjscqzpgllq2qvdlgkllc27kpd87lz8p' +
'dfsfmtteyc3kwq734jpwnvqt96e4nuy0yauzdrtkumxsvawgda8dlljxu3nnj' +
'lhs6w75390wy7ukj6cpfmygah',
secret: '2ca931a1c36b48f54948b898a271a53ed91ff7d0081939a5fa511249e81cba5c',
}
const request = parsePaymentRequest({ request: invoice.payreq })
export interface InvoiceResponseStub {
request: string
is_confirmed: boolean
is_held?: boolean | undefined
id: string
secret: string
tokens: number
created_at: string
description: string
}
export const invoiceResponse: InvoiceResponseStub = {
request: invoice.payreq,
is_confirmed: true,
id: request.id,
export function getTestBuilder(secret: string): BuilderInterface {
const request = lnService.parsePaymentRequest({ request: invoice.payreq })
const identifier = new Identifier({
paymentHash: Buffer.from(request.id, 'hex'),
tokenId: randomBytes(32),
})
const builder = new MacaroonsBuilder(
'location',
secret,
identifier.toString()
)
return builder
}
.forEach(payment => {
const elements = [];
const node = findNode(payment.destination);
const {request} = payment;
elements.push({
subtitle: moment(payment.created_at).fromNow(),
title: node.alias || payment.destination,
});
elements.push({action: 'Sent payment'});
if (payment.request) {
elements.push({
details: `"${parsePaymentRequest({request}).description}"`,
});
}
elements.push({
details: `Sent: ${formatAsBigUnit(payment.tokens)} ${currency}`,
});
return activity.push({elements, date: payment.created_at});
});
module.exports = ({request}) => {
let details;
let network;
try {
details = parsePaymentRequest({request});
} catch (err) {
throw new Error('ExpectedValidRequestToParse');
}
switch (details.network) {
case 'bitcoin':
case 'regtest':
case 'testnet':
network = details.network;
break;
case 'litecoin':
network = 'ltc';
break;
default:
parsedInvoice: (cbk) => {
if (!invoice) {
return cbk([400, 'ExpectedInvoiceForInvoiceDetails']);
}
if (!network) {
return cbk([400, 'ExpectedNetworkForInvoiceDetails']);
}
let parsed;
try {
parsed = parsePaymentRequest({ request: invoice });
} catch (e) {
return cbk([400, 'DecodeInvoiceFailure']);
}
if (parsed.is_expired) {
return cbk([400, 'InvoiceIsExpired']);
}
const now = Date.now();
const expiry = Date.parse(parsed.expires_at);
if (expiry - now < 1000 * 60 * 20) {
return cbk([400, 'InvoiceExpiresTooSoon']);
}
if (parsed.tokens < minLNInvoiceAmount) {
return cbk([400, 'InvoiceAmountTooSmall']);
try {
id = Identifier.fromString(identifier)
} catch (e) {
throw new Error(
`Unexpected encoding for macaroon identifier: ${e.message}`
)
}
const options: LsatOptions = {
id: identifier,
baseMacaroon: macaroon,
paymentHash: id.paymentHash.toString('hex'),
}
if (invoice) {
const { id: paymentHash, tokens } = parsePaymentRequest({
request: invoice,
})
assert(
paymentHash === id.paymentHash.toString('hex'),
'paymentHash from invoice did not match invoice'
)
options.amountPaid = tokens
options.invoice = invoice
}
return new this(options)
}
decodeRequest: ['lnd', ({lnd}, cbk) => {
try {
return cbk(null, parsePaymentRequest({request}));
} catch (err) {
return cbk([400, 'FailedToDecodePayReq', err]);
}
}],