From d1e0d34906fed3e5f9fd4a97286fe821e28c955e Mon Sep 17 00:00:00 2001 From: Adam Soltys Date: Mon, 25 Jul 2022 22:36:55 -0700 Subject: comment out last seen check --- lib/sockets.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/sockets.js b/lib/sockets.js index 30a6b49d..e216d904 100644 --- a/lib/sockets.js +++ b/lib/sockets.js @@ -93,7 +93,7 @@ wss.on("connection", function(ws, req) { case "login": let token = data; - if (differenceInSeconds(new Date(), lastSeen[token]) < 5) return; + // if (differenceInSeconds(new Date(), lastSeen[token]) < 5) return; lastSeen[token] = new Date(); try { -- cgit v1.2.3 From a1db0ff265beb3112591f31f593b99872ff37eb6 Mon Sep 17 00:00:00 2001 From: Adam Soltys Date: Tue, 26 Jul 2022 09:57:34 -0700 Subject: remove datadir flags from readme --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index ad1a6724..b031ea7a 100644 --- a/README.md +++ b/README.md @@ -83,7 +83,7 @@ Under `lna`, update the values for `cert` and `macaroon` with the output from th If your app logs complain that the wallet was not found, do the following: ```bash docker-compose exec bitcoin bash -bitcoin-cli -datadir=config/ createwallet coinos +bitcoin-cli createwallet coinos exit docker exec -it lnd lncli --network=regtest --chain=bitcoin unlock ``` @@ -193,11 +193,11 @@ I've only tested with Maria. Here's a [schema generate some blocks - docker exec -it bitcoin bitcoin-cli -datadir=config/ generatetoaddress 1 $(docker exec -it bitcoin bitcoin-cli -datadir=config/ getnewaddress "" "legacy") + docker exec -it bitcoin bitcoin-cli generatetoaddress 1 $(docker exec -it bitcoin bitcoin-cli getnewaddress "" "legacy") get balance - docker exec -it bitcoin bitcoin-cli -datadir=config/ getbalance + docker exec -it bitcoin bitcoin-cli getbalance --- ##### Liquid @@ -206,11 +206,11 @@ The Liquid network gives you a starting balance of Bitcoin specified in the `con generate some blocks - docker exec -it liquid elements-cli -datadir=/home/elements/.elements generatetoaddress 1 $(docker exec -it liquid elements-cli -datadir=/home/elements/.elements getnewaddress) + docker exec -it liquid elements-cli generatetoaddress 1 $(docker exec -it liquid elements-cli getnewaddress) get balance - docker exec -it liquid elements-cli -datadir=/home/elements/.elements getbalance + docker exec -it liquid elements-cli getbalance --- ##### Lightning @@ -229,7 +229,7 @@ open a channel generate 10 btc blocks - docker exec -it bitcoin bitcoin-cli -datadir=config/ generatetoaddress 10 $(docker exec -it bitcoin bitcoin-cli -datadir=config/ getnewaddress "" "legacy") + docker exec -it bitcoin bitcoin-cli generatetoaddress 10 $(docker exec -it bitcoin bitcoin-cli getnewaddress "" "legacy") --- #### Test clightning payment -- cgit v1.2.3 From dca0fb848ae13dfaa4db305361803415cfe64873 Mon Sep 17 00:00:00 2001 From: Adam Soltys Date: Tue, 26 Jul 2022 09:58:02 -0700 Subject: specify subnet for network --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b031ea7a..86920b91 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ cd coinos-server cp -rf sampleconfig ./config cp .env.sample .env cp fx.sample fx -docker network create net +docker network create net --gateway 172.18.0.1 --subnet 172.18.0.0/16 docker run -it -v $(pwd):/app --entrypoint yarn asoltys/coinos-server docker-compose -f docker-compose.yml -f docker-compose.dev.yml up -d docker exec -i mariadb mysql -u root -ppassword < db/schema.sql -- cgit v1.2.3 From 08dab49e107bf6d9688b012c443151559d5e9e9e Mon Sep 17 00:00:00 2001 From: Adam Soltys Date: Tue, 26 Jul 2022 23:24:58 -0700 Subject: socket error logging --- lib/sockets.js | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/lib/sockets.js b/lib/sockets.js index e216d904..c80935d9 100644 --- a/lib/sockets.js +++ b/lib/sockets.js @@ -2,6 +2,7 @@ const jwt = require("jsonwebtoken"); const { v4: uuidv4 } = require("uuid"); const WebSocket = require("ws"); const { differenceInSeconds, subSeconds } = require("date-fns"); +const code = 1000; wss = new WebSocket.Server({ clientTracking: false, noServer: true }); @@ -64,7 +65,7 @@ setInterval(() => { for (const id in sockets[username]) { let ws = sockets[username][id]; ws.beats++; - if (ws.beats > 10) ws.close(); + if (ws.beats > 10) ws.close(code, "too many beats"); } } }, 2000); @@ -97,7 +98,7 @@ wss.on("connection", function(ws, req) { lastSeen[token] = new Date(); try { - if (!token || token === "null" || !jwt.decode(token)) return ws.close(); + if (!token || token === "null" || !jwt.decode(token)) return ws.close(code, `bad token ${token}`); const username = jwt.decode(token).username; if (!username) throw new Error("Invalid JWT token"); @@ -107,7 +108,7 @@ wss.on("connection", function(ws, req) { const p = existing.find(sid => sid !== id); sockets[username][p].send(JSON.stringify({ type: "logout" })); setTimeout(() => { - if (sockets[username][p]) sockets[username][p].close(); + if (sockets[username][p]) sockets[username][p].close(code, "too many sockets"); }, 5000); } sockets[username][id] = ws; @@ -151,7 +152,7 @@ wss.on("connection", function(ws, req) { } if (e.message.includes("not found")) ws.send(JSON.stringify({ type: "logout" })); - setTimeout(() => ws && ws.close(), 1000); + setTimeout(() => ws && ws.close(code, `closing due to error ${e.message}`), 1000); } break; case "token": @@ -186,7 +187,8 @@ wss.on("connection", function(ws, req) { } }); - ws.on("close", function() { + ws.on("close", function(code, reason) { + if (reason) console.log("closing socket", reason); try { const username = names[id]; if (sockets[username] && sockets[username][id]) { -- cgit v1.2.3 From 5c4b8d7ce23e7285d85e0a704e347910fb994112 Mon Sep 17 00:00:00 2001 From: Adam Soltys Date: Tue, 26 Jul 2022 23:25:06 -0700 Subject: return json for lightning invoice --- routes/lightning/invoice.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/routes/lightning/invoice.js b/routes/lightning/invoice.js index 054a4a46..31f23bd6 100644 --- a/routes/lightning/invoice.js +++ b/routes/lightning/invoice.js @@ -13,10 +13,10 @@ module.exports = ah(async (req, res) => { memo, 360 ); - res.send(invoice.bolt11); + res.send({ text: invoice.bolt11 }); } else { const invoice = await lnp.addInvoice({ value, memo }); - res.send(invoice.payment_request); + res.send({ text: invoice.payment_request }); } } catch (e) { l.error("problem creating invoice", e.message, e.stack); -- cgit v1.2.3 From 1eefc859b253f32367934bcddfbcc1d12998938e Mon Sep 17 00:00:00 2001 From: Adam Soltys Date: Tue, 26 Jul 2022 23:39:05 -0700 Subject: socket error message --- lib/sockets.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/sockets.js b/lib/sockets.js index c80935d9..f482a445 100644 --- a/lib/sockets.js +++ b/lib/sockets.js @@ -65,7 +65,7 @@ setInterval(() => { for (const id in sockets[username]) { let ws = sockets[username][id]; ws.beats++; - if (ws.beats > 10) ws.close(code, "too many beats"); + if (ws.beats > 10) ws.close(code, `${username} ${id} lost heartbeat`); } } }, 2000); -- cgit v1.2.3 From f56bf4375e30ce7b8569d9e259fcdd89922fef3d Mon Sep 17 00:00:00 2001 From: Adam Soltys Date: Sat, 30 Jul 2022 11:10:21 -0700 Subject: mainnet yml file --- docker-compose.mainnet.yml | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 docker-compose.mainnet.yml diff --git a/docker-compose.mainnet.yml b/docker-compose.mainnet.yml new file mode 100644 index 00000000..db4ba9e8 --- /dev/null +++ b/docker-compose.mainnet.yml @@ -0,0 +1,11 @@ +version: '3.6' +services: + lm: + image: ghcr.io/vulpemventures/elements + container_name: lm + volumes: + - ./config/liquidmainnet:/home/elements/.elements + restart: unless-stopped + networks: + default: + ipv4_address: 172.18.0.41 -- cgit v1.2.3 From 82f9acc60b7edbdfee96f1553d0fb1dcc705b866 Mon Sep 17 00:00:00 2001 From: Adam Soltys Date: Sat, 30 Jul 2022 11:10:47 -0700 Subject: don't require auth for invoice, default uuid value --- db/models/invoices.js | 2 +- routes/invoices.js | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/db/models/invoices.js b/db/models/invoices.js index a51ee3f9..324da9ad 100644 --- a/db/models/invoices.js +++ b/db/models/invoices.js @@ -76,7 +76,7 @@ const attributes = { uuid: { type: DataTypes.STRING(255), allowNull: true, - defaultValue: null, + defaultValue: DataTypes.UUIDV4, primaryKey: false, autoIncrement: false, comment: null, diff --git a/routes/invoices.js b/routes/invoices.js index 51906b8c..1208e14e 100644 --- a/routes/invoices.js +++ b/routes/invoices.js @@ -3,7 +3,6 @@ const axios = require("axios"); app.get( "/invoice", - auth, ah(async (req, res, next) => { try { const invoice = await db.Invoice.findOne({ -- cgit v1.2.3 From 99b7b4fbeb64e2e4512211c9c2a4a085bacd96d8 Mon Sep 17 00:00:00 2001 From: Adam Soltys Date: Mon, 1 Aug 2022 22:17:58 -0700 Subject: record invoice status --- db/models/invoices.js | 9 +++++++++ routes/invoices.js | 9 +++++++-- routes/lightning/receive.js | 4 ++++ 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/db/models/invoices.js b/db/models/invoices.js index 324da9ad..d985ce82 100644 --- a/db/models/invoices.js +++ b/db/models/invoices.js @@ -154,6 +154,15 @@ const attributes = { comment: null, field: "webhook" }, + status: { + type: DataTypes.TEXT, + allowNull: true, + defaultValue: "unpaid", + primaryKey: false, + autoIncrement: false, + comment: null, + field: "status" + }, tip: { type: DataTypes.DOUBLE, allowNull: true, diff --git a/routes/invoices.js b/routes/invoices.js index 1208e14e..b5650735 100644 --- a/routes/invoices.js +++ b/routes/invoices.js @@ -8,7 +8,12 @@ app.get( const invoice = await db.Invoice.findOne({ where: { uuid: req.query.uuid - } + }, + include: { + model: db.User, + as: "user", + attributes: ['username'] + } }); res.send(invoice); @@ -23,7 +28,7 @@ app.post( optionalAuth, ah(async (req, res, next) => { try { - let { liquidAddress, invoice, user, tx } = req.body; + let { liquidAddress, id, invoice, user, tx } = req.body; let { blindkey } = invoice; if (invoice.amount < 0) throw new Error("amount out of range"); diff --git a/routes/lightning/receive.js b/routes/lightning/receive.js index 89ad4c29..c9e7dec7 100644 --- a/routes/lightning/receive.js +++ b/routes/lightning/receive.js @@ -61,6 +61,9 @@ const handlePayment = async (msg) => { total = amount + tip; invoice.received += total; + invoice.status = 'paid'; + await invoice.save({ transaction }); + await account.increment({ balance: total }, { transaction }); // get the # of fee credits you would need to pay off this amount of bitcoin await account.increment({ lightning_credits: computeConversionFee(total) }, { transaction }); @@ -71,6 +74,7 @@ const handlePayment = async (msg) => { payment = payment.get({ plain: true }); payment.account = account.get({ plain: true }); + payment.invoice= invoice.get({ plain: true }); callWebhook(invoice, payment); -- cgit v1.2.3 From 7f9e89f2e9743208f3ababf22eadb7afd670b494 Mon Sep 17 00:00:00 2001 From: Adam Soltys Date: Thu, 4 Aug 2022 22:05:09 -0700 Subject: use pnpm --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 86920b91..5702c76e 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ cp -rf sampleconfig ./config cp .env.sample .env cp fx.sample fx docker network create net --gateway 172.18.0.1 --subnet 172.18.0.0/16 -docker run -it -v $(pwd):/app --entrypoint yarn asoltys/coinos-server +docker run -it -v $(pwd):/app --entrypoint pnpm asoltys/coinos-server i docker-compose -f docker-compose.yml -f docker-compose.dev.yml up -d docker exec -i mariadb mysql -u root -ppassword < db/schema.sql docker exec -it liquid elements-cli -conf=/home/elements/.elements/elements.conf sendtoaddress AzpsKhC6xE9FEK4aWAzMnbvueMLiSa5ym1xpuYogFkHzWgMHSt8B79aNNbFppQzCSQ2yZ9E4nL6RQJU7 1000000 -- cgit v1.2.3 From 94724a61c6c80918ddb925910eb348539b475edf Mon Sep 17 00:00:00 2001 From: Adam Soltys Date: Thu, 4 Aug 2022 22:15:58 -0700 Subject: update schema --- db/schema.sql | 88 ++++++++++++++++++++++++++++------------------------------- 1 file changed, 42 insertions(+), 46 deletions(-) diff --git a/db/schema.sql b/db/schema.sql index 854bd2a8..9ea20660 100644 --- a/db/schema.sql +++ b/db/schema.sql @@ -1,13 +1,13 @@ --- MySQL dump 10.14 Distrib 5.5.68-MariaDB, for Linux (x86_64) +-- MariaDB dump 10.19 Distrib 10.6.1-MariaDB, for debian-linux-gnu (x86_64) -- -- Host: localhost Database: coinos -- ------------------------------------------------------ --- Server version 5.5.68-MariaDB +-- Server version 10.6.1-MariaDB-1:10.6.1+maria~focal /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; -/*!40101 SET NAMES utf8 */; +/*!40101 SET NAMES utf8mb4 */; /*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; /*!40103 SET TIME_ZONE='+00:00' */; /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; @@ -19,7 +19,6 @@ -- Current Database: `coinos` -- -DROP DATABASE IF EXISTS `coinos`; CREATE DATABASE /*!32312 IF NOT EXISTS*/ `coinos` /*!40100 DEFAULT CHARACTER SET latin1 */; USE `coinos`; @@ -32,11 +31,11 @@ DROP TABLE IF EXISTS `SequelizeMeta`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8 */; CREATE TABLE `SequelizeMeta` ( - `name` varchar(255) COLLATE utf8_unicode_ci NOT NULL, + `name` varchar(255) COLLATE utf8mb3_unicode_ci NOT NULL, PRIMARY KEY (`name`), UNIQUE KEY `name` (`name`), UNIQUE KEY `SequelizeMeta_name_unique` (`name`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -58,17 +57,20 @@ CREATE TABLE `accounts` ( `ticker` varchar(255) DEFAULT NULL, `precision` int(11) DEFAULT NULL, `domain` varchar(255) DEFAULT NULL, - `contract` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin, - `index` int(11) NOT NULL DEFAULT '0', + `contract` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL, + `index` int(11) NOT NULL DEFAULT 0, `pubkey` varchar(255) DEFAULT NULL, `hide` tinyint(1) DEFAULT NULL, `seed` varchar(255) DEFAULT NULL, `path` varchar(255) DEFAULT NULL, `network` varchar(255) DEFAULT NULL, `privkey` varchar(255) DEFAULT NULL, + `btc_credits` double NOT NULL DEFAULT 0, + `liquid_credits` double NOT NULL DEFAULT 0, + `lightning_credits` double NOT NULL DEFAULT 0, PRIMARY KEY (`id`), KEY `asset` (`asset`) -) ENGINE=InnoDB AUTO_INCREMENT=21553 DEFAULT CHARSET=latin1; +) ENGINE=InnoDB AUTO_INCREMENT=21593 DEFAULT CHARSET=latin1; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -80,7 +82,7 @@ DROP TABLE IF EXISTS `codes`; /*!40101 SET character_set_client = utf8 */; CREATE TABLE `codes` ( `code` varchar(255) NOT NULL DEFAULT '', - `text` text, + `text` text DEFAULT NULL, PRIMARY KEY (`code`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1; /*!40101 SET character_set_client = @saved_cs_client */; @@ -116,7 +118,7 @@ DROP TABLE IF EXISTS `invoices`; CREATE TABLE `invoices` ( `id` int(11) NOT NULL AUTO_INCREMENT, `user_id` int(11) DEFAULT NULL, - `text` text, + `text` text DEFAULT NULL, `createdAt` datetime NOT NULL, `updatedAt` datetime NOT NULL, `rate` double DEFAULT NULL, @@ -127,11 +129,12 @@ CREATE TABLE `invoices` ( `tip` double DEFAULT NULL, `network` varchar(255) DEFAULT NULL, `unconfidential` varchar(255) DEFAULT NULL, - `uuid` varchar(255) DEFAULT NULL, - `memo` text, + `uuid` varchar(255) DEFAULT uuid(), + `memo` text DEFAULT NULL, `account_id` int(11) DEFAULT NULL, `path` varchar(255) DEFAULT NULL, - `webhook` text, + `webhook` text DEFAULT NULL, + `status` varchar(255) DEFAULT 'unpaid', PRIMARY KEY (`id`), KEY `part_of_unconfidential` (`unconfidential`(10)), KEY `text_index` (`text`(100)), @@ -141,7 +144,7 @@ CREATE TABLE `invoices` ( KEY `invoices_account_id_foreign` (`account_id`), CONSTRAINT `invoices_account_id_foreign` FOREIGN KEY (`account_id`) REFERENCES `accounts` (`id`), CONSTRAINT `invoices_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) -) ENGINE=InnoDB AUTO_INCREMENT=46708 DEFAULT CHARSET=latin1; +) ENGINE=InnoDB AUTO_INCREMENT=46953 DEFAULT CHARSET=latin1; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -158,7 +161,7 @@ CREATE TABLE `linkingkeys` ( `createdAt` datetime NOT NULL, `updatedAt` datetime NOT NULL, PRIMARY KEY (`id`) -) ENGINE=InnoDB AUTO_INCREMENT=12617 DEFAULT CHARSET=latin1; +) ENGINE=InnoDB AUTO_INCREMENT=12623 DEFAULT CHARSET=latin1; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -172,9 +175,9 @@ CREATE TABLE `migrations` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `name` varchar(255) DEFAULT NULL, `batch` int(11) DEFAULT NULL, - `migration_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + `migration_time` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(), PRIMARY KEY (`id`) -) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8mb4; +) ENGINE=InnoDB AUTO_INCREMENT=18 DEFAULT CHARSET=utf8mb4; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -205,7 +208,7 @@ CREATE TABLE `orders` ( `user_id` int(11) DEFAULT NULL, `createdAt` datetime NOT NULL, `updatedAt` datetime NOT NULL, - `accepted` tinyint(1) NOT NULL DEFAULT '0', + `accepted` tinyint(1) NOT NULL DEFAULT 0, `a1_id` int(11) DEFAULT NULL, `a2_id` int(11) DEFAULT NULL, `completedAt` datetime DEFAULT NULL, @@ -230,7 +233,7 @@ DROP TABLE IF EXISTS `payments`; CREATE TABLE `payments` ( `id` int(11) NOT NULL AUTO_INCREMENT, `user_id` int(11) DEFAULT NULL, - `hash` text, + `hash` text DEFAULT NULL, `createdAt` datetime NOT NULL, `updatedAt` datetime NOT NULL, `rate` double DEFAULT NULL, @@ -238,26 +241,29 @@ CREATE TABLE `payments` ( `address` varchar(255) DEFAULT NULL, `received` tinyint(1) DEFAULT NULL, `amount` double DEFAULT NULL, - `tip` double NOT NULL DEFAULT '0', + `tip` double NOT NULL DEFAULT 0, `confirmed` tinyint(1) NOT NULL, - `fee` double NOT NULL DEFAULT '0', + `fee` double NOT NULL DEFAULT 0, `network` varchar(255) DEFAULT NULL, `account_id` int(11) DEFAULT NULL, `preimage` varchar(255) DEFAULT NULL, - `memo` text, - `redeemed` tinyint(1) NOT NULL DEFAULT '0', + `memo` text DEFAULT NULL, + `redeemed` tinyint(1) NOT NULL DEFAULT 0, `redeemcode` varchar(255) DEFAULT NULL, `path` varchar(255) DEFAULT NULL, `invoice_id` int(11) DEFAULT NULL, + `fee_payment_id` int(11) DEFAULT NULL, PRIMARY KEY (`id`), KEY `idx_redeemcode` (`redeemcode`), KEY `payments_invoice_id_foreign` (`invoice_id`), KEY `payments_user_id_foreign` (`user_id`), KEY `payments_account_id_foreign` (`account_id`), + KEY `fk_payments` (`fee_payment_id`), + CONSTRAINT `fk_payments` FOREIGN KEY (`fee_payment_id`) REFERENCES `payments` (`id`), CONSTRAINT `payments_account_id_foreign` FOREIGN KEY (`account_id`) REFERENCES `accounts` (`id`), CONSTRAINT `payments_invoice_id_foreign` FOREIGN KEY (`invoice_id`) REFERENCES `invoices` (`id`), CONSTRAINT `payments_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) -) ENGINE=InnoDB AUTO_INCREMENT=29225 DEFAULT CHARSET=latin1; +) ENGINE=InnoDB AUTO_INCREMENT=29354 DEFAULT CHARSET=latin1; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -268,8 +274,8 @@ DROP TABLE IF EXISTS `prs`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8 */; CREATE TABLE `prs` ( - `text` text, - `preimage` text + `text` text DEFAULT NULL, + `preimage` text DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=latin1; /*!40101 SET character_set_client = @saved_cs_client */; @@ -314,16 +320,16 @@ CREATE TABLE `users` ( `updatedAt` datetime NOT NULL, `twofa` tinyint(1) DEFAULT NULL, `pin` varchar(255) DEFAULT NULL, - `currencies` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin, + `currencies` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL, `otpsecret` varchar(255) DEFAULT NULL, `account_id` int(11) DEFAULT NULL, `ip` int(10) unsigned DEFAULT NULL, - `subscriptions` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin, + `subscriptions` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL, `seed` varchar(255) DEFAULT NULL, - `fiat` tinyint(1) NOT NULL DEFAULT '0', - `index` int(11) NOT NULL DEFAULT '0', + `fiat` tinyint(1) NOT NULL DEFAULT 0, + `index` int(11) NOT NULL DEFAULT 0, `verified` varchar(255) DEFAULT NULL, - `locked` tinyint(1) DEFAULT '0', + `locked` tinyint(1) DEFAULT 0, `authyId` varchar(255) DEFAULT NULL, `admin` tinyint(1) DEFAULT NULL, `email` varchar(255) DEFAULT NULL, @@ -331,7 +337,7 @@ CREATE TABLE `users` ( PRIMARY KEY (`id`), KEY `ip` (`ip`), KEY `username` (`username`) -) ENGINE=InnoDB AUTO_INCREMENT=15377 DEFAULT CHARSET=latin1; +) ENGINE=InnoDB AUTO_INCREMENT=15411 DEFAULT CHARSET=latin1; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -347,7 +353,7 @@ CREATE TABLE `waiting_list` ( `phone` varchar(255) NOT NULL, `status` enum('pending','activated','expired','cancelled') NOT NULL, `user_id` int(11) DEFAULT NULL, - `notes` text, + `notes` text DEFAULT NULL, `created_at` datetime DEFAULT NULL, `updated_at` datetime DEFAULT NULL, PRIMARY KEY (`id`), @@ -373,7 +379,7 @@ CREATE TABLE `withdrawals` ( `transit` varchar(255) DEFAULT NULL, `account` varchar(255) DEFAULT NULL, `institution` varchar(255) DEFAULT NULL, - `notes` text, + `notes` text DEFAULT NULL, `email` varchar(255) DEFAULT NULL, PRIMARY KEY (`id`), KEY `withdrawals_user_id_foreign` (`user_id`), @@ -390,14 +396,4 @@ CREATE TABLE `withdrawals` ( /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; --- Dump completed on 2021-08-12 16:26:08 - -INSERT INTO migrations (name, batch) VALUES ('20210612181508_init_referrals.js', 1); -INSERT INTO migrations (name, batch) VALUES ('20210612192804_init_waiting_list.js.js', 1); -INSERT INTO migrations (name, batch) VALUES ('20210612203333_schema_diff_merges.js', 1); -INSERT INTO migrations (name, batch) VALUES ('20210625232223_add_invoice_id_to_payments.js', 1); -INSERT INTO migrations (name, batch) VALUES ('20210628221727_add_webhook_to_invoices.js', 1); -INSERT INTO migrations (name, batch) VALUES ('20210713174217_add_admin_to_users.js', 1); -INSERT INTO migrations (name, batch) VALUES ('20210714123455_data_fixes_merge.js', 1); -INSERT INTO migrations (name, batch) VALUES ('20210714123456_add_fks_merge.js', 1); -INSERT INTO migrations (name, batch) VALUES ('20210814193811_fix_db_conflicts.js', 1); +-- Dump completed on 2022-08-05 5:15:19 -- cgit v1.2.3 From 777d1775d0bb7ad0481328ed2d8960003aaa7984 Mon Sep 17 00:00:00 2001 From: Adam Soltys Date: Thu, 4 Aug 2022 23:17:47 -0700 Subject: readme update --- README.md | 238 +++++--------------------------------------------------------- 1 file changed, 17 insertions(+), 221 deletions(-) diff --git a/README.md b/README.md index 5702c76e..da59f04e 100644 --- a/README.md +++ b/README.md @@ -19,242 +19,38 @@ This repository contains the code for the backend API server which is implemente git clone https://github.com/coinos/coinos-server cd coinos-server cp -rf sampleconfig ./config +sudo chown 1000:1000 config/liquid +sudo chown 1000:1000 config/bitcoin cp .env.sample .env cp fx.sample fx docker network create net --gateway 172.18.0.1 --subnet 172.18.0.0/16 docker run -it -v $(pwd):/app --entrypoint pnpm asoltys/coinos-server i docker-compose -f docker-compose.yml -f docker-compose.dev.yml up -d docker exec -i mariadb mysql -u root -ppassword < db/schema.sql -docker exec -it liquid elements-cli -conf=/home/elements/.elements/elements.conf sendtoaddress AzpsKhC6xE9FEK4aWAzMnbvueMLiSa5ym1xpuYogFkHzWgMHSt8B79aNNbFppQzCSQ2yZ9E4nL6RQJU7 1000000 +docker exec -it bitcoin bitcoin-cli createwallet coinos +docker exec -it bitcoin bitcoin-cli generatetoaddress 1 bcrt1qwhrhu9feqkvmgdph0a4p248zzmy4grjr38a8uq +docker exec -it liquid elements-cli createwallet coinos +docker exec -it liquid elements-cli rescanblockchain +docker exec -it liquid elements-cli sendtoaddress AzpsKhC6xE9FEK4aWAzMnbvueMLiSa5ym1xpuYogFkHzWgMHSt8B79aNNbFppQzCSQ2yZ9E4nL6RQJU7 1000000 +docker exec -it liquid elements-cli generatetoaddress 1 AzpsKhC6xE9FEK4aWAzMnbvueMLiSa5ym1xpuYogFkHzWgMHSt8B79aNNbFppQzCSQ2yZ9E4nL6RQJU7 +docker exec -it lnd lncli create # set password to "password" +sed -i "s/# wallet/wallet/g" config/lnd/lnd.conf +CERT=$(sudo base64 config/lnd/tls.cert | tr -d '\n') +sed -i "s/LS0tL.*\"/$CERT\"/g" config/index.js +MACAROON=$(sudo base64 config/lnd/data/chain/bitcoin/regtest/admin.macaroon | tr -d '\n') +sed -i "s/AgED.*\"/$MACAROON\"/g" config/index.js ``` -then run this and keep reference to the result for the forthcoming [Config changes] +After successful creation of all docker containers coinos ui will be available at http://localhost:8085 and coinos server will be available at http://localhost:3119 -```bash -sudo base64 config/lnd/tls.cert | tr -d '\n' -``` -then run this and type a password when prompted, and then 'n' to create new wallet: - -```bash -docker exec -it lnd lncli create -``` -(optionally write down the seed as backup in case you lose the wallet and/or password) - -then uncomment line 12 of [config/lnd/lnd.conf] and update the [pwd file] with the new wallet password you just set. - -then run this and keep reference to the result again: -```bash -sudo base64 config/lnd/data/chain/bitcoin/regtest/admin.macaroon | tr -d '\n' -``` - -then run: -```bash -docker-compose down --remove-orphans -``` -and start it back up again with the same command from before: -```bash -docker-compose -f docker-compose.yml -f docker-compose.dev.yml up -d -``` - -and finally, create a Bitcoin wallet: - -``` -docker exec -it bitcoin bitcoin-cli -regtest -rpcuser=admin1 -rpcpassword=123 createwallet coinos -``` - -then [generate some BTC] to fund the server. - -For reviewing output, you may run `docker-compose logs` or run the docker-compose up command above but without the `-d `flag - -### Setup pre-commit git hooks - - We have a pre-commit git hook for running prettier on all files to keep the formatting consistent. - - `git config core.hooksPath "./git_hooks"` - This will set the git config path to use this directory for hooks. - - `chmod +x ./git_hooks/pre-commit` - This will give the hook the necessary permissions to run. - -### Config changes - -Navigate to `./config/index.js` -Under `lna`, update the values for `cert` and `macaroon` with the output from the respective commands you ran in the section above. - -### Wallet not found issues -If your app logs complain that the wallet was not found, do the following: -```bash -docker-compose exec bitcoin bash -bitcoin-cli createwallet coinos -exit -docker exec -it lnd lncli --network=regtest --chain=bitcoin unlock -``` -### Spinning down coinos & services - -from the root of this repo, run: - -```bash -docker-compose down --remove-orphans -``` - ---- - - -Note the initial `docker-compose up` step will take some time on first run as it will download all of the necessary images. - -After successful creation of all docker containers coinos will be available at http://localhost:8085 - -To shutdown coinos and all of its containers/services, run `docker-compose down --remove-orphans` again. - -At anypoint to purge the database and start with a new one run `rm -rf mysql` and then `mkdir mysql` and then the same steps following from that point as outlined above. Or run `purge-except-git.sh` from `./scripts` - -To review a log of individual containers use `docker-compose app` or `docker-compose maria` etc; container names are available in `docker-compose.yml` or via `docker-compose ps` when they are running. `docker images` will show you a list of the images installed on your system and `docker image rm [IMAGE ID]` removes them. - -#### Volumes and local filesystem changes - -The `docker-compose.yml` specifies volumes that map to the host (ie- your local machine). As per Docker's volume feature these override what is in the container's 'virtual' filesystem for those folders and instead will map to what is on your local filesystem. As such, changes/developments that occur in these locations will be reflected without needing to restart the containers. - -Additionally Nodemon is setup by default to watch coinos-server directory and will auto-restart the app as changes occur. - -Alternative to allowing nodemon to manage the app, you may enter bash on the docker to start/stop the node app manually ie: - - docker exec -it app bash - node index.js - # ^ starts app manually in a bash session inside the docker - # ( reflecting your local coinos-server directory) - - -To prevent nodemon from starting with the container change the `package.json` `"start"` script value to: `"tail -f /dev/null"` which will then keep the container alive so you may enter an interactive bash as above to start the app manually. - -#### Debugging - -To debug the node app while it is running via Docker, edit `docker-compose.yml` to add `9229` to the ports section for the `app` service: - - ports: - - '3119:3119' - - '9229' - -then get the IP of the app container: - - docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' app - > 192.168.115.72 #outputs the coinos app container IP - -then edit `package.json` start script to: - - "start" : "nodemon --inspect=0.0.0.0 index.js", - -(or use the interactive bash technique above with this same inspect flag) - -restart with `docker-compose restart app` - -then open your browser (Chrome in this example) to the URL`chrome://inspect` then click "Configure" and add the IP address + debugger port to the list of targets ex- `192.168.115.72:92229` - -an inspect link will then display under 'Remote Target'! - - Note the IP address may change between restarts so you may have to rerun the docker inspect command above again to make sure you have the correct IP on following sessions. - ----- - -### Install/Run (standalone) - -Note the Docker way outlined above is recommended as manual setup requirements/instructions shown below are out of date. - - -#### Requirements - -* bitcoind with zmq support -* elementsd with zmq support -* lnd or c-lightning -* a database that sequelize can talk to - -The bitcoind and elementsd nodes can be a pruned if you want to limit the amount of disk space used. - -#### Getting Started - - git clone git@github.com:coinos/coinos-server.git - cd coinos-server - cp -rf sampleconfig ./config # edit config files as necessary for your local setup - cp .env.sample .env - yarn - yarn start - # or, alternatively - yarn min # to run a stripped down development version that doesn't do payments or talk to any nodes - -#### Database Setup - -I've only tested with Maria. Here's a [schema](https://github.com/asoltys/coinos-server/blob/master/db/schema.sql) to get you started. - - cat db/schema.sql | mysql -u root -p - ---- -### Miscellaneous Commands - -#### Funding the regtest chain - -##### Bitcoin - -generate some blocks - - docker exec -it bitcoin bitcoin-cli generatetoaddress 1 $(docker exec -it bitcoin bitcoin-cli getnewaddress "" "legacy") - -get balance - - docker exec -it bitcoin bitcoin-cli getbalance - ---- -##### Liquid - -The Liquid network gives you a starting balance of Bitcoin specified in the `config/liquid/elements.conf` file as `initialfreecoins`. - -generate some blocks - - docker exec -it liquid elements-cli generatetoaddress 1 $(docker exec -it liquid elements-cli getnewaddress) - -get balance - - docker exec -it liquid elements-cli getbalance - ---- -##### Lightning - -get node id of clighting node +### Setup Lightning Channels docker exec -it cl lightning-cli getinfo - -connect to clightning node - docker exec -it lnd lncli --network=regtest --chain=bitcoin connect 029ba19ec5f65f82b1952fd535a86ff136ccc67ff7f91e19c3fcbc83a5224adaee@cl:9735 - -open a channel - docker exec -it lnd lncli --network=regtest --chain=bitcoin openchannel 029ba19ec5f65f82b1952fd535a86ff136ccc67ff7f91e19c3fcbc83a5224adaee 10000000 - -generate 10 btc blocks - docker exec -it bitcoin bitcoin-cli generatetoaddress 10 $(docker exec -it bitcoin bitcoin-cli getnewaddress "" "legacy") ---- -#### Test clightning payment - -payment request from clightning - - docker exec -it cl lightning-cli invoice 100000 "test payment" "test desc" - -get full payment request code from field bolt11 - - something like this - - lnbcrt1u1p3qhle9pp5mzn7aezr59tmlmp5mg9x2sa45j8fec5ygmwx6mg2x29qpnnw3j9qdq0w3jhxapqv3jhxccxqyjw5qcqp2sp54tuk3ns3gd66w50hflkzwks0d9z9eelsa8284283zhkug9kevzqq9qyyssqjsprhd38eywg6kp8w7gmwf48hnx0mpd28465v9f595xfrec0dg2jnqdumrmeh9srw32u5t9g6tdy6tdpu47emhkfnu72fnzevvwd0acqxmurkx - -Use this botl11 address and paste in the UI to check - ---- -#### Check if all three nodes are connected - - curl http://localhost:8085/api/info - -(look for nodes array at the end) - - -### license +### License This code is [licensed]. Coinos is free for personal use. Anyone can fork as long as it stays AGPLv3. -- cgit v1.2.3 From d2eb6a7e4a83650802897364e42cc35df23db25e Mon Sep 17 00:00:00 2001 From: Adam Soltys Date: Thu, 4 Aug 2022 23:21:46 -0700 Subject: update readme --- README.md | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index da59f04e..1c94f46b 100644 --- a/README.md +++ b/README.md @@ -2,18 +2,11 @@ Coinos is a bitcoin wallet app that supports payments over the bitcoin, liquid and lightning networks. Try it out at coinos.io. -This repository contains the code for the backend API server which is implemented as a NodeJS application. The code for the frontend UI is tracked separately here (but is automatically installed & started via the Docker way outlined below). +This repository contains the code for the backend API server which is implemented as a NodeJS application. The code for the frontend UI is tracked separately here. -## Install/Run (the Docker way) +## Install -### Requirements - -* docker and docker-compose -* NodeJS (recommended version: 16) -* ~7GB of hard drive space (which will go into /var/lib/docker; primarily for Liquid) - -### Getting Started +The follow commands will set up bitcoin, liquid and lightning nodes in regtest mode, along with a coinos app server, database, and front end UI. You'll need to have docker installed as a pre-requisite. ```bash git clone https://github.com/coinos/coinos-server -- cgit v1.2.3 From e78c557feb3c0ea0068758cd2d560fff66823736 Mon Sep 17 00:00:00 2001 From: Adam Soltys Date: Mon, 22 Aug 2022 16:03:58 -0700 Subject: select user currency with invoice --- routes/invoices.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/routes/invoices.js b/routes/invoices.js index b5650735..02a8308d 100644 --- a/routes/invoices.js +++ b/routes/invoices.js @@ -12,7 +12,7 @@ app.get( include: { model: db.User, as: "user", - attributes: ['username'] + attributes: ['username', 'currency'] } }); -- cgit v1.2.3 From 906a72dc7db448848587bf5bc36c0d8caf7ef7cc Mon Sep 17 00:00:00 2001 From: Adam Soltys Date: Tue, 23 Aug 2022 15:53:10 -0700 Subject: enable vouchers --- routes/send.js | 1 - routes/users.js | 8 ++++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/routes/send.js b/routes/send.js index 4c8afa34..653da87b 100644 --- a/routes/send.js +++ b/routes/send.js @@ -66,7 +66,6 @@ module.exports = ah(async (req, res, next) => { }; if (!username) { - throw new Error("Vouchers temporarily disabled"); l.info("creating redeemable payment"); params.redeemcode = uuidv4(); params.hash = `${req.get("origin")}/redeem/${params.redeemcode}`; diff --git a/routes/users.js b/routes/users.js index 4fe1362b..c9367c9a 100644 --- a/routes/users.js +++ b/routes/users.js @@ -634,12 +634,16 @@ app.post( }) ); +let redeeming = {}; app.post( "/redeem", optionalAuth, ah(async function(req, res) { + try { await db.transaction(async transaction => { const { redeemcode } = req.body; + if (redeeming[redeemcode]) fail("redemption in progress"); + redeeming[redeemcode] = true; if (!redeemcode) fail("no code provided"); let { user } = req; @@ -652,6 +656,7 @@ app.post( model: db.Account, as: "account" }, + lock: transaction.LOCK.UPDATE, transaction }); @@ -717,6 +722,9 @@ app.post( res.send({ payment }); }); + } catch(e) { + l.error("problem redeeming", e.message); + return res.status(500).send("There was a problem redeeming the voucher"); }) ); -- cgit v1.2.3 From 3f144a605f8f24c526581a2050d21a62b66c2f72 Mon Sep 17 00:00:00 2001 From: Adam Soltys Date: Fri, 8 Jul 2022 01:43:08 -0400 Subject: fix lnurl path --- routes/lnurl.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/routes/lnurl.js b/routes/lnurl.js index 30184d01..3dd436eb 100644 --- a/routes/lnurl.js +++ b/routes/lnurl.js @@ -12,7 +12,7 @@ withdrawals = persist("data/withdrawals.json"); lnurlServer = lnurl.createServer(config.lnurl); -let { computeConversionFee, conversionFeeReceiver } = require('lightning/conversionFee.js'); +let { computeConversionFee, conversionFeeReceiver } = require('./lightning/conversionFee.js'); var optionalAuth = function(req, res, next) { passport.authenticate("jwt", { session: false }, function(err, user, info) { -- cgit v1.2.3