19 Commits

Author SHA1 Message Date
9b81cc6287 Store and return invoice memo 2022-03-01 21:54:52 -06:00
947c7f7056 Fix onchain txs not being accounted for 2022-03-01 21:52:59 -06:00
9563cb9714 Merge branch 'BlueWallet:master' into master 2021-11-05 21:10:00 +02:00
Overtorment
aca47a23e9 ref 2021-10-28 14:25:51 +01:00
Overtorment
53361d2e3a FIX: process locked script would wrongfully evict successfull payment 2021-10-28 14:00:31 +01:00
snyk-bot
ac4461c7f3 fix: upgrade express-rate-limit from 5.3.0 to 5.4.1
Snyk has created this PR to upgrade express-rate-limit from 5.3.0 to 5.4.1.

See this package in npm:
https://www.npmjs.com/package/express-rate-limit

See this project in Snyk:
https://app.snyk.io/org/bluewallet/project/29c066bc-abce-44d9-b68e-064466e610e7?utm_source=github&utm_medium=referral&page=upgrade-pr
2021-10-27 20:13:20 +01:00
snyk-bot
b7d106b499 fix: upgrade ioredis from 4.27.9 to 4.27.10
Snyk has created this PR to upgrade ioredis from 4.27.9 to 4.27.10.

See this package in npm:
https://www.npmjs.com/package/ioredis

See this project in Snyk:
https://app.snyk.io/org/bluewallet/project/29c066bc-abce-44d9-b68e-064466e610e7?utm_source=github&utm_medium=referral&page=upgrade-pr
2021-10-27 20:12:49 +01:00
ac2061c6ed Add support to pass description_hash to LND 2021-10-19 20:22:31 +02:00
snyk-bot
14478becae fix: upgrade @grpc/proto-loader from 0.6.4 to 0.6.5
Snyk has created this PR to upgrade @grpc/proto-loader from 0.6.4 to 0.6.5.

See this package in npm:
https://www.npmjs.com/package/@grpc/proto-loader

See this project in Snyk:
https://app.snyk.io/org/bluewallet/project/29c066bc-abce-44d9-b68e-064466e610e7?utm_source=github&utm_medium=referral&page=upgrade-pr
2021-10-05 15:52:11 +01:00
snyk-bot
292107342e fix: upgrade @babel/preset-env from 7.15.4 to 7.15.6
Snyk has created this PR to upgrade @babel/preset-env from 7.15.4 to 7.15.6.

See this package in npm:
https://www.npmjs.com/package/@babel/preset-env

See this project in Snyk:
https://app.snyk.io/org/bluewallet/project/29c066bc-abce-44d9-b68e-064466e610e7?utm_source=github&utm_medium=referral&page=upgrade-pr
2021-10-01 13:02:08 +01:00
MG-ng
661248702d Last .md style improvement 2021-09-28 21:50:45 +01:00
MG-ng
d5fb16b074 Unified more .md style 2021-09-28 21:50:45 +01:00
MG-ng
a184872b02 Unified .md style
There were some tabs and broken Indentations which I corrected and converted to spaces.
2021-09-28 21:50:45 +01:00
MG-ng
6047383747 /getinvoice instead of /getaddinvoice
According to the code 
66a54570c5/controllers/api.js (L177)
2021-09-28 21:50:16 +01:00
dependabot[bot]
2f2c105177 build(deps): bump ansi-regex from 5.0.0 to 5.0.1
Bumps [ansi-regex](https://github.com/chalk/ansi-regex) from 5.0.0 to 5.0.1.
- [Release notes](https://github.com/chalk/ansi-regex/releases)
- [Commits](https://github.com/chalk/ansi-regex/compare/v5.0.0...v5.0.1)

---
updated-dependencies:
- dependency-name: ansi-regex
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-09-27 15:41:22 +01:00
Overtorment
64adcfc279 REL 2021-09-26 12:59:29 +01:00
Aaron Dewes
3a9cefa64b Update node from 12-buster to 16-bullseye
With Node 16 and Debian Bullseye being out now, this updates the BlueWallet docker containers to these versions. On Citadel, this will allow faster downloads of the app because it always uses the up-to-date containers, and when (if) Umbrel migrates to Node 16, it'll also allow faster downloads there.
2021-09-26 12:57:47 +01:00
MG-ng
e149f695cc or instead of of
according to the code
66a54570c5/controllers/api.js (L158)
2021-09-25 20:01:24 +01:00
Overtorment
c4a41fff48 Update README.md 2021-09-22 19:28:58 +01:00
8 changed files with 267 additions and 210 deletions

View File

@@ -6,7 +6,7 @@ RUN adduser --disabled-password \
--gecos "" \
"lndhub"
FROM node:12-buster-slim AS builder
FROM node:16-bullseye-slim AS builder
# These packages are required for building LNDHub
RUN apt-get update && apt-get -y install python3
@@ -25,7 +25,7 @@ COPY . .
# Delete git data as it's not needed inside the container
RUN rm -rf .git
FROM node:12-buster-slim
FROM node:16-bullseye-slim
# Create a specific user so LNDHub doesn't run as root
COPY --from=perms /etc/group /etc/passwd /etc/shadow /etc/

View File

@@ -52,7 +52,7 @@ Can be used in ReactNative or Nodejs environment
### Tests
Acceptance tests are in https://github.com/BlueWallet/BlueWallet/blob/master/LightningCustodianWallet.test.js
Acceptance tests are in https://github.com/BlueWallet/BlueWallet/blob/master/tests/integration/lightning-custodian-wallet.test.js
![image](https://user-images.githubusercontent.com/1913337/52418916-f30beb00-2ae6-11e9-9d63-17189dc1ae8c.png)

View File

@@ -363,7 +363,7 @@ export class User {
}
if (invoice.decoded) {
invoice.timestamp = invoice.decoded.timestamp;
invoice.memo = invoice.decoded.description;
invoice.memo = invoice.memo || invoice.decoded.description;
}
if (invoice.payment_preimage) {
invoice.payment_preimage = Buffer.from(invoice.payment_preimage, 'hex').toString('hex');
@@ -504,7 +504,7 @@ export class User {
* @returns {Promise<void>}
*/
async accountForPosibleTxids() {
return; // TODO: remove
// return; // TODO: remove
let onchain_txs = await this.getTxs();
let imported_txids = await this._redis.lrange('imported_txids_for_' + this._userid, 0, -1);
for (let tx of onchain_txs) {

View File

@@ -188,11 +188,16 @@ router.post('/addinvoice', postLimiter, async function (req, res) {
const invoice = new Invo(redis, bitcoinclient, lightning);
const r_preimage = invoice.makePreimageHex();
const invoice_args = { memo: req.body.memo, value: req.body.amt, expiry: 3600 * 24, r_preimage: Buffer.from(r_preimage, 'hex').toString('base64') };
if (req.body.description_hash) {
invoice_args.description_hash = Buffer.from(req.body.description_hash, 'hex').toString('base64')
}
lightning.addInvoice(
{ memo: req.body.memo, value: req.body.amt, expiry: 3600 * 24, r_preimage: Buffer.from(r_preimage, 'hex').toString('base64') },
invoice_args,
async function (err, info) {
if (err) return errorLnd(res);
info.memo = req.body.memo;
info.pay_req = info.payment_request; // client backwards compatibility
await u.saveUserInvoice(info);
await invoice.savePreimage(r_preimage);

View File

@@ -33,7 +33,7 @@ associated with corresponding user id.
| Call | Method | Handler | Params | Return | Description |
| ------------- | ------------- | ------------- | ------------- | ------------- | ------------- |
| Create Account | POST | /create | {none} | JSON Auth Data | Create new user account and get credentials |
| Authorize | POST | /auth | auth params (login/password of refresh_token) | JSON token data | Authorize user with Oauth. When user use refresh_token to auth, then this refresh_token not available for access once again. Use new refresh_token |
| Authorize | POST | /auth | auth params (login/password or refresh_token) | JSON token data | Authorize user with Oauth. When user use refresh_token to auth, then this refresh_token not available for access once again. Use new refresh_token |
| Get token | POST | /oauth2/token | user id, secret, grant_type and scope | token data | Get token data from user id, secret, grant_type and scope |
| Get BTC Addr | GET | /getbtc | {none} | Text address | Get user's BTC address to top-up his account |
| New BTC Addr | POST | /newbtc | {none} | Text address | Create new BTC address for user. Old addresses should remain valid, so if user accidentaly sends money to old address transaction will be assigned to his account |
@@ -70,9 +70,9 @@ Response is always JSON.
`error:true` should be always present.
{
"error" : true, // boolean
"code" : 1, // int
"message": "..." // string
"error" : true, // boolean
"code" : 1, // int
"message": "..." // string
}
Error code | Error message
@@ -95,15 +95,15 @@ Create new user account and get credentials. Not whitelisted partners should ret
Request:
{
"partnerid" : "bluewallet" // string, not mandatory parameter
"accounttype" : "..." // string, not mandatory, default is common, also can be test or core
"partnerid" : "bluewallet" // string, not mandatory parameter
"accounttype" : "..." // string, not mandatory, default is common, also can be test or core
}
Response:
{
"login":"...", // srting
"password":"...", // srting
"login":"...", // string
"password":"...", // string
}
## POST /auth?type=auth
@@ -113,16 +113,16 @@ Authorize user with Oauth user and login
Request:
{
"login": "...", //string
"password": "..." //string
"login": "...", // string
"password": "..." // string
}
Response:
{
"access_token": "...", //string
"token_type": "...", //string
"refresh_token": "...", //string
"access_token": "...", // string
"token_type": "...", // string
"refresh_token": "...", // string
"expiry": "0001-01-01T00:00:00Z" // datetime
}
@@ -135,16 +135,16 @@ Authorize user with Oauth user and login
Request:
{
"refresh_token": "...", //string
"refresh_token": "...", // string
}
Response:
{
"access_token": "...", //string
"token_type": "...", //string
"refresh_token": "...", //string
"expiry": "0001-01-01T00:00:00Z" // datetime
"access_token": "...", // string
"token_type": "...", // string
"refresh_token": "...", // string
"expiry": "0001-01-01T00:00:00Z" // datetime
}
## POST /oauth2/token
@@ -154,17 +154,17 @@ Authorize user with Oauth user and login
Request:
{
"grant_type": "client_credentials", //string
"client_id": "...", //string
"grant_type": "client_credentials", // string
"client_id": "...", // string
"client_secret": "..." // string
}
Response:
{
"access_token": "...", //string
"token_type": "...", //string
"refresh_token": "...", //string
"access_token": "...", // string
"token_type": "...", // string
"refresh_token": "...", // string
"expiry": "0001-01-01T00:00:00Z" // datetime
}
@@ -229,34 +229,34 @@ Request:
Response:
{
"destination": "...", //string, lnd node address
"payment_hash": "...", //string
"num_satoshis": "78497", //string, satoshis
"timestamp": "1534430501", //string, unixtime
"expiry": "3600", //string, seconds
"description": "...", //string
"description_hash": "", //string
"fallback_addr": "...", //string, fallback on-chain address
"cltv_expiry": "...", //string, delta to use for the time-lock of the CLTV extended to the final hop
"destination": "...", // string, lnd node address
"payment_hash": "...", // string
"num_satoshis": "78497", // string, satoshis
"timestamp": "1534430501", // string, unixtime
"expiry": "3600", // string, seconds
"description": "...", // string
"description_hash": "", // string
"fallback_addr": "...", // string, fallback on-chain address
"cltv_expiry": "...", // string, delta to use for the time-lock of the CLTV extended to the final hop
"route_hints": [
{
"hop_hints" : [
{
"node_id": "..", //string, the public key of the node at the start of the
"node_id": "..", // string, the public key of the node at the start of the
// channel.
"chan_id": ..., //int, the unique identifier of the channel.
"chan_id": ..., // int, the unique identifier of the channel.
"fee_base_msat": ..., //int, The base fee of the channel denominated in
"fee_base_msat": ..., // int, The base fee of the channel denominated in
// millisatoshis.
"fee_proportional_millionths": ...,
//int, the fee rate of the channel
// int, the fee rate of the channel
// for sending one satoshi across it denominated
// in millionths of a satoshi
"cltv_expiry_delta": ...
//int, the fee rate of the channel for sending one satoshi
// int, the fee rate of the channel for sending one satoshi
// across it denominated in millionths of a satoshi
}, ...
]
@@ -288,7 +288,7 @@ Request:
{
"destination" : "..." // string, destination lnd node address
"amt": "..." // string,
"amt": "..." // string,
}
Response:
@@ -311,26 +311,26 @@ Request:
Response:
{
"payment_error": "..." //string
"payment_preimage": "..." //string
"payment_route": {
"total_time_lock": ... , //int
"total_fees": ... , //int
"total_amt": ... , //int
"total_fees_msat": ... , //int
"total_amt_msat": ... , //int
"hops": [
{
"chan_id": ... , //int
"chan_capacity": ... , //int
"amt_to_forward": ... , //int
"fee": ... , //int
"expiry": ... , //int
"amt_to_forward_msat": ... , //int
"fee_msat": ... , //int
},
]
}
"payment_error": "..." // string
"payment_preimage": "..." // string
"payment_route": {
"total_time_lock": ... , // int
"total_fees": ... , // int
"total_amt": ... , // int
"total_fees_msat": ... , // int
"total_amt_msat": ... , // int
"hops": [
{
"chan_id": ... , // int
"chan_capacity": ... , // int
"amt_to_forward": ... , // int
"fee": ... , // int
"expiry": ... , // int
"amt_to_forward_msat": ... , // int
"fee_msat": ... , // int
},
]
}
}
## POST /sendcoins
@@ -356,14 +356,14 @@ Get successful lightning and btc transactions user made. Order newest to oldest.
Request:
{
"limit" : 10, // INT
"offset": 0, // INT
"limit" : 10, // INT
"offset": 0, // INT
}
Response:
{
[ // array of Transaction object (see below)
[ // array of Transaction object (see below)
{
...
}
@@ -398,10 +398,10 @@ Request:
Response:
{
"BTC": { //string, currency
"TotalBalance": 109388, //int, satoshis
"BTC": { // string, currency
"TotalBalance": 109388, // int, satoshis
"AvailableBalance": 109388, // int, satoshis
"UncomfirmedBalance": 0 //int, satoshis
"UncomfirmedBalance": 0 // int, satoshis
}, ...
//now available only btc balance
@@ -422,50 +422,52 @@ Response:
"fee": 0, // int, in cents of percent, i.e. 100 for 1%, 50 for 0.5%, 1 for 0.01%
"identity_pubkey": "...", //string, lnd node identity pubkey
"alias": "...", //string, lnd node alias
"num_pending_channels": 0, //int
"num_active_channels": 3, //int
"num_peers": 6, //int
"block_height": 542389, //int
"block_hash": "...", //string
"synced_to_chain": true, //bool
"testnet": false,
"chains": [
"bitcoin" //string, available chans to operate by lnd
],
"uris": [
"...", //string, uris of lnd node
],
"best_header_timestamp": "...", //string, unixtime
"version": "..." // string, lnd version
"identity_pubkey": "...", // string, lnd node identity pubkey
"alias": "...", // string, lnd node alias
"num_pending_channels": 0, // int
"num_active_channels": 3, // int
"num_peers": 6, // int
"block_height": 542389, // int
"block_hash": "...", // string
"synced_to_chain": true, // bool
"testnet": false,
"chains": [
"bitcoin" // string, available chans to operate by lnd
],
"uris": [
"...", // string, uris of lnd node
],
"best_header_timestamp": "...", // string, unixtime
"version": "..." // string, lnd version
}
## GET /getaddinvoice
## GET /getinvoice
Returns fees user pays for payments, status of the system, etc.
Request:
{
"amt": "...", //string
"memo":"...", //string
"receipt":"...", //string, not mandatory parameter
"preimage": "...", //string, not mandatory parameter
"fallbackAddr": "...", //string, not mandatory parameter
"expiry": "...", //string, not mandatory parameter
"private": "..." //string, not mandatory parameter
"amt": "...", // string
"memo":"...", // string
"receipt":"...", // string, not mandatory parameter
"preimage": "...", // string, not mandatory parameter
"fallbackAddr": "...", // string, not mandatory parameter
"expiry": "...", // string, not mandatory parameter
"private": "..." // string, not mandatory parameter
}
Response:
{
"r_hash": "...", //string,
"pay_req": "...", //string, a bare-bones invoice for a payment within the Lightning Network
"add_index": ... //int, The “add” index of this invoice. Each newly created invoice will
"r_hash": "...", // string,
"pay_req": "...", // string, a bare-bones invoice for a payment within the Lightning Network
"add_index": ... // int, 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.
}
## GET /getuserinvoices
Returns fees user pays for payments, status of the system, etc.
@@ -475,33 +477,35 @@ Request:
none
Response:
{
"r_hash": "...", //string
"payment_request": "...", //string
"add_index": "...", //string
"description": "...", //string
"amt": ... , //int
"ispaid": ... //bool
}
{
"r_hash": "...", // string
"payment_request": "...", // string
"add_index": "...", // string
"description": "...", // string
"amt": ... , // int
"ispaid": ... // bool
}
# Data structures
## Transaction object
{
"type": "...", // string, type of txs. Types:
// bitcoind_internal_tx - moves to user btc address or account
// bitcoind_tx - received by address or account
// paid_invoice - user paid someone's invoice
// sent_coins - user sent coins by lnd to someone's btc account
// received_invoice_payments - user received payments by invoice
"txid": "...", // string, internal tx id. not related to onchain transaction id
"amt": 666, // satoshi, int
"fee": 11, // satoshi, int
"timestamp": 1234567, // int, unixtime
"from": "...", // string
"to": "...", // string
"description": "...", // string, user-defined text
"invoice": "...", // string, original bolt11-format invoice
// bitcoind_internal_tx - moves to user btc address or account
// bitcoind_tx - received by address or account
// paid_invoice - user paid someone's invoice
// sent_coins - user sent coins by lnd to someone's btc account
// received_invoice_payments - user received payments by invoice
"txid": "...", // string, internal tx id. not related to onchain transaction id
"amt": 666, // satoshi, int
"fee": 11, // satoshi, int
"timestamp": 1234567, // int, unixtime
"from": "...", // string
"to": "...", // string
"description": "...", // string, user-defined text
"invoice": "...", // string, original bolt11-format invoice
}
# Explaining oauth2 mechanism

171
package-lock.json generated
View File

@@ -1,6 +1,6 @@
{
"name": "lndhub",
"version": "1.4.0",
"version": "1.4.1",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@@ -470,15 +470,15 @@
}
},
"@babel/plugin-proposal-object-rest-spread": {
"version": "7.14.7",
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.14.7.tgz",
"integrity": "sha512-082hsZz+sVabfmDWo1Oct1u1AgbKbUAyVgmX4otIc7bdsRgHBXwTwb3DpDmD4Eyyx6DNiuz5UAATT655k+kL5g==",
"version": "7.15.6",
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.15.6.tgz",
"integrity": "sha512-qtOHo7A1Vt+O23qEAX+GdBpqaIuD3i9VRrWgCJeq7WO6H2d14EK3q11urj5Te2MAeK97nMiIdRpwd/ST4JFbNg==",
"requires": {
"@babel/compat-data": "^7.14.7",
"@babel/helper-compilation-targets": "^7.14.5",
"@babel/compat-data": "^7.15.0",
"@babel/helper-compilation-targets": "^7.15.4",
"@babel/helper-plugin-utils": "^7.14.5",
"@babel/plugin-syntax-object-rest-spread": "^7.8.3",
"@babel/plugin-transform-parameters": "^7.14.5"
"@babel/plugin-transform-parameters": "^7.15.4"
}
},
"@babel/plugin-proposal-optional-catch-binding": {
@@ -922,9 +922,9 @@
}
},
"@babel/preset-env": {
"version": "7.15.4",
"resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.15.4.tgz",
"integrity": "sha512-4f2nLw+q6ht8gl3sHCmNhmA5W6b1ItLzbH3UrKuJxACHr2eCpk96jwjrAfCAaXaaVwTQGnyUYHY2EWXJGt7TUQ==",
"version": "7.15.6",
"resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.15.6.tgz",
"integrity": "sha512-L+6jcGn7EWu7zqaO2uoTDjjMBW+88FXzV8KvrBl2z6MtRNxlsmUNRlZPaNNPUTgqhyC5DHNFk/2Jmra+ublZWw==",
"requires": {
"@babel/compat-data": "^7.15.0",
"@babel/helper-compilation-targets": "^7.15.4",
@@ -940,7 +940,7 @@
"@babel/plugin-proposal-logical-assignment-operators": "^7.14.5",
"@babel/plugin-proposal-nullish-coalescing-operator": "^7.14.5",
"@babel/plugin-proposal-numeric-separator": "^7.14.5",
"@babel/plugin-proposal-object-rest-spread": "^7.14.7",
"@babel/plugin-proposal-object-rest-spread": "^7.15.6",
"@babel/plugin-proposal-optional-catch-binding": "^7.14.5",
"@babel/plugin-proposal-optional-chaining": "^7.14.5",
"@babel/plugin-proposal-private-methods": "^7.14.5",
@@ -993,7 +993,7 @@
"@babel/plugin-transform-unicode-escapes": "^7.14.5",
"@babel/plugin-transform-unicode-regex": "^7.14.5",
"@babel/preset-modules": "^0.1.4",
"@babel/types": "^7.15.4",
"@babel/types": "^7.15.6",
"babel-plugin-polyfill-corejs2": "^0.2.2",
"babel-plugin-polyfill-corejs3": "^0.2.2",
"babel-plugin-polyfill-regenerator": "^0.2.2",
@@ -1001,6 +1001,15 @@
"semver": "^6.3.0"
},
"dependencies": {
"@babel/types": {
"version": "7.15.6",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.15.6.tgz",
"integrity": "sha512-BPU+7QhqNjmWyDO0/vitH/CuhpV8ZmK1wpKva8nuyNF5MJfuRNWMc+hc14+u9xT93kvykMdncrJT19h74uB1Ig==",
"requires": {
"@babel/helper-validator-identifier": "^7.14.9",
"to-fast-properties": "^2.0.0"
}
},
"semver": {
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
@@ -1148,9 +1157,9 @@
}
},
"@grpc/proto-loader": {
"version": "0.6.4",
"resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.6.4.tgz",
"integrity": "sha512-7xvDvW/vJEcmLUltCUGOgWRPM8Oofv0eCFSVMuKqaqWJaXSzmB+m9hiyqe34QofAl4WAzIKUZZlinIF9FOHyTQ==",
"version": "0.6.5",
"resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.6.5.tgz",
"integrity": "sha512-GZdzyVQI1Bln/kCzIYgTKu+rQJ5dno0gVrfmLe4jqQu7T2e7svSwJzpCBqVU5hhBSJP3peuPjOMWsj5GR61YmQ==",
"requires": {
"@types/long": "^4.0.1",
"lodash.camelcase": "^4.3.0",
@@ -1371,9 +1380,9 @@
"integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA=="
},
"ansi-regex": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
"integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg=="
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="
},
"ansi-styles": {
"version": "3.2.1",
@@ -1523,12 +1532,12 @@
}
},
"babel-plugin-polyfill-corejs3": {
"version": "0.2.4",
"resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.2.4.tgz",
"integrity": "sha512-z3HnJE5TY/j4EFEa/qpQMSbcUJZ5JQi+3UFjXzn6pQCmIKc5Ug5j98SuYyH+m4xQnvKlMDIW4plLfgyVnd0IcQ==",
"version": "0.2.5",
"resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.2.5.tgz",
"integrity": "sha512-ninF5MQNwAX9Z7c9ED+H2pGt1mXdP4TqzlHKyPIYmJIYz0N+++uwdM7RnJukklhzJ54Q84vA4ZJkgs7lu5vqcw==",
"requires": {
"@babel/helper-define-polyfill-provider": "^0.2.2",
"core-js-compat": "^3.14.0"
"core-js-compat": "^3.16.2"
}
},
"babel-plugin-polyfill-regenerator": {
@@ -2215,14 +2224,41 @@
"integrity": "sha512-XkbXqhcXeMHPRk2ItS+zQYliAMilea2euoMsnpRRdDad6b2VY6CQQcwz1K8AnWesfw4p165RzY0bTnr3UrbYiA=="
},
"core-js-compat": {
"version": "3.17.2",
"resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.17.2.tgz",
"integrity": "sha512-lHnt7A1Oqplebl5i0MrQyFv/yyEzr9p29OjlkcsFRDDgHwwQyVckfRGJ790qzXhkwM8ba4SFHHa2sO+T5f1zGg==",
"version": "3.18.1",
"resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.18.1.tgz",
"integrity": "sha512-XJMYx58zo4W0kLPmIingVZA10+7TuKrMLPt83+EzDmxFJQUMcTVVmQ+n5JP4r6Z14qSzhQBRi3NSWoeVyKKXUg==",
"requires": {
"browserslist": "^4.16.8",
"browserslist": "^4.17.1",
"semver": "7.0.0"
},
"dependencies": {
"browserslist": {
"version": "4.17.2",
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.17.2.tgz",
"integrity": "sha512-jSDZyqJmkKMEMi7SZAgX5UltFdR5NAO43vY0AwTpu4X3sGH7GLLQ83KiUomgrnvZRCeW0yPPnKqnxPqQOER9zQ==",
"requires": {
"caniuse-lite": "^1.0.30001261",
"electron-to-chromium": "^1.3.854",
"escalade": "^3.1.1",
"nanocolors": "^0.2.12",
"node-releases": "^1.1.76"
}
},
"caniuse-lite": {
"version": "1.0.30001261",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001261.tgz",
"integrity": "sha512-vM8D9Uvp7bHIN0fZ2KQ4wnmYFpJo/Etb4Vwsuc+ka0tfGDHvOPrFm6S/7CCNLSOkAUjenT2HnUPESdOIL91FaA=="
},
"electron-to-chromium": {
"version": "1.3.856",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.856.tgz",
"integrity": "sha512-lSezYIe1/p5qkEswAfaQUseOBiwGwuCvRl/MKzOEVe++DcmQ92+43dznDl4rFJ4Zpu+kevhwyIf7KjJevyDA/A=="
},
"node-releases": {
"version": "1.1.76",
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.76.tgz",
"integrity": "sha512-9/IECtNr8dXNmPWmFXepT0/7o5eolGesHUa3mtr0KlgnCvnZxwh2qensKL42JJY2vQKC3nIBXetFAqR+PW1CmA=="
},
"semver": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz",
@@ -2849,9 +2885,9 @@
}
},
"express-rate-limit": {
"version": "5.3.0",
"resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-5.3.0.tgz",
"integrity": "sha512-qJhfEgCnmteSeZAeuOKQ2WEIFTX5ajrzE0xS6gCOBCoRQcU+xEzQmgYQQTpzCcqUAAzTEtu4YEih4pnLfvNtew=="
"version": "5.4.1",
"resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-5.4.1.tgz",
"integrity": "sha512-ZQh2h3qiu7wWdvWNYHznBhaOp2ZIXNnT4hl2Ff608STeWtCuJ251NzqQlk7mo5wnO2HmrydBYHuVA9Z3S3ZtXg=="
},
"extend": {
"version": "3.0.2",
@@ -3457,9 +3493,9 @@
}
},
"ioredis": {
"version": "4.27.9",
"resolved": "https://registry.npmjs.org/ioredis/-/ioredis-4.27.9.tgz",
"integrity": "sha512-hAwrx9F+OQ0uIvaJefuS3UTqW+ByOLyLIV+j0EH8ClNVxvFyH9Vmb08hCL4yje6mDYT5zMquShhypkd50RRzkg==",
"version": "4.27.10",
"resolved": "https://registry.npmjs.org/ioredis/-/ioredis-4.27.10.tgz",
"integrity": "sha512-BtV2mEoZlhnW0EyxuK49V5iutLeZeJAYi/+Fuc4Q6DpDjq0cGMLODdS/+Kb5CHpT7v3YT6SK0vgJF6y0Ls4+Bg==",
"requires": {
"cluster-key-slot": "^1.1.0",
"debug": "^4.3.1",
@@ -3557,9 +3593,9 @@
"integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w=="
},
"is-core-module": {
"version": "2.6.0",
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.6.0.tgz",
"integrity": "sha512-wShG8vs60jKfPWpF2KZRaAtvt3a20OAn7+IJ6hLPECpSABLcKtFKTTI4ZtH5QcBruBHlq+WsdHWyz0BCZW7svQ==",
"version": "2.7.0",
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.7.0.tgz",
"integrity": "sha512-ByY+tjCciCr+9nLryBYcSD50EOGWt95c7tIsKTG1J2ixKKXPvF7Ej3AVd+UfDydAJom3biBGDBALaO79ktwgEQ==",
"requires": {
"has": "^1.0.3"
}
@@ -4125,6 +4161,11 @@
"resolved": "https://registry.npmjs.org/nan/-/nan-2.15.0.tgz",
"integrity": "sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ=="
},
"nanocolors": {
"version": "0.2.12",
"resolved": "https://registry.npmjs.org/nanocolors/-/nanocolors-0.2.12.tgz",
"integrity": "sha512-SFNdALvzW+rVlzqexid6epYdt8H9Zol7xDoQarioEFcFN0JHo4CYNztAxmtfgGTVRCmFlEOqqhBpoFGKqSAMug=="
},
"nanomatch": {
"version": "1.2.13",
"resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz",
@@ -4587,11 +4628,11 @@
"integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A=="
},
"regenerate-unicode-properties": {
"version": "8.2.0",
"resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-8.2.0.tgz",
"integrity": "sha512-F9DjY1vKLo/tPePDycuH3dn9H1OTPIkVD9Kz4LODu+F2C75mgjAJ7x/gwy6ZcSNRAAkhNlJSOHRe8k3p+K9WhA==",
"version": "9.0.0",
"resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-9.0.0.tgz",
"integrity": "sha512-3E12UeNSPfjrgwjkR81m5J7Aw/T55Tu7nUyZVQYCKEOs+2dkxEY+DpPtZzO4YruuiPb7NkYLVcyJC4+zCbk5pA==",
"requires": {
"regenerate": "^1.4.0"
"regenerate": "^1.4.2"
}
},
"regenerator-runtime": {
@@ -4623,16 +4664,16 @@
"integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg=="
},
"regexpu-core": {
"version": "4.7.1",
"resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.7.1.tgz",
"integrity": "sha512-ywH2VUraA44DZQuRKzARmw6S66mr48pQVva4LBeRhcOltJ6hExvWly5ZjFLYo67xbIxb6W1q4bAGtgfEl20zfQ==",
"version": "4.8.0",
"resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.8.0.tgz",
"integrity": "sha512-1F6bYsoYiz6is+oz70NWur2Vlh9KWtswuRuzJOfeYUrfPX2o8n74AnUVaOGDbUqVGO9fNHu48/pjJO4sNVwsOg==",
"requires": {
"regenerate": "^1.4.0",
"regenerate-unicode-properties": "^8.2.0",
"regjsgen": "^0.5.1",
"regjsparser": "^0.6.4",
"unicode-match-property-ecmascript": "^1.0.4",
"unicode-match-property-value-ecmascript": "^1.2.0"
"regenerate": "^1.4.2",
"regenerate-unicode-properties": "^9.0.0",
"regjsgen": "^0.5.2",
"regjsparser": "^0.7.0",
"unicode-match-property-ecmascript": "^2.0.0",
"unicode-match-property-value-ecmascript": "^2.0.0"
}
},
"regjsgen": {
@@ -4641,9 +4682,9 @@
"integrity": "sha512-OFFT3MfrH90xIW8OOSyUrk6QHD5E9JOTeGodiJeBS3J6IwlgzJMNE/1bZklWz5oTg+9dCMyEetclvCVXOPoN3A=="
},
"regjsparser": {
"version": "0.6.9",
"resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.9.tgz",
"integrity": "sha512-ZqbNRz1SNjLAiYuwY0zoXW8Ne675IX5q+YHioAGbCw4X96Mjl2+dcX9B2ciaeyYjViDAfvIjFpQjJgLttTEERQ==",
"version": "0.7.0",
"resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.7.0.tgz",
"integrity": "sha512-A4pcaORqmNMDVwUjWoTzuhwMGpP+NykpfqAsEgI1FSH/EzC7lrN5TMd+kN8YCovX+jMpu8eaqXgXPCa0g8FQNQ==",
"requires": {
"jsesc": "~0.5.0"
},
@@ -5431,28 +5472,28 @@
}
},
"unicode-canonical-property-names-ecmascript": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz",
"integrity": "sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ=="
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz",
"integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ=="
},
"unicode-match-property-ecmascript": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz",
"integrity": "sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg==",
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz",
"integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==",
"requires": {
"unicode-canonical-property-names-ecmascript": "^1.0.4",
"unicode-property-aliases-ecmascript": "^1.0.4"
"unicode-canonical-property-names-ecmascript": "^2.0.0",
"unicode-property-aliases-ecmascript": "^2.0.0"
}
},
"unicode-match-property-value-ecmascript": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.2.0.tgz",
"integrity": "sha512-wjuQHGQVofmSJv1uVISKLE5zO2rNGzM/KCYZch/QQvez7C1hUhBIuZ701fYXExuufJFMPhv2SyL8CyoIfMLbIQ=="
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.0.0.tgz",
"integrity": "sha512-7Yhkc0Ye+t4PNYzOGKedDhXbYIBe1XEQYQxOPyhcXNMJ0WCABqqj6ckydd6pWRZTHV4GuCPKdBAUiMc60tsKVw=="
},
"unicode-property-aliases-ecmascript": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.1.0.tgz",
"integrity": "sha512-PqSoPh/pWetQ2phoj5RLiaqIk4kCNwoV3CI+LfGmWLKI3rE3kl1h59XpX2BjgDrmbxD9ARtQobPGU1SguCYuQg=="
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.0.0.tgz",
"integrity": "sha512-5Zfuy9q/DFr4tfO7ZPeVXb1aPoeQSdeFMLpYuFebehDAhbuevLs5yxSZmIFN1tP5F9Wl4IpJrYojg85/zgyZHQ=="
},
"union-value": {
"version": "1.0.1",

View File

@@ -1,6 +1,6 @@
{
"name": "lndhub",
"version": "1.4.0",
"version": "1.4.1",
"description": "",
"main": "index.js",
"scripts": {
@@ -16,10 +16,10 @@
"@babel/core": "^7.15.0",
"@babel/eslint-parser": "^7.14.2",
"@babel/node": "^7.14.9",
"@babel/preset-env": "^7.15.0",
"@babel/preset-env": "^7.15.6",
"@babel/register": "^7.14.5",
"@grpc/grpc-js": "^1.3.7",
"@grpc/proto-loader": "^0.6.4",
"@grpc/proto-loader": "^0.6.5",
"bignumber.js": "^9.0.1",
"bitcoinjs-lib": "^5.2.0",
"bolt11": "^1.3.2",
@@ -27,10 +27,10 @@
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-prettier": "^3.4.0",
"express": "^4.17.1",
"express-rate-limit": "^5.3.0",
"express-rate-limit": "^5.4.1",
"frisbee": "^3.1.4",
"helmet": "^4.6.0",
"ioredis": "^4.27.8",
"ioredis": "^4.27.10",
"jayson": "^3.6.4",
"morgan": "^1.10.0",
"mustache": "^4.1.0",

View File

@@ -3,10 +3,15 @@
* sentout payments from LND. If locked payment is in there we moe locked payment to array of real payments for the user
* (it is effectively spent coins by user), if not - we attempt to pay it again (if it is not too old).
*/
import { User, Lock, Paym } from '../class/';
import { User, Paym } from '../class/';
const config = require('../config');
const fs = require('fs');
/****** START SET FEES FROM CONFIG AT STARTUP ******/
/** GLOBALS */
global.forwardFee = config.forwardReserveFee || 0.01;
global.internalFee = config.intraHubFee || 0.003;
/****** END SET FEES FROM CONFIG AT STARTUP ******/
var Redis = require('ioredis');
var redis = new Redis(config.redis);
@@ -20,8 +25,8 @@ let lightning = require('../lightning');
console.log('fetching listPayments...');
let tempPaym = new Paym(redis, bitcoinclient, lightning);
let listPayments = await tempPaym.listPayments();
// DEBUG let listPayments = JSON.parse(fs.readFileSync('listpayments.txt').toString('ascii'));
console.log('done', 'got', listPayments['payments'].length, 'payments');
fs.writeFileSync('listPayments.json', JSON.stringify(listPayments['payments'], null, 2));
for (let key of keys) {
const userid = key.replace('locked_payments_for_', '');
@@ -30,7 +35,7 @@ let lightning = require('../lightning');
let user = new User(redis, bitcoinclient, lightning);
user._userid = userid;
let lockedPayments = await user.getLockedPayments();
// lockedPayments = [{pay_req : 'lnbc2m1pwgd4tdpp5vjz80mm8murdkskrnre6w4kphzy3d6gap5jyffr93u02ruaj0wtsdq2xgcrqvpsxqcqzysk34zva4h9ce9jdf08nfdm2sh2ek4y4hjse8ww9jputneltjl24krkv50sene4jh0wpull6ujgrg632u2qt3lkva74vpkqr5e5tuuljspasqfhx'}];
// DEBUG let lockedPayments = [{ pay_req : 'lnbc108130n1pshdaeupp58kw9djt9vcdx26wkdxl07tgncdmxz2w7s9hzul45tf8gfplme94sdqqcqzzgxqrrssrzjqw8c7yfutqqy3kz8662fxutjvef7q2ujsxtt45csu0k688lkzu3ld93gutl3k6wauyqqqqryqqqqthqqpysp5jcmk82hypuud0lhpf66dg3w5ta6aumc4w9g9sxljazglq9wkwstq9qypqsqnw8hwwauvzrala3g4yrkgazk2l2fh582j9ytz7le46gmsgglvmrknx842ej9z4c63en5866l8tpevm8cwul8g94kf2nepppn256unucp43jnsw', amount: 10813, timestamp: 1635186606 }];
for (let lockedPayment of lockedPayments) {
let daysPassed = (+new Date() / 1000 - lockedPayment.timestamp) / 3600 / 24;
@@ -38,8 +43,25 @@ let lightning = require('../lightning');
let payment = new Paym(redis, bitcoinclient, lightning);
payment.setInvoice(lockedPayment.pay_req);
// first things first:
// trying to lookup this stuck payment in an array of delivered payments
let isPaid = false;
for (let sentPayment of listPayments['payments']) {
if ((await payment.getPaymentHash()) == sentPayment.payment_hash) {
console.log('found this payment in listPayments array, so it is paid successfully');
let sendResult = payment.processSendPaymentResponse({ payment_error: 'already paid' } /* hacky */); // adds fees
console.log('saving paid invoice:', sendResult);
await user.savePaidLndInvoice(sendResult);
await user.unlockFunds(lockedPayment.pay_req);
isPaid = true;
console.log('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!', await payment.getPaymentHash(), sentPayment.payment_hash);
break;
}
}
// could not find...
if (daysPassed > 1 / 24 && daysPassed <= 1) {
// if (!await payment.isExpired()) {
let sendResult;
console.log('attempting to pay to route');
try {
@@ -68,22 +90,7 @@ let lightning = require('../lightning');
console.log('-----------------------------------------------------------------------------------');
await User._sleep(0);
} else if (daysPassed > 1) {
// trying to lookup this stuck payment in an array of delivered payments
let isPaid = false;
for (let sentPayment of listPayments['payments']) {
if ((await payment.getPaymentHash()) == sentPayment.payment_hash) {
console.log('found this payment in listPayments array, so it is paid successfully');
let sendResult = payment.processSendPaymentResponse({ payment_error: 'already paid' } /* hacky */); // adds fees
console.log('saving paid invoice:', sendResult);
await user.savePaidLndInvoice(sendResult);
await user.unlockFunds(lockedPayment.pay_req);
isPaid = true;
console.log('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!', await payment.getPaymentHash(), sentPayment.payment_hash);
process.exit();
break;
}
}
// could not find in listpayments array; too late to retry
if (!isPaid) {
console.log('very old payment, evict the lock');
await user.unlockFunds(lockedPayment.pay_req);