Compare commits

...

66 Commits

Author SHA1 Message Date
dependabot[bot]
819518eab0 build(deps): bump elliptic from 6.5.4 to 6.6.1
Some checks failed
Build on push / Build image (push) Has been cancelled
Bumps [elliptic](https://github.com/indutny/elliptic) from 6.5.4 to 6.6.1.
- [Commits](https://github.com/indutny/elliptic/compare/v6.5.4...v6.6.1)

---
updated-dependencies:
- dependency-name: elliptic
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-02-15 19:55:29 +00:00
overtorment
0311e56aa2 FIX: groundcontrol post notification 2024-11-05 11:15:34 +00:00
dependabot[bot]
0cf7387c30 build(deps): bump ws from 7.5.4 to 7.5.10
Bumps [ws](https://github.com/websockets/ws) from 7.5.4 to 7.5.10.
- [Release notes](https://github.com/websockets/ws/releases)
- [Commits](https://github.com/websockets/ws/compare/7.5.4...7.5.10)

---
updated-dependencies:
- dependency-name: ws
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-08-01 11:21:18 +01:00
snyk-bot
edb2ab0949 fix: package.json & package-lock.json to reduce vulnerabilities
The following vulnerabilities are fixed with an upgrade:
- https://snyk.io/vuln/SNYK-JS-SEMVER-3247795
2023-12-29 12:00:36 +00:00
dependabot[bot]
625a6e9526 build(deps): bump @babel/traverse from 7.15.4 to 7.23.2
Bumps [@babel/traverse](https://github.com/babel/babel/tree/HEAD/packages/babel-traverse) from 7.15.4 to 7.23.2.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.23.2/packages/babel-traverse)

---
updated-dependencies:
- dependency-name: "@babel/traverse"
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-21 18:15:13 +01:00
dependabot[bot]
525e309105 build(deps): bump protobufjs from 6.11.2 to 6.11.4
Bumps [protobufjs](https://github.com/protobufjs/protobuf.js) from 6.11.2 to 6.11.4.
- [Release notes](https://github.com/protobufjs/protobuf.js/releases)
- [Changelog](https://github.com/protobufjs/protobuf.js/blob/master/CHANGELOG.md)
- [Commits](https://github.com/protobufjs/protobuf.js/commits)

---
updated-dependencies:
- dependency-name: protobufjs
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-08-31 00:06:41 +01:00
overtorment
0964ebfca5 REL 2023-02-10 18:52:11 +00:00
overtorment
c87f1b322a FIX: add rate limiter to more api calls 2023-02-10 18:51:15 +00:00
overtorment
3a7b452c65 FIX: correct sat amount when unlocking paid stuck zero-sat invoice 2023-02-10 18:44:48 +00:00
Overtorment
fb023b02be FIX: race condition for address generation 2022-04-14 17:49:50 +01:00
Overtorment
60cda5eb14 FIX: unlock wont retry anymore, only sit tight and wait for a payment result 2022-04-13 12:51:22 +01:00
dependabot[bot]
c6dc983964 build(deps): bump minimist from 1.2.5 to 1.2.6
Bumps [minimist](https://github.com/substack/minimist) from 1.2.5 to 1.2.6.
- [Release notes](https://github.com/substack/minimist/releases)
- [Commits](https://github.com/substack/minimist/compare/1.2.5...1.2.6)

---
updated-dependencies:
- dependency-name: minimist
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-04-03 13:15:52 +01:00
Overtorment
481758f03a FIX: required reserve rounding for small amounts 2022-02-04 10:45:56 +00:00
Overtorment
348ee7ce81 OPS: renamed build action so its not triggered on heroku 2022-02-03 21:51:40 +00:00
kwizzn
05eace759f Add the transpiled artifacts to build/ for a slimmer native Node Docker container 2021-11-22 14:20:59 +00: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
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
Some checks failed
Build on push / Build image (push) Has been cancelled
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
Overtorment
688798024c
REL: v1.4.0
Some checks failed
Build on push / Build image (push) Has been cancelled
2021-09-22 14:18:04 +01:00
Overtorment
66a54570c5
DOC 2021-09-22 14:11:39 +01:00
Overtorment
e42ef3a85e
FIX: default values for fees config 2021-09-22 14:11:20 +01:00
Overtorment
600556f84c
FIX: qr in index page 2021-09-22 14:03:47 +01:00
xanoni
a01a8c6e14 index.js: add HOST environment argument 2021-09-22 13:54:34 +01:00
MG-ng
e9c6f3abde accounttype and partnerid check on create account
Refined the partnerid and accounttype check in the /create route according to the /doc/Send-requirements.md
Both are not mandatory but if given, they should be strings.

The typeof check is for direct string initialisation with "".
instanceof is used for string initialisation with new String() / the primitiv wrapper class.
2021-09-22 13:49:03 +01:00
lndhub-admin
7f9463bbbc sync changes to variable name 2021-09-22 13:46:51 +01:00
lndhub-admin
1b1fe8f08b tip invoices now use forwardFee
changed internalFee for tip invoices to forwardFee
2021-09-22 13:46:51 +01:00
lndhub-admin
28dd3a847a shorten default variables 2021-09-22 13:46:51 +01:00
lndhub-admin
a28eead0ab move default in varible name to comment
keep // default  0.* comment as reminder what defaults was
2021-09-22 13:46:51 +01:00
lndhub-admin
87afa20019 deleted space becouse karen said so 2021-09-22 13:46:51 +01:00
lndhub-admin
067f6d6667 delete commented fields 2021-09-22 13:46:51 +01:00
xraid
957d6c5951 Add global fee settings from config.js 2021-09-22 13:46:51 +01:00
Overtorment
d3df6aab05
REF: remove obsolete dep; small fixes 2021-09-07 22:00:33 +01:00
snyk-bot
4e8ce5e46f fix: upgrade @grpc/grpc-js from 1.3.6 to 1.3.7
Snyk has created this PR to upgrade @grpc/grpc-js from 1.3.6 to 1.3.7.

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

See this project in Snyk:
https://app.snyk.io/org/bluewallet/project/29c066bc-abce-44d9-b68e-064466e610e7?utm_source=github&utm_medium=upgrade-pr
2021-08-31 12:10:24 +01:00
snyk-bot
1fd24b640e fix: upgrade core-js from 3.16.0 to 3.16.1
Snyk has created this PR to upgrade core-js from 3.16.0 to 3.16.1.

See this package in npm:
https://www.npmjs.com/package/core-js

See this project in Snyk:
https://app.snyk.io/org/bluewallet/project/29c066bc-abce-44d9-b68e-064466e610e7?utm_source=github&utm_medium=upgrade-pr
2021-08-30 10:20:39 +01:00
snyk-bot
c47211f984 fix: upgrade multiple dependencies with Snyk
Snyk has created this PR to upgrade:
  - @babel/core from 7.14.8 to 7.15.0.
    See this package in npm: https://www.npmjs.com/package/@babel/core
  - @babel/preset-env from 7.14.9 to 7.15.0.
    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=upgrade-pr
2021-08-26 09:04:38 +01:00
Denys Zaliskyi
5223edc2b7 Update README.md
fix reference to `lightning-custodian-wallet`
2021-08-25 18:56:51 +01:00
snyk-bot
92e626508c fix: upgrade multiple dependencies with Snyk
Snyk has created this PR to upgrade:
  - @babel/node from 7.14.5 to 7.14.9.
    See this package in npm: https://www.npmjs.com/package/@babel/node
  - @babel/preset-env from 7.14.8 to 7.14.9.
    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=upgrade-pr
2021-08-23 13:15:56 +01:00
Denys Zaliskyi
3e2c31f429 Fix typo in Readme 2021-08-22 20:56:13 +01:00
snyk-bot
376d61f81d fix: upgrade core-js from 3.15.2 to 3.16.0
Snyk has created this PR to upgrade core-js from 3.15.2 to 3.16.0.

See this package in npm:
https://www.npmjs.com/package/core-js

See this project in Snyk:
https://app.snyk.io/org/bluewallet/project/29c066bc-abce-44d9-b68e-064466e610e7?utm_source=github&utm_medium=upgrade-pr
2021-08-21 19:46:06 +01:00
snyk-bot
1bb781270c fix: package.json & package-lock.json to reduce vulnerabilities
The following vulnerabilities are fixed with an upgrade:
- https://snyk.io/vuln/SNYK-JS-IOREDIS-1567196
2021-08-19 11:29:37 +01:00
dependabot[bot]
c0716bc6e9 build(deps): bump url-parse from 1.5.1 to 1.5.3
Bumps [url-parse](https://github.com/unshiftio/url-parse) from 1.5.1 to 1.5.3.
- [Release notes](https://github.com/unshiftio/url-parse/releases)
- [Commits](https://github.com/unshiftio/url-parse/compare/1.5.1...1.5.3)

---
updated-dependencies:
- dependency-name: url-parse
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-08-11 11:37:34 +01:00
snyk-bot
358f858ad8 fix: upgrade multiple dependencies with Snyk
Snyk has created this PR to upgrade:
  - @babel/cli from 7.14.5 to 7.14.8.
    See this package in npm: https://www.npmjs.com/package/@babel/cli
  - @babel/core from 7.14.5 to 7.14.8.
    See this package in npm: https://www.npmjs.com/package/@babel/core
  - @babel/preset-env from 7.14.5 to 7.14.8.
    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=upgrade-pr
2021-08-11 11:34:26 +01:00
snyk-bot
7a6e8a2940 fix: upgrade @grpc/grpc-js from 1.3.5 to 1.3.6
Snyk has created this PR to upgrade @grpc/grpc-js from 1.3.5 to 1.3.6.

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

See this project in Snyk:
https://app.snyk.io/org/bluewallet/project/29c066bc-abce-44d9-b68e-064466e610e7?utm_source=github&utm_medium=upgrade-pr
2021-08-10 12:14:34 +01:00
snyk-bot
96e82ad20d fix: upgrade @grpc/grpc-js from 1.3.4 to 1.3.5
Snyk has created this PR to upgrade @grpc/grpc-js from 1.3.4 to 1.3.5.

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

See this project in Snyk:
https://app.snyk.io/org/bluewallet/project/29c066bc-abce-44d9-b68e-064466e610e7?utm_source=github&utm_medium=upgrade-pr
2021-08-04 14:07:49 +01:00
snyk-bot
406afef7f7 fix: upgrade express-rate-limit from 5.2.6 to 5.3.0
Snyk has created this PR to upgrade express-rate-limit from 5.2.6 to 5.3.0.

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=upgrade-pr
2021-07-23 12:08:37 +01:00
snyk-bot
3ebe1938ab fix: upgrade core-js from 3.14.0 to 3.15.2
Snyk has created this PR to upgrade core-js from 3.14.0 to 3.15.2.

See this package in npm:
https://www.npmjs.com/package/core-js

See this project in Snyk:
https://app.snyk.io/org/bluewallet/project/29c066bc-abce-44d9-b68e-064466e610e7?utm_source=github&utm_medium=upgrade-pr
2021-07-21 12:35:06 +01:00
snyk-bot
ee2398f247 fix: upgrade @grpc/proto-loader from 0.6.3 to 0.6.4
Snyk has created this PR to upgrade @grpc/proto-loader from 0.6.3 to 0.6.4.

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=upgrade-pr
2021-07-21 12:32:48 +01:00
xanoni
bc84429b61 README.md: cleaned up and removed 'deprecatedrpc' recommendation 2021-07-20 11:35:05 +01:00
snyk-bot
ec3039d91d fix: upgrade bolt11 from 1.3.1 to 1.3.2
Snyk has created this PR to upgrade bolt11 from 1.3.1 to 1.3.2.

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

See this project in Snyk:
https://app.snyk.io/org/bluewallet/project/29c066bc-abce-44d9-b68e-064466e610e7?utm_source=github&utm_medium=upgrade-pr
2021-07-20 11:33:21 +01:00
snyk-bot
1483449529 fix: upgrade @grpc/grpc-js from 1.3.3 to 1.3.4
Snyk has created this PR to upgrade @grpc/grpc-js from 1.3.3 to 1.3.4.

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

See this project in Snyk:
https://app.snyk.io/org/bluewallet/project/29c066bc-abce-44d9-b68e-064466e610e7?utm_source=github&utm_medium=upgrade-pr
2021-07-17 11:41:40 +01:00
snyk-bot
e0f037ea95 fix: upgrade jayson from 3.6.3 to 3.6.4
Snyk has created this PR to upgrade jayson from 3.6.3 to 3.6.4.

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

See this project in Snyk:
https://app.snyk.io/org/bluewallet/project/29c066bc-abce-44d9-b68e-064466e610e7?utm_source=github&utm_medium=upgrade-pr
2021-07-17 11:41:18 +01:00
snyk-bot
b4f880b35d fix: upgrade @grpc/proto-loader from 0.6.2 to 0.6.3
Snyk has created this PR to upgrade @grpc/proto-loader from 0.6.2 to 0.6.3.

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=upgrade-pr
2021-07-16 11:06:57 +01:00
Overtorment
35fe816d0a Merge branch 'master' of github.com:BlueWallet/LndHub into sunset 2021-07-14 17:29:00 +01:00
snyk-bot
4a4daccecd fix: upgrade @grpc/grpc-js from 1.3.2 to 1.3.3
Snyk has created this PR to upgrade @grpc/grpc-js from 1.3.2 to 1.3.3.

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

See this project in Snyk:
https://app.snyk.io/org/bluewallet/project/29c066bc-abce-44d9-b68e-064466e610e7?utm_source=github&utm_medium=upgrade-pr
2021-07-14 16:53:23 +01:00
16 changed files with 5275 additions and 3116 deletions

15
.dockerignore Normal file
View File

@ -0,0 +1,15 @@
*
!build/
!class/
!controllers/
!scripts/
!static/
!templates/
!utils/
!*.js
!.babelrc
!.eslint*
!admin.macaroon
!package*.json
!rpc.proto
!tls.cert

1
.gitignore vendored
View File

@ -2,6 +2,7 @@
admin.macaroon
tls.cert
build/
logs/
# dependencies

View File

@ -6,26 +6,24 @@ 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
WORKDIR /lndhub
# Copy 'package-lock.json' and 'package.json'
COPY package.json package-lock.json ./
# Copy project files and folders to the current working directory
COPY . .
# Install dependencies
RUN npm i
# Copy project files and folders to the current working directory
COPY . .
RUN npm run dockerbuild
# Delete git data as it's not needed inside the container
RUN rm -rf .git
FROM node:12-buster-slim
FROM node:16-alpine
# Create a specific user so LNDHub doesn't run as root
COPY --from=perms /etc/group /etc/passwd /etc/shadow /etc/
@ -34,10 +32,11 @@ COPY --from=perms /etc/group /etc/passwd /etc/shadow /etc/
COPY --from=builder /lndhub /lndhub
# Create logs folder and ensure permissions are set correctly
RUN mkdir /lndhub/logs && chown -R lndhub:lndhub /lndhub
RUN mkdir -p /lndhub/logs && chown -R lndhub:lndhub /lndhub
USER lndhub
ENV PORT=3000
EXPOSE 3000
WORKDIR /lndhub
CMD cp $LND_CERT_FILE /lndhub/ && cp $LND_ADMIN_MACAROON_FILE /lndhub/ && cd /lndhub && npm start

View File

@ -1,7 +1,7 @@
LndHub
======
Wrapper for Lightning Network Daemon. It provides separate accounts with minimum trust for end users
Wrapper for Lightning Network Daemon (lnd). It provides separate accounts with minimum trust for end users.
INSTALLATION
------------
@ -17,15 +17,17 @@ cd LndHub
npm i
```
Install `bitcoind`, `lnd` and `redis`. Edit `config.js` and set it up correctly.
Copy `admin.macaroon` and `tls.cert` in root folder of LndHub.
Install `bitcoind`, `lnd`, and `redis`. Edit LndHub's `config.js` to set it up correctly.
Copy the files `admin.macaroon` (for Bitcoin mainnet, usually stored in `~/.lnd/data/chain/bitcoin/mainnet/admin.macaroon`)
and `tls.cert` (usually stored in `~/.lnd/tls.cert`) into the root folder of LndHub.
`bitcoind` should run with `-deprecatedrpc=accounts`, for now. Lndhub expects Lnd's wallet to be unlocked, if not - it will attempt to unlock it with password stored in `config.lnd.password`.
Don't forget to enable disk-persistance for `redis`.
LndHub expects LND's wallet to be unlocked, if not — it will attempt to unlock it with the password stored in `config.lnd.password`.
Don't forget to configure disk-persistence for `redis` (e.g., you may want to set `appendonly` to `yes` in `redis.conf` (see
http://redis.io/topics/persistence for more information).
If you have no `bitcoind` instance, for example if you use neutrino, or you have no bitcoind wallet,
for example if you use LND for wallet managment, you can remove the bitcoind settings from `config.js`.
Please not that this feature is limited to Bitcoin, so you can't use this feature if you use any other cryptocurrency with LND.
Please note that this feature is limited to Bitcoin, so you can't use it if you use any other cryptocurrency with LND (e.g., Litecoin).
### Deploy to Heroku
@ -44,12 +46,13 @@ You can also view Umbrel's implementation using docker-compose [here](https://gi
Can be used in ReactNative or Nodejs environment
* https://github.com/BlueWallet/BlueWallet/blob/master/class/lightning-custodian-wallet.js
* https://github.com/BlueWallet/BlueWallet/blob/master/class/wallets/lightning-custodian-wallet.js
### 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)
@ -57,5 +60,5 @@ Acceptance tests are in https://github.com/BlueWallet/BlueWallet/blob/master/Lig
## Responsible disclosure
Found critical bugs/vulnerabilities? Please email them bluewallet@bluewallet.io
Found critical bugs/vulnerabilities? Please email them to bluewallet@bluewallet.io
Thanks!

View File

@ -12,10 +12,6 @@ export class Paym {
this._isPaid = null;
}
static get fee() {
return 0.003;
}
setInvoice(bolt11) {
this._bolt11 = bolt11;
}
@ -39,7 +35,7 @@ export class Paym {
pub_key: this._decoded.destination,
amt: this._decoded.num_satoshis,
final_cltv_delta: 144,
fee_limit: { fixed: Math.floor(this._decoded.num_satoshis * 0.01) + 1 },
fee_limit: { fixed: Math.floor(this._decoded.num_satoshis * forwardFee) + 1 },
};
let that = this;
return new Promise(function (resolve, reject) {
@ -74,7 +70,7 @@ export class Paym {
if (payment && payment.payment_route && payment.payment_route.total_amt_msat) {
// paid just now
this._isPaid = true;
payment.payment_route.total_fees = +payment.payment_route.total_fees + Math.floor(+payment.payment_route.total_amt * Paym.fee);
payment.payment_route.total_fees = +payment.payment_route.total_fees + Math.floor(+payment.payment_route.total_amt * internalFee);
if (this._bolt11) payment.pay_req = this._bolt11;
if (this._decoded) payment.decoded = this._decoded;
}
@ -87,7 +83,7 @@ export class Paym {
if (this._bolt11) payment.pay_req = this._bolt11;
// trying to guess the fee
payment.payment_route = payment.payment_route || {};
payment.payment_route.total_fees = Math.floor(this._decoded.num_satoshis * 0.01); // we dont know the exact fee, so we use max (same as fee_limit)
payment.payment_route.total_fees = Math.floor(this._decoded.num_satoshis * forwardFee); // we dont know the exact fee, so we use max (same as fee_limit)
payment.payment_route.total_amt = this._decoded.num_satoshis;
}
}

View File

@ -119,6 +119,12 @@ export class User {
return new Promise(function (resolve, reject) {
self._lightning.newAddress({ type: 0 }, async function (err, response) {
if (err) return reject('LND failure when trying to generate new address');
const addressAlreadyExists = await self.getAddress();
if (addressAlreadyExists) {
// one last final check, for a case of really long race condition
resolve();
return;
}
await self.addAddress(response.address);
if (config.bitcoind) self._bitcoindrpc.request('importaddress', [response.address, response.address, false]);
resolve();
@ -175,7 +181,7 @@ export class User {
let lockedPayments = await this.getLockedPayments();
for (let paym of lockedPayments) {
// locked payments are processed in scripts/process-locked-payments.js
calculatedBalance -= +paym.amount + /* feelimit */ Math.floor(paym.amount * 0.01);
calculatedBalance -= +paym.amount + /* feelimit */ Math.floor(paym.amount * forwardFee);
}
return calculatedBalance;

View File

@ -2,6 +2,8 @@ let config = {
enableUpdateDescribeGraph: false,
postRateLimit: 100,
rateLimit: 200,
forwardReserveFee: 0.01, // default 0.01
intraHubFee: 0.003, // default 0.003
bitcoind: {
rpc: 'http://login:password@1.1.1.1:8332/wallet/wallet.dat',
},

View File

@ -1,11 +1,13 @@
import { User, Lock, Paym, Invo } from '../class/';
import Frisbee from 'frisbee';
import fetch from 'node-fetch';
const config = require('../config');
let express = require('express');
let router = express.Router();
let logger = require('../utils/logger');
const MIN_BTC_BLOCK = 670000;
console.log('using config', JSON.stringify(config));
if (process.env.NODE_ENV !== 'prod') {
console.log('using config', JSON.stringify(config));
}
var Redis = require('ioredis');
var redis = new Redis(config.redis);
@ -15,6 +17,12 @@ redis.monitor(function (err, monitor) {
});
});
/****** 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 ******/
let bitcoinclient = require('../bitcoin');
let lightning = require('../lightning');
let identity_pubkey = false;
@ -84,21 +92,16 @@ const subscribeInvoicesCallCallback = async function (response) {
console.log('payment', LightningInvoiceSettledNotification.hash, 'was paid, posting to GroundControl...');
const baseURI = process.env.GROUNDCONTROL;
if (!baseURI) return;
const _api = new Frisbee({ baseURI: baseURI });
const apiResponse = await _api.post(
'/lightningInvoiceGotSettled',
Object.assign(
{},
{
headers: {
'Access-Control-Allow-Origin': '*',
'Content-Type': 'application/json',
},
body: LightningInvoiceSettledNotification,
},
),
);
console.log('GroundControl:', apiResponse.originalResponse.status);
const apiResponse = await fetch(`${baseURI}/lightningInvoiceGotSettled`, {
method: 'POST',
headers: {
'Access-Control-Allow-Origin': '*',
'Content-Type': 'application/json',
},
body: JSON.stringify(LightningInvoiceSettledNotification),
});
console.log('Groundcontrol apiResponse=', apiResponse);
}
};
let subscribeInvoicesCall = lightning.subscribeInvoices({});
@ -133,7 +136,11 @@ const postLimiter = rateLimit({
router.post('/create', postLimiter, async function (req, res) {
logger.log('/create', [req.id]);
if (!(req.body.partnerid && req.body.partnerid === 'bluewallet' && req.body.accounttype)) return errorBadArguments(res);
// Valid if the partnerid isn't there or is a string (same with accounttype)
if (! (
(!req.body.partnerid || (typeof req.body.partnerid === 'string' || req.body.partnerid instanceof String))
&& (!req.body.accounttype || (typeof req.body.accounttype === 'string' || req.body.accounttype instanceof String))
) ) return errorBadArguments(res);
if (config.sunset) return errorSunset(res);
@ -192,7 +199,7 @@ router.post('/addinvoice', postLimiter, async function (req, res) {
);
});
router.post('/payinvoice', async function (req, res) {
router.post('/payinvoice', postLimiter, async function (req, res) {
let u = new User(redis, bitcoinclient, lightning);
if (!(await u.loadByAuthorization(req.headers.authorization))) {
return errorBadAuth(res);
@ -235,7 +242,7 @@ router.post('/payinvoice', async function (req, res) {
logger.log('/payinvoice', [req.id, 'userBalance: ' + userBalance, 'num_satoshis: ' + info.num_satoshis]);
if (userBalance >= +info.num_satoshis + Math.floor(info.num_satoshis * 0.01)) {
if (userBalance >= +info.num_satoshis + Math.floor(info.num_satoshis * forwardFee) + 1) {
// got enough balance, including 1% of payment amount - reserve for fees
if (identity_pubkey === info.destination) {
@ -262,8 +269,8 @@ router.post('/payinvoice', async function (req, res) {
await u.savePaidLndInvoice({
timestamp: parseInt(+new Date() / 1000),
type: 'paid_invoice',
value: +info.num_satoshis + Math.floor(info.num_satoshis * Paym.fee),
fee: Math.floor(info.num_satoshis * Paym.fee),
value: +info.num_satoshis + Math.floor(info.num_satoshis * internalFee),
fee: Math.floor(info.num_satoshis * internalFee),
memo: decodeURIComponent(info.description),
pay_req: req.body.invoice,
});
@ -316,7 +323,7 @@ router.post('/payinvoice', async function (req, res) {
let inv = {
payment_request: req.body.invoice,
amt: info.num_satoshis, // amt is used only for 'tip' invoices
fee_limit: { fixed: Math.floor(info.num_satoshis * 0.005) + 1 },
fee_limit: { fixed: Math.floor(info.num_satoshis * forwardFee) + 1 },
};
try {
await u.lockFunds(req.body.invoice, info);
@ -403,7 +410,7 @@ router.get('/getinfo', postLimiter, async function (req, res) {
});
});
router.get('/gettxs', async function (req, res) {
router.get('/gettxs', postLimiter, async function (req, res) {
logger.log('/gettxs', [req.id]);
let u = new User(redis, bitcoinclient, lightning);
if (!(await u.loadByAuthorization(req.headers.authorization))) {
@ -419,8 +426,8 @@ router.get('/gettxs', async function (req, res) {
for (let locked of lockedPayments) {
txs.push({
type: 'paid_invoice',
fee: Math.floor(locked.amount * 0.01) /* feelimit */,
value: locked.amount + Math.floor(locked.amount * 0.01) /* feelimit */,
fee: Math.floor(locked.amount * forwardFee) /* feelimit */,
value: locked.amount + Math.floor(locked.amount * forwardFee) /* feelimit */,
timestamp: locked.timestamp,
memo: 'Payment in transition',
});
@ -449,7 +456,7 @@ router.get('/getuserinvoices', postLimiter, async function (req, res) {
}
});
router.get('/getpending', async function (req, res) {
router.get('/getpending', postLimiter, async function (req, res) {
logger.log('/getpending', [req.id]);
let u = new User(redis, bitcoinclient, lightning);
if (!(await u.loadByAuthorization(req.headers.authorization))) {
@ -463,7 +470,7 @@ router.get('/getpending', async function (req, res) {
res.send(txs);
});
router.get('/decodeinvoice', async function (req, res) {
router.get('/decodeinvoice', postLimiter, async function (req, res) {
logger.log('/decodeinvoice', [req.id]);
let u = new User(redis, bitcoinclient, lightning);
if (!(await u.loadByAuthorization(req.headers.authorization))) {

View File

@ -62,6 +62,7 @@ const pubkey2name = {
'030c3f19d742ca294a55c00376b3b355c3c90d61c6b6b39554dbc7ac19b141c14f': 'bitrefill.com',
'03864ef025fde8fb587d989186ce6a4a186895ee44a926bfc370e2c366597a3f8f': 'ACINQ',
'03abf6f44c355dec0d5aa155bdbdd6e0c8fefe318eff402de65c6eb2e1be55dc3e': 'OpenNode',
'028d98b9969fbed53784a36617eb489a59ab6dc9b9d77fcdca9ff55307cd98e3c4': 'OpenNode 2',
'0242a4ae0c5bef18048fbecf995094b74bfb0f7391418d71ed394784373f41e4f3': 'coingate.com',
'0279c22ed7a068d10dc1a38ae66d2d6461e269226c60258c021b1ddcdfe4b00bc4': 'ln1.satoshilabs.com',
'02c91d6aa51aa940608b497b6beebcb1aec05be3c47704b682b3889424679ca490': 'lnd-21.LNBIG.com',
@ -82,6 +83,10 @@ const pubkey2name = {
'033d8656219478701227199cbd6f670335c8d408a92ae88b962c49d4dc0e83e025': 'bfx-lnd0',
'03021c5f5f57322740e4ee6936452add19dc7ea7ccf90635f95119ab82a62ae268': 'lnd1.bluewallet.io',
'037cc5f9f1da20ac0d60e83989729a204a33cc2d8e80438969fadf35c1c5f1233b': 'lnd2.bluewallet.io',
'036b53093df5a932deac828cca6d663472dbc88322b05eec1d42b26ab9b16caa1c': 'okcoin',
'038f8f113c580048d847d6949371726653e02b928196bad310e3eda39ff61723f6': 'magnetron',
'03829249ef39746fd534a196510232df08b83db0967804ec71bf4120930864ff97': 'blokada.org',
'02ce691b2e321954644514db708ba2a72769a6f9142ac63e65dd87964e9cf2add9': 'Satoshis.Games',
};
router.get('/', function (req, res) {
@ -100,7 +105,8 @@ router.get('/qr', function (req, res) {
if (process.env.TOR_URL) {
host = process.env.TOR_URL;
}
const url = 'bluewallet:setlndhuburl?url=' + encodeURIComponent(req.protocol + '://' + host);
const customPath = req.url.replace('/qr', '');
const url = 'bluewallet:setlndhuburl?url=' + encodeURIComponent(req.protocol + '://' + host + customPath);
var code = qr.image(url, { type: 'png' });
res.setHeader('Content-type', 'image/png');
code.pipe(res);

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

View File

@ -47,7 +47,11 @@ app.use('/static', express.static('static'));
app.use(require('./controllers/api'));
app.use(require('./controllers/website'));
let server = app.listen(process.env.PORT || 3000, function () {
logger.log('BOOTING UP', 'Listening on port ' + (process.env.PORT || 3000));
const bindHost = process.env.HOST || '0.0.0.0';
const bindPort = process.env.PORT || 3000;
let server = app.listen(bindPort, bindHost, function () {
logger.log('BOOTING UP', 'Listening on ' + bindHost + ':' + bindPort);
logger.log('using GroundControl', process.env.GROUNDCONTROL);
});
module.exports = server;

7898
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,10 +1,11 @@
{
"name": "lndhub",
"version": "1.3.5",
"version": "1.4.3",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"dockerbuild": "./node_modules/.bin/babel ./ --ignore node_modules/ --ignore *.spec.js --out-dir ./build",
"dev": "nodemon node_modules/.bin/babel-node index.js",
"start": "node_modules/.bin/babel-node index.js",
"lint": "./node_modules/.bin/eslint ./ controllers/ class/ --fix"
@ -12,29 +13,28 @@
"author": "Igor Korsakov <overtorment@gmail.com>",
"license": "MIT",
"dependencies": {
"@babel/cli": "^7.14.5",
"@babel/core": "^7.14.5",
"@babel/cli": "^7.14.8",
"@babel/core": "^7.15.0",
"@babel/eslint-parser": "^7.14.2",
"@babel/node": "^7.14.5",
"@babel/preset-env": "^7.14.5",
"@babel/node": "^7.14.9",
"@babel/preset-env": "^7.22.0",
"@babel/register": "^7.14.5",
"@grpc/grpc-js": "^1.3.2",
"@grpc/proto-loader": "^0.6.2",
"@grpc/grpc-js": "^1.3.7",
"@grpc/proto-loader": "^0.6.5",
"bignumber.js": "^9.0.1",
"bitcoinjs-lib": "^5.2.0",
"bolt11": "^1.3.1",
"core-js": "^3.14.0",
"bolt11": "^1.3.2",
"eslint": "^7.24.0",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-prettier": "^3.4.0",
"express": "^4.17.1",
"express-rate-limit": "^5.2.6",
"frisbee": "^3.1.4",
"express-rate-limit": "^5.4.1",
"helmet": "^4.6.0",
"ioredis": "^4.27.2",
"jayson": "^3.6.3",
"ioredis": "^4.27.10",
"jayson": "^3.6.4",
"morgan": "^1.10.0",
"mustache": "^4.1.0",
"node-fetch": "^2.6.1",
"prettier": "^2.3.0",
"qr-image": "3.2.0",
"request": "^2.88.2",

View File

@ -9,6 +9,11 @@ const important_channels = {
uri: '03abf6f44c355dec0d5aa155bdbdd6e0c8fefe318eff402de65c6eb2e1be55dc3e@18.221.23.28:9735',
wumbo: 1,
},
'028d98b9969fbed53784a36617eb489a59ab6dc9b9d77fcdca9ff55307cd98e3c4': {
name: 'OpenNode 2',
uri: '028d98b9969fbed53784a36617eb489a59ab6dc9b9d77fcdca9ff55307cd98e3c4@18.222.70.85:9735',
wumbo: 1,
},
// '0242a4ae0c5bef18048fbecf995094b74bfb0f7391418d71ed394784373f41e4f3': {
// name: 'coingate.com',
// uri: '0242a4ae0c5bef18048fbecf995094b74bfb0f7391418d71ed394784373f41e4f3@3.124.63.44:9735',
@ -78,7 +83,7 @@ lightning.listChannels({}, function (err, response) {
}
let lightningListChannels = response;
for (let channel of lightningListChannels.channels) {
if (channel.capacity < 0.05 / 100000000) {
if (channel.capacity <= 1000000) {
console.log(
'lncli closechannel',
channel.channel_point.replace(':', ' '),

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,52 +43,33 @@ let lightning = require('../lightning');
let payment = new Paym(redis, bitcoinclient, lightning);
payment.setInvoice(lockedPayment.pay_req);
if (daysPassed > 1 / 24 && daysPassed <= 1) {
// if (!await payment.isExpired()) {
let sendResult;
console.log('attempting to pay to route');
try {
sendResult = await payment.attemptPayToRoute();
} catch (_) {
console.log(_);
console.log('evict lock');
await user.unlockFunds(lockedPayment.pay_req);
continue;
}
console.log('sendResult=', sendResult);
console.log('payment.getIsPaid() = ', payment.getIsPaid());
if (payment.getIsPaid() === true) {
console.log('paid successfully');
sendResult = payment.processSendPaymentResponse(sendResult); // adds fees
// 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
if (sendResult.decoded.num_satoshis == 0) {
// zero sat invoice, get corect sat number from the lockedPayment info
sendResult.decoded.num_satoshis = lockedPayment.amount + Math.ceil(lockedPayment.amount * forwardFee);
sendResult.decoded.num_msat = sendResult.decoded.num_satoshis * 1000;
sendResult.payment_route.total_fees = 0;
sendResult.payment_route.total_amt = sendResult.decoded.num_satoshis;
}
console.log('saving paid invoice:', sendResult);
await user.savePaidLndInvoice(sendResult);
await user.unlockFunds(lockedPayment.pay_req);
} else if (payment.getIsPaid() === false) {
console.log('not paid, just evict the lock');
await user.unlockFunds(lockedPayment.pay_req);
} else {
console.log('payment is in unknown state');
}
console.log('sleeping 5 sec...');
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;
}
isPaid = true;
console.log('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!', await payment.getPaymentHash(), sentPayment.payment_hash);
break;
}
}
// could not find...
if (daysPassed > 1) {
// 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);

View File

@ -50,9 +50,10 @@ let lightning = require('../lightning');
let locked = await U.getLockedPayments();
for (let loc of locked) {
console.log('-', loc.amount + /* fee limit */ Math.floor(loc.amount * 0.01), new Date(loc.timestamp * 1000).toString(), '[locked]');
console.log('-', loc.amount + /* fee limit */ Math.floor(loc.amount * config.forwardReserveFee), new Date(loc.timestamp * 1000).toString(), '[locked]');
}
console.log('\ncalculatedBalance\n================\n', calculatedBalance, await U.getCalculatedBalance());
console.log('txs:', txs.length, 'userinvoices:', userinvoices.length);
process.exit();
})();