"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); const models_1 = require("../models"); const LND = require("../utils/lightning"); const signer = require("../utils/signer"); const msg_1 = require("../utils/msg"); const path = require("path"); const tribes = require("../utils/tribes"); const confirmations_1 = require("../controllers/confirmations"); const receive_1 = require("./receive"); const constants = require(path.join(__dirname, '../../config/constants.json')); const MIN_SATS = 3; function sendMessage(params) { return __awaiter(this, void 0, void 0, function* () { const { type, chat, message, sender, amount, success, failure, skipPubKey } = params; let msg = newmsg(type, chat, sender, message); // console.log("=> MSG TO SEND",msg) // console.log(type,message) if (!(sender && sender.publicKey)) { console.log("NO SENDER?????"); return; } let contactIds = (typeof chat.contactIds === 'string' ? JSON.parse(chat.contactIds) : chat.contactIds) || []; if (contactIds.length === 1) { if (contactIds[0] === 1) { if (success) success(true); return; // if no contacts thats fine (like create public tribe) } } let networkType = undefined; const isTribe = chat.type === constants.chat_types.tribe; let isTribeOwner = false; const chatUUID = chat.uuid; if (isTribe) { const tribeOwnerPubKey = chat.ownerPubkey; isTribeOwner = sender.publicKey === tribeOwnerPubKey; if (type === constants.message_types.confirmation) { // if u are owner, go ahead! if (!isTribeOwner) return; // dont send confs for tribe if not owner } if (isTribeOwner) { networkType = 'mqtt'; // broadcast to all // decrypt message.content and message.mediaKey w groupKey msg = yield msg_1.decryptMessage(msg, chat); } else { // if tribe, send to owner only const tribeOwner = yield models_1.models.Contact.findOne({ where: { publicKey: tribeOwnerPubKey } }); contactIds = tribeOwner ? [tribeOwner.id] : []; } } let yes = null; let no = null; console.log('all contactIds', contactIds); yield asyncForEach(contactIds, (contactId) => __awaiter(this, void 0, void 0, function* () { if (contactId == 1) { // dont send to self return; } const contact = yield models_1.models.Contact.findOne({ where: { id: contactId } }); if (!contact) { return; // skip if u simply dont have the contact } const destkey = contact.publicKey; if (destkey === skipPubKey) { return; // skip (for tribe owner broadcasting, not back to the sender) } console.log('-> sending to ', contact.id, destkey); let mqttTopic = networkType === 'mqtt' ? `${destkey}/${chatUUID}` : ''; // sending a payment to one subscriber (like buying a pic) if (isTribeOwner && contactIds.length === 1 && amount && amount > MIN_SATS) { mqttTopic = ''; // FORCE KEYSEND!!! } const m = yield msg_1.personalizeMessage(msg, contact, isTribeOwner); const opts = { dest: destkey, data: m, amt: Math.max((amount || 0), MIN_SATS) }; try { const r = yield signAndSend(opts, mqttTopic); yes = r; } catch (e) { console.log("KEYSEND ERROR", e); no = e; } // await sleep(2) })); if (yes) { if (success) success(yes); } else { if (failure) failure(no); } }); } exports.sendMessage = sendMessage; function signAndSend(opts, mqttTopic, replayingHistory) { // console.log('sign and send!',opts) return new Promise(function (resolve, reject) { return __awaiter(this, void 0, void 0, function* () { if (!opts || typeof opts !== 'object') { return reject('object plz'); } if (!opts.dest) { return reject('no dest pubkey'); } let data = JSON.stringify(opts.data || {}); opts.amt = opts.amt || 0; const sig = yield signer.signAscii(data); data = data + sig; // console.log("ACTUALLY SEND", mqttTopic) try { if (mqttTopic) { yield tribes.publish(mqttTopic, data, function () { if (!replayingHistory) { if (mqttTopic) checkIfAutoConfirm(opts.data); } }); } else { yield LND.keysendMessage(Object.assign(Object.assign({}, opts), { data })); } resolve(true); } catch (e) { reject(e); } }); }); } exports.signAndSend = signAndSend; function checkIfAutoConfirm(data) { if (receive_1.typesToForward.includes(data.type)) { if (data.type === constants.message_types.delete) { return; // dont auto confirm delete msg } confirmations_1.tribeOwnerAutoConfirmation(data.message.id, data.chat.uuid); } } function newmsg(type, chat, sender, message) { const includeGroupKey = type === constants.message_types.group_create || type === constants.message_types.group_invite; const includeAlias = sender && sender.alias && chat.type === constants.chat_types.tribe; // const includePhotoUrl = sender && sender.photoUrl && !sender.privatePhoto return { type: type, chat: Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({ uuid: chat.uuid }, chat.name && { name: chat.name }), (chat.type || chat.type === 0) && { type: chat.type }), chat.members && { members: chat.members }), (includeGroupKey && chat.groupKey) && { groupKey: chat.groupKey }), (includeGroupKey && chat.host) && { host: chat.host }), message: message, sender: Object.assign({ pub_key: sender.publicKey }, includeAlias && { alias: sender.alias }) }; } exports.newmsg = newmsg; 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); } }); } // async function sleep(ms) { // return new Promise(resolve => setTimeout(resolve, ms)) // } // function urlBase64FromHex(ascii){ // return Buffer.from(ascii,'hex').toString('base64').replace(/\//g, '_').replace(/\+/g, '-') // } // function urlBase64FromBytes(buf){ // return Buffer.from(buf).toString('base64').replace(/\//g, '_').replace(/\+/g, '-') // } //# sourceMappingURL=send.js.map