You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

234 lines
5.9 KiB

import { loadLightning } from './lightning'
import { sequelize, models } from '../models'
import { exec } from 'child_process'
import * as QRCode from 'qrcode'
import { checkTag, checkCommitHash } from '../utils/gitinfo'
import * as fs from 'fs';
import { isClean } from './nodeinfo'
import { getQR } from './connect'
const USER_VERSION = 7
const setupDatabase = async () => {
console.log('=> [db] starting setup...')
await setVersion()
try {
await sequelize.sync()
console.log("=> [db] done syncing")
} catch (e) {
// console.log("db sync failed", e)
}
await migrate()
console.log('=> [db] setup done')
}
async function setVersion() {
try {
await sequelize.query(`PRAGMA user_version = ${USER_VERSION}`)
} catch (e) {
console.log('=> setVersion failed', e)
}
}
async function migrate() {
addTableColumn('sphinx_accountings', 'funding_txid')
addTableColumn('sphinx_chat_members', 'last_alias')
addTableColumn('sphinx_chats', 'my_photo_url')
addTableColumn('sphinx_chats', 'my_alias')
addTableColumn('sphinx_messages', 'sender_pic')
addTableColumn('sphinx_messages', 'network_type', 'INTEGER')
addTableColumn('sphinx_chats', 'meta')
addTableColumn('sphinx_contacts', 'tip_amount', 'BIGINT')
addTableColumn('sphinx_contacts', 'last_active', 'DATETIME')
try {
await sequelize.query(`
CREATE TABLE sphinx_chat_bots (
id BIGINT NOT NULL PRIMARY KEY,
chat_id BIGINT,
bot_uuid TEXT,
bot_type INT,
bot_prefix TEXT,
bot_maker_pubkey TEXT,
msg_types TEXT,
meta TEXT,
price_per_use INT,
created_at DATETIME,
updated_at DATETIME
)`)
} catch (e) { }
try {
await sequelize.query(`CREATE UNIQUE INDEX chat_bot_index ON sphinx_chat_bots(chat_id, bot_uuid);`)
} catch (e) { }
addTableColumn('sphinx_bots', 'webhook')
addTableColumn('sphinx_bots', 'uuid')
addTableColumn('sphinx_bots', 'price_per_use', 'INT')
try {
await sequelize.query(`
CREATE TABLE sphinx_bot_members (
id BIGINT NOT NULL PRIMARY KEY,
member_pubkey TEXT,
tribe_uuid TEXT,
msg_count BIGINT,
created_at DATETIME,
updated_at DATETIME
)`)
} catch (e) { }
addTableColumn('sphinx_bot_members', 'bot_id')
//////////
try {
await sequelize.query(`
CREATE TABLE sphinx_bots (
id TEXT NOT NULL PRIMARY KEY,
name TEXT,
secret TEXT,
created_at DATETIME,
updated_at DATETIME
)`)
} catch (e) { }
addTableColumn('sphinx_chats', 'app_url')
addTableColumn('sphinx_chats', 'feed_url')
try {
await sequelize.query(`CREATE UNIQUE INDEX chat_member_index ON sphinx_chat_members(chat_id, contact_id);`)
} catch (e) { }
addTableColumn('sphinx_chats', 'private', 'BOOLEAN')
addTableColumn('sphinx_chats', 'unlisted', 'BOOLEAN')
addTableColumn('sphinx_chat_members', 'status', 'BIGINT')
addTableColumn('sphinx_chats', 'seen', 'BOOLEAN')
try {
await sequelize.query(`CREATE INDEX idx_messages_sender ON sphinx_messages (sender);`)
} catch (e) { }
addTableColumn('sphinx_contacts', 'notification_sound')
addTableColumn('sphinx_contacts', 'from_group', 'BOOLEAN')
addTableColumn('sphinx_contacts', 'private_photo', 'BOOLEAN')
addTableColumn('sphinx_chats', 'escrow_amount', 'BIGINT')
addTableColumn('sphinx_chats', 'escrow_millis', 'BIGINT')
// try{
// await sequelize.query(`
// CREATE TABLE sphinx_timers (
// id BIGINT,
// chat_id BIGINT,
// receiver BIGINT,
// millis BIGINT,
// msg_id BIGINT,
// amount DECIMAL
// )`)
// } catch(e){}
}
async function addTableColumn(table: string, column: string, type = 'TEXT') {
try {
await sequelize.query(`alter table ${table} add ${column} ${type}`)
} catch (e) {
//console.log('=> migrate failed',e)
}
}
const setupOwnerContact = async () => {
const owner = await models.Contact.findOne({ where: { isOwner: true } })
if (!owner) {
const lightning = await loadLightning()
lightning.getInfo({}, async (err, info) => {
if (err) {
console.log('[db] error creating node owner due to lnd failure', err)
} else {
try {
const one = await models.Contact.findOne({ where: { id: 1 } })
if (!one) {
const contact = await models.Contact.create({
id: 1,
publicKey: info.identity_pubkey,
isOwner: true,
authToken: null
})
console.log('[db] created node owner contact, id:', contact.id)
}
} catch (error) {
console.log('[db] error creating owner contact', error)
}
}
})
}
}
const runMigrations = async () => {
await new Promise((resolve, reject) => {
const migrate: any = exec('node_modules/.bin/sequelize db:migrate',
{ env: process.env },
(err, stdout, stderr) => {
if (err) {
reject(err);
} else {
resolve(true);
}
}
);
// Forward stdout+stderr to this process
migrate.stdout.pipe(process.stdout);
migrate.stderr.pipe(process.stderr);
});
}
export { setupDatabase, setupOwnerContact, runMigrations, setupDone }
async function setupDone() {
await printGitInfo()
printQR()
}
async function printGitInfo() {
const commitHash = await checkCommitHash()
const tag = await checkTag()
console.log(`=> Relay version: ${tag}, commit: ${commitHash}`)
}
async function printQR() {
const b64 = await getQR()
if (!b64) {
console.log('=> no public IP provided')
return ''
}
console.log('>>', b64)
connectionStringFile(b64)
const clean = await isClean()
if (!clean) return // skip it if already setup!
console.log('Scan this QR in Sphinx app:')
QRCode.toString(b64, { type: 'terminal' }, function (err, url) {
console.log(url)
})
}
function connectionStringFile(str: string) {
fs.writeFile('connection_string.txt', str, function (err) {
if (err) console.log('ERROR SAVING connection_string.txt.', err);
});
}