Browse Source

auto open channel from Accounting record

master^2
Evan Feenstra 4 years ago
parent
commit
7a0d55cf3e
  1. 1
      dist/src/controllers/index.js
  2. 2
      dist/src/controllers/index.js.map
  3. 56
      dist/src/controllers/queries.js
  4. 2
      dist/src/controllers/queries.js.map
  5. 4
      dist/src/models/ts/accounting.js
  6. 2
      dist/src/models/ts/accounting.js.map
  7. 16
      dist/src/utils/lightning.js
  8. 2
      dist/src/utils/lightning.js.map
  9. 1
      dist/src/utils/setup.js
  10. 2
      dist/src/utils/setup.js.map
  11. 2
      src/controllers/index.ts
  12. 56
      src/controllers/queries.ts
  13. 3
      src/models/ts/accounting.ts
  14. 19
      src/utils/lightning.ts
  15. 3
      src/utils/setup.ts

1
dist/src/controllers/index.js

@ -38,6 +38,7 @@ function set(app) {
}
media.cycleMediaToken();
timers.reloadTimers();
queries.startWatchingUTXOs();
app.get('/chats', chats.getChats);
app.post('/group', chats.createGroupChat);
app.put('/chats/:id', chats.updateChat);

2
dist/src/controllers/index.js.map

File diff suppressed because one or more lines are too long

56
dist/src/controllers/queries.js

@ -18,6 +18,7 @@ const lightning = require("../utils/lightning");
const wallet_1 = require("../utils/wallet");
const jsonUtils = require("../utils/json");
const sequelize_1 = require("sequelize");
const node_fetch_1 = require("node-fetch");
let queries = {};
const hub_pubkey = '023d70f2f76d283c6c4e58109ee3a2816eb9d8feb40b23d62469060a2b2867b77f';
function getPendingAccountings() {
@ -61,17 +62,57 @@ function listUTXOs(req, res) {
});
}
exports.listUTXOs = listUTXOs;
// function genChannel(acc: Accounting) {
// }
function getSuggestedSatPerByte() {
return __awaiter(this, void 0, void 0, function* () {
const MAX_AMT = 250;
try {
const r = yield node_fetch_1.default('https://mempool.space/api/v1/fees/recommended');
const j = yield r.json();
return Math.min(MAX_AMT, j.hourFee);
}
catch (e) {
return MAX_AMT;
}
});
}
// https://mempool.space/api/v1/fees/recommended
function genChannelAndConfirmAccounting(acc) {
return __awaiter(this, void 0, void 0, function* () {
const sat_per_byte = yield getSuggestedSatPerByte();
console.log("[WATCH]=> sat_per_byte", sat_per_byte);
try {
const r = yield lightning.openChannel({
node_pubkey: acc.pubkey,
local_funding_amount: acc.amount,
push_sat: 0,
sat_per_byte
});
console.log("[WATCH]=> CHANNEL OPENED!", r);
yield models_1.models.Accounting.update({
status: constants_1.default.statuses.confirmed,
fudingTxid: r.funding_txid_str
}, {
where: { id: acc.id }
});
console.log("[WATCH]=> ACCOUNTINGS UPDATED!");
}
catch (e) {
console.log('[ACCOUNTING] error creating channel', e);
}
});
}
function pollUTXOs() {
return __awaiter(this, void 0, void 0, function* () {
console.log("[WATCH]=> pollUTXOs");
const accs = yield getPendingAccountings();
if (!accs)
return;
accs.forEach(acc => {
console.log("[WATCH]=> accs", accs.length);
asyncForEach(accs, (acc) => __awaiter(this, void 0, void 0, function* () {
if (acc.confirmations < 1)
return;
});
yield genChannelAndConfirmAccounting(acc);
}));
});
}
function startWatchingUTXOs() {
@ -197,4 +238,11 @@ exports.receiveQueryResponse = (payload) => __awaiter(void 0, void 0, void 0, fu
console.log("=> ERROR receiveQueryResponse,", e);
}
});
function asyncForEach(array, callback) {
return __awaiter(this, void 0, void 0, function* () {
for (let index = 0; index < array.length; index++) {
yield callback(array[index], index, array);
}
});
}
//# sourceMappingURL=queries.js.map

2
dist/src/controllers/queries.js.map

File diff suppressed because one or more lines are too long

4
dist/src/models/ts/accounting.js

@ -53,6 +53,10 @@ __decorate([
sequelize_typescript_1.Column(sequelize_typescript_1.DataType.BIGINT),
__metadata("design:type", Number)
], Accounting.prototype, "chanId", void 0);
__decorate([
sequelize_typescript_1.Column,
__metadata("design:type", String)
], Accounting.prototype, "fundingTxid", void 0);
Accounting = __decorate([
sequelize_typescript_1.Table({ tableName: 'sphinx_accountings', underscored: true })
], Accounting);

2
dist/src/models/ts/accounting.js.map

@ -1 +1 @@
{"version":3,"file":"accounting.js","sourceRoot":"","sources":["../../../../src/models/ts/accounting.ts"],"names":[],"mappings":";;;;;;;;;;;AAAA,+DAAsE;AAGtE,IAAqB,UAAU,GAA/B,MAAqB,UAAW,SAAQ,4BAAiB;CAkCxD,CAAA;AA1BC;IANC,6BAAM,CAAC;QACN,IAAI,EAAE,+BAAQ,CAAC,MAAM;QACrB,UAAU,EAAE,IAAI;QAChB,MAAM,EAAE,IAAI;QACZ,aAAa,EAAE,IAAI;KACpB,CAAC;;sCACQ;AAGV;IADC,6BAAM;8BACD,IAAI;wCAAA;AAGV;IADC,6BAAM;;0CACO;AAGd;IADC,6BAAM;;kDACe;AAGtB;IADC,6BAAM,CAAC,+BAAQ,CAAC,OAAO,CAAC;;0CACX;AAGd;IADC,6BAAM;;6CACU;AAGjB;IADC,6BAAM,CAAC,+BAAQ,CAAC,MAAM,CAAC;;0CACV;AAGd;IADC,6BAAM;;yCACM;AAGb;IADC,6BAAM,CAAC,+BAAQ,CAAC,MAAM,CAAC;;0CACV;AAhCK,UAAU;IAD9B,4BAAK,CAAC,EAAE,SAAS,EAAE,oBAAoB,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC;GACzC,UAAU,CAkC9B;kBAlCoB,UAAU"}
{"version":3,"file":"accounting.js","sourceRoot":"","sources":["../../../../src/models/ts/accounting.ts"],"names":[],"mappings":";;;;;;;;;;;AAAA,+DAAsE;AAGtE,IAAqB,UAAU,GAA/B,MAAqB,UAAW,SAAQ,4BAAiB;CAqCxD,CAAA;AA7BC;IANC,6BAAM,CAAC;QACN,IAAI,EAAE,+BAAQ,CAAC,MAAM;QACrB,UAAU,EAAE,IAAI;QAChB,MAAM,EAAE,IAAI;QACZ,aAAa,EAAE,IAAI;KACpB,CAAC;;sCACQ;AAGV;IADC,6BAAM;8BACD,IAAI;wCAAA;AAGV;IADC,6BAAM;;0CACO;AAGd;IADC,6BAAM;;kDACe;AAGtB;IADC,6BAAM,CAAC,+BAAQ,CAAC,OAAO,CAAC;;0CACX;AAGd;IADC,6BAAM;;6CACU;AAGjB;IADC,6BAAM,CAAC,+BAAQ,CAAC,MAAM,CAAC;;0CACV;AAGd;IADC,6BAAM;;yCACM;AAGb;IADC,6BAAM,CAAC,+BAAQ,CAAC,MAAM,CAAC;;0CACV;AAGd;IADC,6BAAM;;+CACY;AAnCA,UAAU;IAD9B,4BAAK,CAAC,EAAE,SAAS,EAAE,oBAAoB,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC;GACzC,UAAU,CAqC9B;kBArCoB,UAAU"}

16
dist/src/utils/lightning.js

@ -503,6 +503,22 @@ function listChannels() {
});
}
exports.listChannels = listChannels;
function openChannel(args) {
return __awaiter(this, void 0, void 0, function* () {
return new Promise((resolve, reject) => {
const lightning = loadLightning();
lightning.openChannelSync(args, function (err, response) {
if (err == null) {
resolve(response);
}
else {
reject(err);
}
});
});
});
}
exports.openChannel = openChannel;
function channelBalance() {
return __awaiter(this, void 0, void 0, function* () {
return new Promise((resolve, reject) => {

2
dist/src/utils/lightning.js.map

File diff suppressed because one or more lines are too long

1
dist/src/utils/setup.js

@ -44,6 +44,7 @@ function setVersion() {
}
function migrate() {
return __awaiter(this, void 0, void 0, function* () {
addTableColumn('sphinx_accountings', 'funding_txid');
addTableColumn('sphinx_chat_members', 'last_alias');
addTableColumn('sphinx_chats', 'my_photo_url');
addTableColumn('sphinx_chats', 'my_alias');

2
dist/src/utils/setup.js.map

File diff suppressed because one or more lines are too long

2
src/controllers/index.ts

@ -32,6 +32,8 @@ export async function set(app) {
timers.reloadTimers()
queries.startWatchingUTXOs()
app.get('/chats', chats.getChats)
app.post('/group', chats.createGroupChat)
app.put('/chats/:id', chats.updateChat)

56
src/controllers/queries.ts

@ -7,6 +7,7 @@ import * as lightning from '../utils/lightning'
import { listUnspent, UTXO } from '../utils/wallet'
import * as jsonUtils from '../utils/json'
import { Op } from 'sequelize'
import fetch from 'node-fetch'
type QueryType = 'onchain_address'
export interface Query {
@ -30,7 +31,7 @@ interface Accounting {
date: string
}
async function getPendingAccountings():Promise<Accounting[]> {
async function getPendingAccountings(): Promise<Accounting[]> {
const utxos: UTXO[] = await listUnspent() // at least 1 confg
const accountings = await models.Accounting.findAll({
where: {
@ -68,16 +69,49 @@ export async function listUTXOs(req, res) {
}
}
// function genChannel(acc: Accounting) {
async function getSuggestedSatPerByte(): Promise<number> {
const MAX_AMT = 250
try {
const r = await fetch('https://mempool.space/api/v1/fees/recommended')
const j = await r.json()
return Math.min(MAX_AMT, j.hourFee)
} catch (e) {
return MAX_AMT
}
}
// }
// https://mempool.space/api/v1/fees/recommended
async function genChannelAndConfirmAccounting(acc: Accounting) {
const sat_per_byte = await getSuggestedSatPerByte()
console.log("[WATCH]=> sat_per_byte", sat_per_byte)
try {
const r = await lightning.openChannel({
node_pubkey: acc.pubkey,
local_funding_amount: acc.amount,
push_sat: 0,
sat_per_byte
})
console.log("[WATCH]=> CHANNEL OPENED!", r)
await models.Accounting.update({
status: constants.statuses.confirmed,
fudingTxid: r.funding_txid_str
},{
where: {id: acc.id}
})
console.log("[WATCH]=> ACCOUNTINGS UPDATED!")
} catch (e) {
console.log('[ACCOUNTING] error creating channel',e)
}
}
async function pollUTXOs(){
async function pollUTXOs() {
console.log("[WATCH]=> pollUTXOs")
const accs: Accounting[] = await getPendingAccountings()
if(!accs) return
accs.forEach(acc=>{
if(acc.confirmations<1) return
if (!accs) return
console.log("[WATCH]=> accs", accs.length)
asyncForEach(accs, async acc=>{
if (acc.confirmations < 1) return
await genChannelAndConfirmAccounting(acc)
})
}
@ -202,4 +236,10 @@ export const receiveQueryResponse = async (payload) => {
} catch (e) {
console.log("=> ERROR receiveQueryResponse,", e)
}
}
async function asyncForEach(array, callback) {
for (let index = 0; index < array.length; index++) {
await callback(array[index], index, array);
}
}

3
src/models/ts/accounting.ts

@ -35,4 +35,7 @@ export default class Accounting extends Model<Accounting> {
@Column(DataType.BIGINT)
chanId: number
@Column
fundingTxid: string
}

19
src/utils/lightning.ts

@ -449,6 +449,25 @@ async function listChannels(): Promise<{ [k: string]: any }> {
})
}
export interface OpenChannelArgs {
node_pubkey: any // bytes
local_funding_amount: number
push_sat: number // 0
sat_per_byte: number // 75?
}
export async function openChannel(args: OpenChannelArgs): Promise<{ [k: string]: any }> {
return new Promise((resolve, reject) => {
const lightning = loadLightning()
lightning.openChannelSync(args, function (err, response) {
if (err == null) {
resolve(response)
} else {
reject(err)
}
});
})
}
async function channelBalance(): Promise<{ [k: string]: any }> {
return new Promise((resolve, reject) => {
const lightning = loadLightning()

3
src/utils/setup.ts

@ -32,6 +32,9 @@ async function setVersion() {
async function migrate() {
addTableColumn('sphinx_accountings', 'funding_txid')
addTableColumn('sphinx_chat_members', 'last_alias')
addTableColumn('sphinx_chats', 'my_photo_url')

Loading…
Cancel
Save