commit
831ca1c77d
5 changed files with 403 additions and 184 deletions
33
.vscode/snippets.code-snippets
vendored
Normal file
33
.vscode/snippets.code-snippets
vendored
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
{
|
||||||
|
// Place your api workspace snippets here. Each snippet is defined under a
|
||||||
|
// snippet name and has a scope, prefix, body and description. Add comma
|
||||||
|
// separated ids of the languages where the snippet is applicable in the scope
|
||||||
|
// field. If scope is left empty or omitted, the snippet gets applied to all
|
||||||
|
// languages. The prefix is what is used to trigger the snippet and the body
|
||||||
|
// will be expanded and inserted. Possible variables are: $1, $2 for tab
|
||||||
|
// stops, $0 for the final cursor position, and ${1:label}, ${2:another} for
|
||||||
|
// placeholders. Placeholders with the same ids are connected. Example: "Print
|
||||||
|
// to console": {"scope": "javascript,typescript", "prefix": "log", "body":
|
||||||
|
// ["console.log('$1');", "$2"
|
||||||
|
// ],
|
||||||
|
// "description": "Log output to console"
|
||||||
|
// }
|
||||||
|
|
||||||
|
"Route Body": {
|
||||||
|
"body": [
|
||||||
|
"try {",
|
||||||
|
" return res.json({",
|
||||||
|
"",
|
||||||
|
" })",
|
||||||
|
"} catch (e) {",
|
||||||
|
" console.log(e)",
|
||||||
|
" return res.status(500).json({",
|
||||||
|
" errorMessage: e.message",
|
||||||
|
" })",
|
||||||
|
"}"
|
||||||
|
],
|
||||||
|
"description": "Route Body",
|
||||||
|
"prefix": "rbody",
|
||||||
|
"scope": "javascript"
|
||||||
|
}
|
||||||
|
}
|
||||||
281
src/routes.js
281
src/routes.js
|
|
@ -30,11 +30,7 @@ const {
|
||||||
const GunActions = require('../services/gunDB/contact-api/actions')
|
const GunActions = require('../services/gunDB/contact-api/actions')
|
||||||
const GunGetters = require('../services/gunDB/contact-api/getters')
|
const GunGetters = require('../services/gunDB/contact-api/getters')
|
||||||
const GunKey = require('../services/gunDB/contact-api/key')
|
const GunKey = require('../services/gunDB/contact-api/key')
|
||||||
const {
|
const LV2 = require('../utils/lightningServices/v2')
|
||||||
sendPaymentV2Keysend,
|
|
||||||
sendPaymentV2Invoice,
|
|
||||||
listPayments
|
|
||||||
} = require('../utils/lightningServices/v2')
|
|
||||||
const GunWriteRPC = require('../services/gunDB/rpc')
|
const GunWriteRPC = require('../services/gunDB/rpc')
|
||||||
|
|
||||||
const DEFAULT_MAX_NUM_ROUTES_TO_QUERY = 10
|
const DEFAULT_MAX_NUM_ROUTES_TO_QUERY = 10
|
||||||
|
|
@ -1024,30 +1020,15 @@ module.exports = async (
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
// get lnd chan info
|
// get lnd chan info
|
||||||
app.post('/api/lnd/getchaninfo', (req, res) => {
|
app.post('/api/lnd/getchaninfo', async (req, res) => {
|
||||||
const { lightning } = LightningServices.services
|
try {
|
||||||
|
return res.json(await LV2.getChanInfo(req.body.chan_id))
|
||||||
lightning.getChanInfo(
|
} catch (e) {
|
||||||
{ chan_id: req.body.chan_id },
|
console.log(e)
|
||||||
async (err, response) => {
|
return res.status(500).json({
|
||||||
if (err) {
|
errorMessage: e.message
|
||||||
logger.debug('GetChanInfo Error:', err)
|
})
|
||||||
const health = await checkHealth()
|
}
|
||||||
if (health.LNDStatus.success) {
|
|
||||||
res.status(400)
|
|
||||||
res.json({
|
|
||||||
field: 'getChanInfo',
|
|
||||||
errorMessage: sanitizeLNDError(err.message)
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
res.status(500)
|
|
||||||
res.json({ errorMessage: 'LND is down' })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
logger.debug('GetChanInfo:', response)
|
|
||||||
res.json(response)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
app.get('/api/lnd/getnetworkinfo', (req, res) => {
|
app.get('/api/lnd/getnetworkinfo', (req, res) => {
|
||||||
|
|
@ -1072,47 +1053,30 @@ module.exports = async (
|
||||||
})
|
})
|
||||||
|
|
||||||
// get lnd node active channels list
|
// get lnd node active channels list
|
||||||
app.get('/api/lnd/listpeers', (req, res) => {
|
app.get('/api/lnd/listpeers', async (req, res) => {
|
||||||
const { lightning } = LightningServices.services
|
try {
|
||||||
lightning.listPeers({}, async (err, response) => {
|
return res.json({
|
||||||
if (err) {
|
peers: await LV2.listPeers(req.body.latestError)
|
||||||
logger.debug('ListPeers Error:', err)
|
})
|
||||||
const health = await checkHealth()
|
} catch (e) {
|
||||||
if (health.LNDStatus.success) {
|
console.log(e)
|
||||||
res.status(400).json({
|
return res.status(500).json({
|
||||||
field: 'listPeers',
|
errorMessage: e.message
|
||||||
errorMessage: sanitizeLNDError(err.message)
|
})
|
||||||
})
|
}
|
||||||
} else {
|
|
||||||
res.status(500)
|
|
||||||
res.json({ errorMessage: 'LND is down' })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
logger.debug('ListPeers:', response)
|
|
||||||
res.json(response)
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
|
|
||||||
// newaddress
|
// newaddress
|
||||||
app.post('/api/lnd/newaddress', (req, res) => {
|
app.post('/api/lnd/newaddress', async (req, res) => {
|
||||||
const { lightning } = LightningServices.services
|
try {
|
||||||
lightning.newAddress({ type: req.body.type }, async (err, response) => {
|
return res.json({
|
||||||
if (err) {
|
address: await LV2.newAddress(req.body.type)
|
||||||
logger.debug('NewAddress Error:', err)
|
})
|
||||||
const health = await checkHealth()
|
} catch (e) {
|
||||||
if (health.LNDStatus.success) {
|
return res.status(500).json({
|
||||||
res.status(400).json({
|
errorMessage: e.message
|
||||||
field: 'newAddress',
|
})
|
||||||
errorMessage: sanitizeLNDError(err.message)
|
}
|
||||||
})
|
|
||||||
} else {
|
|
||||||
res.status(500)
|
|
||||||
res.json({ errorMessage: 'LND is down' })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
logger.debug('NewAddress:', response)
|
|
||||||
res.json(response)
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
|
|
||||||
// connect peer to lnd node
|
// connect peer to lnd node
|
||||||
|
|
@ -1157,47 +1121,28 @@ module.exports = async (
|
||||||
})
|
})
|
||||||
|
|
||||||
// get lnd node opened channels list
|
// get lnd node opened channels list
|
||||||
app.get('/api/lnd/listchannels', (req, res) => {
|
app.get('/api/lnd/listchannels', async (_, res) => {
|
||||||
const { lightning } = LightningServices.services
|
try {
|
||||||
lightning.listChannels({}, async (err, response) => {
|
return res.json({
|
||||||
if (err) {
|
channels: await LV2.listChannels()
|
||||||
logger.debug('ListChannels Error:', err)
|
})
|
||||||
const health = await checkHealth()
|
} catch (e) {
|
||||||
if (health.LNDStatus.success) {
|
console.log(e)
|
||||||
res.status(400).json({
|
return res.status(500).json({
|
||||||
field: 'listChannels',
|
errorMessage: e.message
|
||||||
errorMessage: sanitizeLNDError(err.message)
|
})
|
||||||
})
|
}
|
||||||
} else {
|
|
||||||
res.status(500)
|
|
||||||
res.json({ errorMessage: 'LND is down' })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
logger.debug('ListChannels:', response)
|
|
||||||
res.json(response)
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
|
|
||||||
// get lnd node pending channels list
|
app.get('/api/lnd/pendingchannels', async (req, res) => {
|
||||||
app.get('/api/lnd/pendingchannels', (req, res) => {
|
try {
|
||||||
const { lightning } = LightningServices.services
|
return res.json(await LV2.pendingChannels())
|
||||||
lightning.pendingChannels({}, async (err, response) => {
|
} catch (e) {
|
||||||
if (err) {
|
console.log(e)
|
||||||
logger.debug('PendingChannels Error:', err)
|
return res.status(500).json({
|
||||||
const health = await checkHealth()
|
errorMessage: e.message
|
||||||
if (health.LNDStatus.success) {
|
})
|
||||||
res.status(400).json({
|
}
|
||||||
field: 'pendingChannels',
|
|
||||||
errorMessage: sanitizeLNDError(err.message)
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
res.status(500)
|
|
||||||
res.json({ errorMessage: 'LND is down' })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
logger.debug('PendingChannels:', response)
|
|
||||||
res.json(response)
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
|
|
||||||
app.get('/api/lnd/unifiedTrx', (req, res) => {
|
app.get('/api/lnd/unifiedTrx', (req, res) => {
|
||||||
|
|
@ -1375,7 +1320,7 @@ module.exports = async (
|
||||||
}
|
}
|
||||||
|
|
||||||
return res.status(200).json(
|
return res.status(200).json(
|
||||||
await listPayments({
|
await LV2.listPayments({
|
||||||
include_incomplete,
|
include_incomplete,
|
||||||
index_offset,
|
index_offset,
|
||||||
max_payments,
|
max_payments,
|
||||||
|
|
@ -1662,7 +1607,7 @@ module.exports = async (
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const payment = await sendPaymentV2Keysend({
|
const payment = await LV2.sendPaymentV2Keysend({
|
||||||
amt,
|
amt,
|
||||||
dest,
|
dest,
|
||||||
feeLimit,
|
feeLimit,
|
||||||
|
|
@ -1675,7 +1620,7 @@ module.exports = async (
|
||||||
}
|
}
|
||||||
const { payreq } = req.body
|
const { payreq } = req.body
|
||||||
|
|
||||||
const payment = await sendPaymentV2Invoice({
|
const payment = await LV2.sendPaymentV2Invoice({
|
||||||
feeLimit,
|
feeLimit,
|
||||||
payment_request: payreq,
|
payment_request: payreq,
|
||||||
amt: req.body.amt,
|
amt: req.body.amt,
|
||||||
|
|
@ -1764,64 +1709,32 @@ module.exports = async (
|
||||||
})
|
})
|
||||||
|
|
||||||
// addinvoice
|
// addinvoice
|
||||||
app.post('/api/lnd/addinvoice', (req, res) => {
|
app.post('/api/lnd/addinvoice', async (req, res) => {
|
||||||
const { lightning } = LightningServices.services
|
const { expiry, value, memo } = req.body
|
||||||
const invoiceRequest = { memo: req.body.memo, private: true }
|
const addInvoiceRes = await LV2.addInvoice(value, memo, true, expiry)
|
||||||
if (req.body.value) {
|
|
||||||
invoiceRequest.value = req.body.value
|
if (value) {
|
||||||
}
|
const channelsList = await LV2.listChannels({ active_only: true })
|
||||||
if (req.body.expiry) {
|
let remoteBalance = Big(0)
|
||||||
invoiceRequest.expiry = req.body.expiry
|
channelsList.forEach(element => {
|
||||||
}
|
const remB = Big(element.remote_balance)
|
||||||
lightning.addInvoice(invoiceRequest, async (err, newInvoice) => {
|
if (remB.gt(remoteBalance)) {
|
||||||
if (err) {
|
remoteBalance = remB
|
||||||
logger.debug('AddInvoice Error:', err)
|
|
||||||
const health = await checkHealth()
|
|
||||||
if (health.LNDStatus.success) {
|
|
||||||
res.status(400).json({
|
|
||||||
field: 'addInvoice',
|
|
||||||
errorMessage: sanitizeLNDError(err.message)
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
res.status(500)
|
|
||||||
res.json({ errorMessage: 'LND is down' })
|
|
||||||
}
|
}
|
||||||
return err
|
})
|
||||||
}
|
|
||||||
logger.debug('AddInvoice:', newInvoice)
|
addInvoiceRes.liquidityCheck = remoteBalance > value
|
||||||
if (req.body.value) {
|
//newInvoice.remoteBalance = remoteBalance
|
||||||
logger.debug('AddInvoice liquidity check:')
|
}
|
||||||
lightning.listChannels({ active_only: true }, async (err, response) => {
|
|
||||||
if (err) {
|
try {
|
||||||
logger.debug('ListChannels Error:', err)
|
return res.json(addInvoiceRes)
|
||||||
const health = await checkHealth()
|
} catch (e) {
|
||||||
if (health.LNDStatus.success) {
|
console.log(e)
|
||||||
res.status(400).json({
|
return res.status(500).json({
|
||||||
field: 'listChannels',
|
errorMessage: e.message
|
||||||
errorMessage: sanitizeLNDError(err.message)
|
})
|
||||||
})
|
}
|
||||||
} else {
|
|
||||||
res.status(500)
|
|
||||||
res.json({ errorMessage: 'LND is down' })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
logger.debug('ListChannels:', response)
|
|
||||||
const channelsList = response.channels
|
|
||||||
let remoteBalance = Big(0)
|
|
||||||
channelsList.forEach(element => {
|
|
||||||
const remB = Big(element.remote_balance)
|
|
||||||
if (remB.gt(remoteBalance)) {
|
|
||||||
remoteBalance = remB
|
|
||||||
}
|
|
||||||
})
|
|
||||||
newInvoice.liquidityCheck = remoteBalance > req.body.value
|
|
||||||
//newInvoice.remoteBalance = remoteBalance
|
|
||||||
res.json(newInvoice)
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
res.json(newInvoice)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
|
|
||||||
// signmessage
|
// signmessage
|
||||||
|
|
@ -1959,23 +1872,25 @@ module.exports = async (
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
app.post('/api/lnd/listunspent', (req, res) => {
|
const listunspent = async (req, res) => {
|
||||||
const { lightning } = LightningServices.services
|
try {
|
||||||
const { minConfirmations = 3, maxConfirmations = 6 } = req.body
|
return res.status(200).json({
|
||||||
lightning.listUnspent(
|
utxos: await LV2.listUnspent(
|
||||||
{
|
req.body.minConfirmations,
|
||||||
min_confs: minConfirmations,
|
req.body.maxConfirmations
|
||||||
max_confs: maxConfirmations
|
)
|
||||||
},
|
})
|
||||||
(err, unspent) => {
|
} catch (e) {
|
||||||
if (err) {
|
return res.status(500).json({
|
||||||
return handleError(res, err)
|
errorMessage: e.message
|
||||||
}
|
})
|
||||||
logger.debug('ListUnspent:', unspent)
|
}
|
||||||
res.json(unspent)
|
}
|
||||||
}
|
|
||||||
)
|
app.get('/api/lnd/listunspent', listunspent)
|
||||||
})
|
|
||||||
|
// TODO: should be GET
|
||||||
|
app.post('/api/lnd/listunspent', listunspent)
|
||||||
|
|
||||||
app.get('/api/lnd/transactions', (req, res) => {
|
app.get('/api/lnd/transactions', (req, res) => {
|
||||||
const { lightning } = LightningServices.services
|
const { lightning } = LightningServices.services
|
||||||
|
|
|
||||||
|
|
@ -74,6 +74,13 @@ class LightningServices {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns {import('./types').Services}
|
||||||
|
*/
|
||||||
|
getServices() {
|
||||||
|
return this.services
|
||||||
|
}
|
||||||
|
|
||||||
get servicesData() {
|
get servicesData() {
|
||||||
return this.lnServicesData
|
return this.lnServicesData
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
/**
|
/**
|
||||||
* @format
|
* @format
|
||||||
*/
|
*/
|
||||||
|
import * as Common from 'shock-common'
|
||||||
|
|
||||||
export interface PaymentV2 {
|
export interface PaymentV2 {
|
||||||
payment_hash: string
|
payment_hash: string
|
||||||
|
|
@ -106,3 +107,90 @@ export interface SendPaymentInvoiceParams {
|
||||||
payment_request: string
|
payment_request: string
|
||||||
timeoutSeconds?: number
|
timeoutSeconds?: number
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type StreamListener = (data: any) => void
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Caution: Not all methods return an stream.
|
||||||
|
*/
|
||||||
|
interface LightningStream {
|
||||||
|
on(ev: 'data' | 'end' | 'error' | 'status', listener: StreamListener): void
|
||||||
|
}
|
||||||
|
|
||||||
|
type LightningCB = (err: Error, data: Record<string, any>) => void
|
||||||
|
|
||||||
|
type LightningMethod = (
|
||||||
|
args: Record<string, any>,
|
||||||
|
cb?: LightningCB
|
||||||
|
) => LightningStream
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Makes it easier for code calling services.
|
||||||
|
*/
|
||||||
|
export interface Services {
|
||||||
|
lightning: Record<string, LightningMethod>
|
||||||
|
walletUnlocker: Record<string, LightningMethod>
|
||||||
|
router: Record<string, LightningMethod>
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ListChannelsReq {
|
||||||
|
active_only: boolean
|
||||||
|
inactive_only: boolean
|
||||||
|
public_only: boolean
|
||||||
|
private_only: boolean
|
||||||
|
/**
|
||||||
|
* Filters the response for channels with a target peer's pubkey. If peer is
|
||||||
|
* empty, all channels will be returned.
|
||||||
|
*/
|
||||||
|
peer: Common.Bytes
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* https://api.lightning.community/#pendingchannels
|
||||||
|
*/
|
||||||
|
export interface PendingChannelsRes {
|
||||||
|
/**
|
||||||
|
* The balance in satoshis encumbered in pending channels.
|
||||||
|
*/
|
||||||
|
total_limbo_balance: string
|
||||||
|
/**
|
||||||
|
* Channels pending opening.
|
||||||
|
*/
|
||||||
|
pending_open_channels: Common.PendingOpenChannel[]
|
||||||
|
/**
|
||||||
|
* Channels pending force closing.
|
||||||
|
*/
|
||||||
|
pending_force_closing_channels: Common.ForceClosedChannel[]
|
||||||
|
/**
|
||||||
|
* Channels waiting for closing tx to confirm.
|
||||||
|
*/
|
||||||
|
waiting_close_channels: Common.WaitingCloseChannel[]
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* https://github.com/lightningnetwork/lnd/blob/daf7c8a85420fc67fffa18fa5f7d08c2040946e4/lnrpc/rpc.proto#L2948
|
||||||
|
*/
|
||||||
|
export interface AddInvoiceRes {
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
r_hash: Common.Bytes
|
||||||
|
/**
|
||||||
|
* A bare-bones invoice for a payment within the Lightning Network. With the
|
||||||
|
* details of the invoice, the sender has all the data necessary to send a
|
||||||
|
* payment to the recipient.
|
||||||
|
*/
|
||||||
|
payment_request: string
|
||||||
|
/**
|
||||||
|
* The "add" index of this invoice. Each newly created invoice will increment
|
||||||
|
* this index making it monotonically increasing. Callers to the
|
||||||
|
* SubscribeInvoices call can use this to instantly get notified of all added
|
||||||
|
* invoices with an add_index greater than this one.
|
||||||
|
*/
|
||||||
|
add_index: string
|
||||||
|
/**
|
||||||
|
* The payment address of the generated invoice. This value should be used in
|
||||||
|
* all payments for this invoice as we require it for end to end security.
|
||||||
|
*/
|
||||||
|
payment_addr: Common.Bytes
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -402,9 +402,185 @@ const decodePayReq = payReq =>
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {0|1} type
|
||||||
|
* @returns {Promise<string>}
|
||||||
|
*/
|
||||||
|
const newAddress = (type = 0) => {
|
||||||
|
const { lightning } = lightningServices.getServices()
|
||||||
|
|
||||||
|
return Common.Utils.makePromise((res, rej) => {
|
||||||
|
lightning.newAddress({ type }, (err, response) => {
|
||||||
|
if (err) {
|
||||||
|
rej(new Error(err.message))
|
||||||
|
} else {
|
||||||
|
res(response.address)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {number} minConfs
|
||||||
|
* @param {number} maxConfs
|
||||||
|
* @returns {Promise<Common.Utxo[]>}
|
||||||
|
*/
|
||||||
|
const listUnspent = (minConfs = 3, maxConfs = 6) =>
|
||||||
|
Common.makePromise((res, rej) => {
|
||||||
|
const { lightning } = lightningServices.getServices()
|
||||||
|
|
||||||
|
lightning.listUnspent(
|
||||||
|
{
|
||||||
|
min_confs: minConfs,
|
||||||
|
max_confs: maxConfs
|
||||||
|
},
|
||||||
|
(err, unspent) => {
|
||||||
|
if (err) {
|
||||||
|
rej(new Error(err.message))
|
||||||
|
} else {
|
||||||
|
res(unspent.utxos)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {import('./types').ListChannelsReq} ListChannelsReq
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {ListChannelsReq} req
|
||||||
|
* @returns {Promise<Common.Channel[]>}
|
||||||
|
*/
|
||||||
|
const listChannels = req =>
|
||||||
|
Common.makePromise((res, rej) => {
|
||||||
|
const { lightning } = lightningServices.getServices()
|
||||||
|
|
||||||
|
lightning.listChannels(req, (err, resp) => {
|
||||||
|
if (err) {
|
||||||
|
rej(new Error(err.message))
|
||||||
|
} else {
|
||||||
|
res(resp.channels)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
* https://api.lightning.community/#getchaninfo
|
||||||
|
* @param {string} chanID
|
||||||
|
* @returns {Promise<Common.ChannelEdge>}
|
||||||
|
*/
|
||||||
|
const getChanInfo = chanID =>
|
||||||
|
Common.makePromise((res, rej) => {
|
||||||
|
const { lightning } = lightningServices.getServices()
|
||||||
|
|
||||||
|
lightning.getChanInfo(
|
||||||
|
{
|
||||||
|
chan_id: chanID
|
||||||
|
},
|
||||||
|
(err, resp) => {
|
||||||
|
if (err) {
|
||||||
|
rej(new Error(err.message))
|
||||||
|
} else {
|
||||||
|
// Needs cast because typescript refuses to assign Record<string, any>
|
||||||
|
// to an actual object :shrugs
|
||||||
|
res(/** @type {Common.ChannelEdge} */ (resp))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
* https://api.lightning.community/#listpeers
|
||||||
|
* @param {boolean=} latestError If true, only the last error that our peer sent
|
||||||
|
* us will be returned with the peer's information, rather than the full set of
|
||||||
|
* historic errors we have stored.
|
||||||
|
* @returns {Promise<Common.Peer[]>}
|
||||||
|
*/
|
||||||
|
const listPeers = latestError =>
|
||||||
|
Common.makePromise((res, rej) => {
|
||||||
|
const { lightning } = lightningServices.getServices()
|
||||||
|
|
||||||
|
lightning.listPeers(
|
||||||
|
{
|
||||||
|
latest_error: latestError
|
||||||
|
},
|
||||||
|
(err, resp) => {
|
||||||
|
if (err) {
|
||||||
|
rej(new Error(err.message))
|
||||||
|
} else {
|
||||||
|
res(resp.peers)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {import('./types').PendingChannelsRes} PendingChannelsRes
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns {Promise<PendingChannelsRes>}
|
||||||
|
*/
|
||||||
|
const pendingChannels = () =>
|
||||||
|
Common.makePromise((res, rej) => {
|
||||||
|
const { lightning } = lightningServices.getServices()
|
||||||
|
|
||||||
|
lightning.pendingChannels({}, (err, resp) => {
|
||||||
|
if (err) {
|
||||||
|
rej(new Error(err.message))
|
||||||
|
} else {
|
||||||
|
// Needs cast because typescript refuses to assign Record<string, any>
|
||||||
|
// to an actual object :shrugs
|
||||||
|
res(/** @type {PendingChannelsRes} */ (resp))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {import('./types').AddInvoiceRes} AddInvoiceRes
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* https://api.lightning.community/#addinvoice
|
||||||
|
* @param {number} value
|
||||||
|
* @param {string=} memo
|
||||||
|
* @param {boolean=} confidential Alias for `private`.
|
||||||
|
* @param {number=} expiry
|
||||||
|
* @returns {Promise<AddInvoiceRes>}
|
||||||
|
*/
|
||||||
|
const addInvoice = (value, memo = '', confidential = true, expiry = 180) =>
|
||||||
|
Common.makePromise((res, rej) => {
|
||||||
|
const { lightning } = lightningServices.getServices()
|
||||||
|
|
||||||
|
lightning.addInvoice(
|
||||||
|
{
|
||||||
|
value,
|
||||||
|
memo,
|
||||||
|
private: confidential,
|
||||||
|
expiry
|
||||||
|
},
|
||||||
|
(err, resp) => {
|
||||||
|
if (err) {
|
||||||
|
rej(new Error(err.message))
|
||||||
|
} else {
|
||||||
|
// Needs cast because typescript refuses to assign Record<string, any>
|
||||||
|
// to an actual object :shrugs
|
||||||
|
res(/** @type {AddInvoiceRes} */ (resp))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
sendPaymentV2Keysend,
|
sendPaymentV2Keysend,
|
||||||
sendPaymentV2Invoice,
|
sendPaymentV2Invoice,
|
||||||
listPayments,
|
listPayments,
|
||||||
decodePayReq
|
decodePayReq,
|
||||||
|
newAddress,
|
||||||
|
listUnspent,
|
||||||
|
listChannels,
|
||||||
|
getChanInfo,
|
||||||
|
listPeers,
|
||||||
|
pendingChannels,
|
||||||
|
addInvoice
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue