aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2021-06-29 10:28:58 -0700
committerAdam Soltys <[email protected]>2021-07-07 12:42:19 -0700
commit0fb703b85d99c888d1df971e7c3562f7918e0ff8 (patch)
tree2f167df25b172c3b7166952444e39e7f582e93c4
parent9bf4080d67d6342624c8f1fb543acab00191f730 (diff)
downloadcoinos-server-0fb703b85d99c888d1df971e7c3562f7918e0ff8.tar.gz
coinos-server-0fb703b85d99c888d1df971e7c3562f7918e0ff8.zip
add webhooks to invoices
-rw-r--r--db/index.js50
l---------db/knexfile.js1
-rw-r--r--db/migrations/20210612181508_init_referrals.js19
-rw-r--r--db/migrations/20210612192804_init_waiting_list.js.js17
-rw-r--r--db/migrations/20210625232223_add_invoice_id_to_payments.js10
-rw-r--r--db/migrations/20210628221727_add_webhook_to_invoices.js11
-rw-r--r--db/migrations/user_adjustments.js53
-rw-r--r--db/models/invoices.js9
-rw-r--r--db/models/payments.js9
-rw-r--r--docker-compose.yml2
-rw-r--r--index.js7
-rw-r--r--package.json2
-rw-r--r--routes/bitcoin/receive.js33
-rw-r--r--routes/invoices.js2
-rw-r--r--routes/payments.js8
-rw-r--r--yarn.lock5
16 files changed, 113 insertions, 125 deletions
diff --git a/db/index.js b/db/index.js
index 4c327d35..c1d316cc 100644
--- a/db/index.js
+++ b/db/index.js
@@ -1,28 +1,30 @@
const Sequelize = require("sequelize");
-const debug = require('debug')('debug');
+const debug = require("debug")("debug");
-const dbOptions = require('./../config/knexfile.js')[process.env.NODE_ENV || "development"]
+const dbOptions = require("./../config/knexfile.js")[
+ process.env.NODE_ENV || "development"
+];
-db = new Sequelize(dbOptions.connection.database, dbOptions.connection.user, dbOptions.connection.password, {
- host: dbOptions.connection.host,
- dialect: "mariadb",
- logging: false,
- dialectOptions: { "multipleStatements": true, "timezone": "Etc/GMT+7" }
-});
+db = new Sequelize(
+ dbOptions.connection.database,
+ dbOptions.connection.user,
+ dbOptions.connection.password,
+ {
+ host: dbOptions.connection.host,
+ dialect: "mariadb",
+ logging: false,
+ dialectOptions: { multipleStatements: true, timezone: "Etc/GMT+7" }
+ }
+);
-db.authenticate()
-.then (response => {
- console.log('DB Connection established');
-})
-.catch (err => {
- console.debug('Error connecting to database: ' + err.message);
- console.log(dbOptions.connection.database + '.' + dbOptions.connection.user);
-})
+db.authenticate().catch(err => {
+ console.debug("Error connecting to database: " + err.message);
+ console.log(dbOptions.connection.database + "." + dbOptions.connection.user);
+});
-console.log("DB: " + JSON.stringify(dbOptions))
-debug('knex dbOptions: ' + JSON.stringify(dbOptions))
+debug("knex dbOptions: " + JSON.stringify(dbOptions));
-knex = require('knex')(dbOptions)
+knex = require("knex")(dbOptions);
require("./models/accounts.js");
require("./models/codes.js");
@@ -62,7 +64,7 @@ require("./normalized/waiting_list.js");
// require("./normalized/orders.js");
// require("./normalized/invoices.js");
-const { User, Account, Payment, Invoice, Key, Order, Referral} = db;
+const { User, Account, Payment, Invoice, Key, Order, Referral } = db;
// move relationships to specfic models
User.hasMany(Account, {
@@ -125,6 +127,11 @@ Payment.belongsTo(User, {
foreignKey: "user_id"
});
+Payment.belongsTo(Invoice, {
+ as: "invoice",
+ foreignKey: "invoice_id"
+});
+
Order.belongsTo(User, {
as: "user",
foreignKey: "user_id"
@@ -158,6 +165,5 @@ Referral.belongsTo(User, {
foreignKey: "user_id"
});
-debug('added model relationships')
+debug("added model relationships");
db.Order = Order;
-
diff --git a/db/knexfile.js b/db/knexfile.js
new file mode 120000
index 00000000..10bb1d03
--- /dev/null
+++ b/db/knexfile.js
@@ -0,0 +1 @@
+../config/knexfile.js \ No newline at end of file
diff --git a/db/migrations/20210612181508_init_referrals.js b/db/migrations/20210612181508_init_referrals.js
deleted file mode 100644
index 260a2c8f..00000000
--- a/db/migrations/20210612181508_init_referrals.js
+++ /dev/null
@@ -1,19 +0,0 @@
-
-exports.up = function(knex) {
- return knex.schema.createTable('referrals', function(t) {
- t.increments('id').unsigned().primary();
-
- t.string('token').notNull();
- t.string('expiry').nullable();
- t.enum('status', ['pending', 'active', 'expired', 'cancelled')).notNull().defaultTo('pending');
- t.int('sponsor_id').notNull();
- t.foreign('sponsor_id').references('users.user_id')
- t.int('user_id').nullable();
- t.foreign('user_id').references('users.user_id')
-
- t.timestamps();
-};
-
-exports.down = function(knex) {
- return knex.schema.dropTable('referrals');
-};
diff --git a/db/migrations/20210612192804_init_waiting_list.js.js b/db/migrations/20210612192804_init_waiting_list.js.js
deleted file mode 100644
index 5322cf6d..00000000
--- a/db/migrations/20210612192804_init_waiting_list.js.js
+++ /dev/null
@@ -1,17 +0,0 @@
-
-exports.up = function(knex) {
- return knex.schema.createTable('waiting_list', function(t) {
- t.increments('id').unsigned().primary();
-
- t.string('email').nullable();
- t.string('sms').nullable();
- t.enum('status', ['pending', 'contacted', 'registered', 'cancelled')).notNull().defaultTo('pending');
- t.int('user_id').notNull();
- t.foreign('user_id').references('users.user_id');
-
- t.timestamps();
-};
-
-exports.down = function(knex) {
- return knex.schema.dropTable('waiting_list');
-};
diff --git a/db/migrations/20210625232223_add_invoice_id_to_payments.js b/db/migrations/20210625232223_add_invoice_id_to_payments.js
new file mode 100644
index 00000000..46e2a82e
--- /dev/null
+++ b/db/migrations/20210625232223_add_invoice_id_to_payments.js
@@ -0,0 +1,10 @@
+exports.up = async knex =>
+ knex.schema.table("payments", function(table) {
+ table.integer("invoice_id");
+ table.foreign("invoice_id").references("invoices.id");
+ });
+
+exports.down = async knex =>
+ knex.schema.table("payments", function(table) {
+ table.dropColumn("invoice_id");
+ });
diff --git a/db/migrations/20210628221727_add_webhook_to_invoices.js b/db/migrations/20210628221727_add_webhook_to_invoices.js
new file mode 100644
index 00000000..073b8d01
--- /dev/null
+++ b/db/migrations/20210628221727_add_webhook_to_invoices.js
@@ -0,0 +1,11 @@
+exports.up = async function(knex) {
+ return knex.schema.table("invoices", function(table) {
+ table.text("webhook");
+ });
+};
+
+exports.down = async function(knex) {
+ return knex.schema.table("invoices", function(table) {
+ table.dropColumn("webhook");
+ });
+};
diff --git a/db/migrations/user_adjustments.js b/db/migrations/user_adjustments.js
deleted file mode 100644
index b4273848..00000000
--- a/db/migrations/user_adjustments.js
+++ /dev/null
@@ -1,53 +0,0 @@
-
-exports.up = function(knex) {
- return Promise.all([
-
- // move security fields to separate t (potentially different access permissions)
-
- knex.schema.createTable('user_security', function (t) {
- t.increments('id').unsigned().primary();
- t.int('user_id').notNull();
- t.foreign('user_id').references('users.user_id');
-
- t.boolean('twofa').notNull().defaultTo(false);
- t.string('pin').notNull();
- t.string('otp_secret').nullable();
- t.string('seed').nullable();
- },
-
- knex.raw("INSERT INTO user_security (user_id, twofa, pin, otp_secret, seed) SELECT users.id, twofa, pin, otpsecret, seed FROM users"),
-
- // move user-customizeable fields to separate t (potentially different access permissions)
-
- knex.schema.createTable('user_preferences', function (t) {
- t.increments('id').unsigned().primary();
- t.int('user_id').notNull();
- t.foreign('user_id').references('users.user_id');
-
- t.enum('default_unit', ['SAT', 'BTC', 'CAD']).notNull().defaultTo('SAT');
- t.enum('default_currency', ['CAD', 'USD']).notNull().defaultTo('CAD');
- t.enum('default_fiat', ['CAD', 'USD']).notNull().defaultTo('CAD');
- t.set('show_currencies', ['CAD', 'USD']).notNull().defaultTo('CAD');
- }
-
- knex.raw("INSERT INTO user_preferences (user_id, default_unit, default_currency, default_fiat, show_currencies) SELECT users.id, unit, currency, fiat, currencies FROM users"),
-
- // remove deprecated fields
-
- knex.schema.table('users', function (t) {
- t.string('uuid');
- t.enum('access', ['Anonymous', 'Member', 'Admin']).defaultTo('Anonymous');
-
- t.dropColumn('account_id');
- t.dropColumn('unit');
- t.dropColumn('fiat');
- t.dropColumn('currency');
- t.dropColumn('currencies');
- },
- ])
-
-};
-
-exports.down = function(knex) {
-
-};
diff --git a/db/models/invoices.js b/db/models/invoices.js
index e2c499f4..a51ee3f9 100644
--- a/db/models/invoices.js
+++ b/db/models/invoices.js
@@ -145,6 +145,15 @@ const attributes = {
comment: null,
field: "amount"
},
+ webhook: {
+ type: DataTypes.TEXT,
+ allowNull: true,
+ defaultValue: null,
+ primaryKey: false,
+ autoIncrement: false,
+ comment: null,
+ field: "webhook"
+ },
tip: {
type: DataTypes.DOUBLE,
allowNull: true,
diff --git a/db/models/payments.js b/db/models/payments.js
index 94050a0b..c315a5a0 100644
--- a/db/models/payments.js
+++ b/db/models/payments.js
@@ -19,6 +19,15 @@ const attributes = {
comment: null,
field: "account_id"
},
+ invoice_id: {
+ type: DataTypes.INTEGER(11),
+ allowNull: true,
+ defaultValue: null,
+ primaryKey: false,
+ autoIncrement: false,
+ comment: null,
+ field: "invoice_id"
+ },
user_id: {
type: DataTypes.INTEGER(11),
allowNull: true,
diff --git a/docker-compose.yml b/docker-compose.yml
index 3fe0f546..8e3f4ef8 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -79,7 +79,7 @@ services:
- ${LIQUID_ELECTRS_RPC_PORT}:60401
- ${LIQUID_ELECTRS_PORT}:3002
volumes:
- - ./liquidregtest/liquid-config/:/config
+ - ./liquid/:/config
restart: unless-stopped
esplora-liquid:
image: vulpemventures/esplora:latest
diff --git a/index.js b/index.js
index 92423249..0bea8dcf 100644
--- a/index.js
+++ b/index.js
@@ -58,7 +58,6 @@ require("./db");
require("./lib/utils");
require("./lib/sockets");
require("./lib/passport");
-
require("./lib/register");
require("./lib/send");
@@ -69,24 +68,20 @@ require("./routes/users");
// Exclude plugins for minimalist version
if (process.env.SCOPE !== 'MIN') {
-
if (config.bitcoin) networks.push("bitcoin");
if (config.liquid) networks.push("liquid");
if (config.lna) networks.push("lightning");
require("./lib/rates");
require("./lib/notifications");
+
if (config.imap) require("./lib/mail");
-
if (config.lnurl) require("./routes/lnurl");
if (config.mailgun) require("./routes/funding");
- require("./routes/funding");
require("./routes/invoices");
require("./routes/payments");
-
require("./routes/swaps");
-
}
// Scope based Route Handling
diff --git a/package.json b/package.json
index 8babd585..1474238a 100644
--- a/package.json
+++ b/package.json
@@ -41,6 +41,7 @@
"multer": "^1.4.2",
"mysql": "^2.18.1",
"mysql2": "^2.2.5",
+ "node-fetch": "^2.6.1",
"nodemon": "^2.0.7",
"otplib": "^12.0.1",
"passport": "0.4.0",
@@ -54,6 +55,7 @@
"sqlite3": "^5.0.2",
"uuid": "^3.3.2",
"web-push": "^3.4.4",
+ "wretch": "^1.7.4",
"ws": "^7.1.2",
"zeromq": "^5.1.0"
},
diff --git a/routes/bitcoin/receive.js b/routes/bitcoin/receive.js
index 6bf38a9e..ba522aeb 100644
--- a/routes/bitcoin/receive.js
+++ b/routes/bitcoin/receive.js
@@ -2,6 +2,9 @@ const reverse = require("buffer-reverse");
const zmq = require("zeromq");
const { Op } = require("sequelize");
const { fromBase58 } = require("bip32");
+const wretch = require("wretch");
+const fetch = require("node-fetch");
+wretch().polyfills({ fetch });
const bitcoin = require("bitcoinjs-lib");
@@ -84,7 +87,6 @@ zmqRawTx.on("message", async (topic, message, sequence) => {
for (let i = 0; i < tx.ins.length; i++) {
let { hash, index } = tx.ins[i];
hash = reverse(hash).toString("hex");
- console.log(hash);
let hex = await bc.getRawTransaction(hash);
let inputTx = bitcoin.Transaction.fromHex(hex);
totalInputs += inputTx.outs[index].value;
@@ -104,7 +106,8 @@ zmqRawTx.on("message", async (topic, message, sequence) => {
tip,
confirmed,
address,
- network: "bitcoin"
+ network: "bitcoin",
+ invoice_id: invoice.id
});
payment = payment.get({ plain: true });
payment.account = account.get({ plain: true });
@@ -154,13 +157,24 @@ setInterval(async () => {
{
model: db.User,
as: "user"
+ },
+ {
+ model: db.Invoice,
+ as: "invoice"
}
],
lock: transaction.LOCK.UPDATE,
transaction
});
-
+ if (p.invoice && p.invoice.webhook) {
+ l.info("calling webhook", p.invoice.webhook);
+ console.log(await wretch()
+ .url(p.invoice.webhook)
+ .post({ oh: "yeah" })
+ .json());
+ }
+
if (p && p.address) address = p.address;
if (p && p.user) user = p.user;
@@ -194,7 +208,12 @@ setInterval(async () => {
let c = convert[address];
if (address && c) {
- l.info("bitcoin detected to conversion address", address, c.address, user.username);
+ l.info(
+ "bitcoin detected to conversion address",
+ address,
+ c.address,
+ user.username
+ );
user.account = account;
await sendLiquid({
@@ -206,6 +225,10 @@ setInterval(async () => {
}
}
} catch (e) {
- l.error("problem processing queued bitcoin transaction", e.message, e.stack);
+ l.error(
+ "problem processing queued bitcoin transaction",
+ e.message,
+ e.stack
+ );
}
}, 1000);
diff --git a/routes/invoices.js b/routes/invoices.js
index f7682bfe..c188811e 100644
--- a/routes/invoices.js
+++ b/routes/invoices.js
@@ -55,7 +55,7 @@ app.post(
invoice.amount,
invoice.tip,
invoice.currency,
- `${invoice.text.substr(0, 8)}..${invoice.text.substr(-6)}`,
+ invoice.text && `${invoice.text.substr(0, 8)}..${invoice.text.substr(-6)}`,
);
if (!invoice.tip) invoice.tip = 0;
diff --git a/routes/payments.js b/routes/payments.js
index a52ad395..41dfce26 100644
--- a/routes/payments.js
+++ b/routes/payments.js
@@ -17,6 +17,7 @@ ah(async () => {
l.warn("couldn't read exceptions file", e.message);
}
+ try {
(
await db.Invoice.findAll({
include: {
@@ -28,6 +29,9 @@ ah(async () => {
if (address && user) addresses[address] = user.username;
if (unconfidential && user) addresses[unconfidential] = user.username;
});
+ } catch(e) {
+ console.log(e);
+ }
try {
const accounts = await db.Account.findAll({
@@ -51,6 +55,7 @@ ah(async () => {
})
).map((p) => p.hash);
+
setInterval(async () => {
const unconfirmed = (
await db.Payment.findAll({
@@ -129,6 +134,7 @@ ah(async () => {
}
}, 50);
}
+ /*
if (config.liquid) {
lq = new BitcoinCore(config.liquid);
@@ -151,7 +157,6 @@ ah(async () => {
}, 50);
}
-
app.get(
"/payments",
auth,
@@ -194,4 +199,5 @@ ah(async () => {
}
})
);
+*/
})();
diff --git a/yarn.lock b/yarn.lock
index 96096131..75c13c79 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -4566,6 +4566,11 @@ wrappy@1:
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=
+wretch@^1.7.4:
+ version "1.7.4"
+ resolved "https://registry.yarnpkg.com/wretch/-/wretch-1.7.4.tgz#d71fc16ed01a8fd549df6cd06f205c6d13e2cf73"
+ integrity sha512-gBET7PgqgJ89GPBHujw0+arM/8YtWPqG6od8dRMTumvr3xvSlONpp2ANYqbpSL+cSoe6g97quZTgwM0jNn6riA==
+
write-file-atomic@^3.0.0:
version "3.0.3"
resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-3.0.3.tgz#56bd5c5a5c70481cd19c571bd39ab965a5de56e8"