commit
6eca25d216
21 changed files with 157 additions and 814 deletions
|
|
@ -51,6 +51,7 @@
|
|||
"request-promise": "^4.2.2",
|
||||
"response-time": "^2.3.2",
|
||||
"shelljs": "^0.8.2",
|
||||
"shock-common": "^0.0.1",
|
||||
"socket.io": "2.1.1",
|
||||
"text-encoding": "^0.7.0",
|
||||
"tingodb": "^0.6.1",
|
||||
|
|
|
|||
|
|
@ -23,9 +23,6 @@ const mySEA = {}
|
|||
const $$__SHOCKWALLET__MSG__ = '$$__SHOCKWALLET__MSG__'
|
||||
const $$__SHOCKWALLET__ENCRYPTED__ = '$$_SHOCKWALLET__ENCRYPTED__'
|
||||
|
||||
// TO DO: Move this constant to common repo
|
||||
const IS_GUN_AUTH = 'IS_GUN_AUTH'
|
||||
|
||||
mySEA.encrypt = (msg, secret) => {
|
||||
if (typeof msg !== 'string') {
|
||||
throw new TypeError(
|
||||
|
|
@ -172,10 +169,11 @@ mySEA.secret = async (recipientOrSenderEpub, recipientOrSenderSEA) => {
|
|||
|
||||
const auth = require('../../auth/auth')
|
||||
|
||||
const Action = require('../action-constants.js')
|
||||
const { Constants } = require('shock-common')
|
||||
const { Action, Event } = Constants
|
||||
|
||||
const API = require('../contact-api/index')
|
||||
const Config = require('../config')
|
||||
const Event = require('../event-constants')
|
||||
// const { nonEncryptedRoutes } = require('../../../utils/protectedRoutes')
|
||||
|
||||
/**
|
||||
|
|
@ -441,7 +439,7 @@ class Mediator {
|
|||
this.socket.on(Event.ON_BIO, this.onBio)
|
||||
this.socket.on(Event.ON_SEED_BACKUP, this.onSeedBackup)
|
||||
|
||||
this.socket.on(IS_GUN_AUTH, this.isGunAuth)
|
||||
this.socket.on(Constants.Misc.IS_GUN_AUTH, this.isGunAuth)
|
||||
|
||||
this.socket.on(Action.SET_LAST_SEEN_APP, this.setLastSeenApp)
|
||||
|
||||
|
|
@ -557,7 +555,7 @@ class Mediator {
|
|||
try {
|
||||
const isGunAuth = isAuthenticated()
|
||||
|
||||
this.socket.emit(IS_GUN_AUTH, {
|
||||
this.socket.emit(Constants.Misc.IS_GUN_AUTH, {
|
||||
ok: true,
|
||||
msg: {
|
||||
isGunAuth
|
||||
|
|
@ -565,7 +563,7 @@ class Mediator {
|
|||
origBody: {}
|
||||
})
|
||||
} catch (err) {
|
||||
this.socket.emit(IS_GUN_AUTH, {
|
||||
this.socket.emit(Constants.Misc.IS_GUN_AUTH, {
|
||||
ok: false,
|
||||
msg: err.message,
|
||||
origBody: {}
|
||||
|
|
|
|||
|
|
@ -1,16 +0,0 @@
|
|||
const Actions = {
|
||||
ACCEPT_REQUEST: "ACCEPT_REQUEST",
|
||||
BLACKLIST: "BLACKLIST",
|
||||
GENERATE_NEW_HANDSHAKE_NODE: "GENERATE_NEW_HANDSHAKE_NODE",
|
||||
SEND_HANDSHAKE_REQUEST: "SEND_HANDSHAKE_REQUEST",
|
||||
SEND_HANDSHAKE_REQUEST_WITH_INITIAL_MSG: "SEND_HANDSHAKE_REQUEST_WITH_INITIAL_MSG",
|
||||
SEND_MESSAGE: "SEND_MESSAGE",
|
||||
SEND_PAYMENT: "SEND_PAYMENT",
|
||||
SET_AVATAR: "SET_AVATAR",
|
||||
SET_DISPLAY_NAME: "SET_DISPLAY_NAME",
|
||||
SET_BIO: "SET_BIO",
|
||||
DISCONNECT: "DISCONNECT",
|
||||
SET_LAST_SEEN_APP: "SET_LAST_SEEN_APP"
|
||||
};
|
||||
|
||||
module.exports = Actions;
|
||||
|
|
@ -3,37 +3,29 @@
|
|||
*/
|
||||
const uuidv1 = require('uuid/v1')
|
||||
const logger = require('winston')
|
||||
const { Constants, Schema } = require('shock-common')
|
||||
|
||||
const { ErrorCode } = Constants
|
||||
|
||||
const LightningServices = require('../../../utils/lightningServices')
|
||||
|
||||
const ErrorCode = require('./errorCode')
|
||||
const Getters = require('./getters')
|
||||
const Key = require('./key')
|
||||
const Utils = require('./utils')
|
||||
// const { promisifyGunNode: p } = Utils
|
||||
const {
|
||||
isHandshakeRequest,
|
||||
isOrderResponse,
|
||||
encodeSpontaneousPayment
|
||||
} = require('./schema')
|
||||
|
||||
/**
|
||||
* @typedef {import('./SimpleGUN').GUNNode} GUNNode
|
||||
* @typedef {import('./SimpleGUN').ISEA} ISEA
|
||||
* @typedef {import('./SimpleGUN').UserGUNNode} UserGUNNode
|
||||
* @typedef {import('./schema').HandshakeRequest} HandshakeRequest
|
||||
* @typedef {import('./schema').StoredRequest} StoredReq
|
||||
* @typedef {import('./schema').Message} Message
|
||||
* @typedef {import('./schema').Outgoing} Outgoing
|
||||
* @typedef {import('./schema').PartialOutgoing} PartialOutgoing
|
||||
* @typedef {import('./schema').Order} Order
|
||||
* @typedef {import('shock-common').Schema.HandshakeRequest} HandshakeRequest
|
||||
* @typedef {import('shock-common').Schema.StoredRequest} StoredReq
|
||||
* @typedef {import('shock-common').Schema.Message} Message
|
||||
* @typedef {import('shock-common').Schema.Outgoing} Outgoing
|
||||
* @typedef {import('shock-common').Schema.PartialOutgoing} PartialOutgoing
|
||||
* @typedef {import('shock-common').Schema.Order} Order
|
||||
* @typedef {import('./SimpleGUN').Ack} Ack
|
||||
*/
|
||||
|
||||
/**
|
||||
* An special message signaling the acceptance.
|
||||
*/
|
||||
const INITIAL_MSG = '$$__SHOCKWALLET__INITIAL__MESSAGE'
|
||||
|
||||
/**
|
||||
* Create a an outgoing feed. The feed will have an initial special acceptance
|
||||
* message. Returns a promise that resolves to the id of the newly-created
|
||||
|
|
@ -92,7 +84,7 @@ const __createOutgoingFeed = async (withPublicKey, user, SEA) => {
|
|||
|
||||
/** @type {Message} */
|
||||
const initialMsg = {
|
||||
body: await SEA.encrypt(INITIAL_MSG, ourSecret),
|
||||
body: await SEA.encrypt(Constants.Misc.INITIAL_MSG, ourSecret),
|
||||
timestamp: Date.now()
|
||||
}
|
||||
|
||||
|
|
@ -203,7 +195,7 @@ const acceptRequest = async (
|
|||
.get(requestID)
|
||||
.then()
|
||||
|
||||
if (!isHandshakeRequest(hr)) {
|
||||
if (!Schema.isHandshakeRequest(hr)) {
|
||||
throw new Error(ErrorCode.TRIED_TO_ACCEPT_AN_INVALID_REQUEST)
|
||||
}
|
||||
|
||||
|
|
@ -981,7 +973,7 @@ const sendPayment = async (to, amount, memo) => {
|
|||
)
|
||||
|
||||
/**
|
||||
* @type {import('./schema').OrderResponse}
|
||||
* @type {import('shock-common').Schema.OrderResponse}
|
||||
*/
|
||||
const encryptedOrderRes = await Promise.race([
|
||||
Promise.race([onMethod, freshGunMethod]).then(v => {
|
||||
|
|
@ -996,14 +988,14 @@ const sendPayment = async (to, amount, memo) => {
|
|||
})
|
||||
])
|
||||
|
||||
if (!isOrderResponse(encryptedOrderRes)) {
|
||||
if (!Schema.isOrderResponse(encryptedOrderRes)) {
|
||||
throw new Error(
|
||||
'received response not an OrderResponse, instead got: ' +
|
||||
JSON.stringify(encryptedOrderRes)
|
||||
)
|
||||
}
|
||||
|
||||
/** @type {import('./schema').OrderResponse} */
|
||||
/** @type {import('shock-common').Schema.OrderResponse} */
|
||||
const orderResponse = {
|
||||
response: await SEA.decrypt(encryptedOrderRes.response, ourSecret),
|
||||
type: encryptedOrderRes.type
|
||||
|
|
@ -1075,7 +1067,7 @@ const sendPayment = async (to, amount, memo) => {
|
|||
if (Utils.successfulHandshakeAlreadyExists(to)) {
|
||||
await sendMessage(
|
||||
to,
|
||||
encodeSpontaneousPayment(amount, memo || 'no memo', preimage),
|
||||
Schema.encodeSpontaneousPayment(amount, memo || 'no memo', preimage),
|
||||
require('../Mediator').getUser(),
|
||||
require('../Mediator').mySEA
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,45 +0,0 @@
|
|||
/**
|
||||
* @prettier
|
||||
*/
|
||||
exports.ALREADY_AUTH = 'ALREADY_AUTH'
|
||||
|
||||
exports.NOT_AUTH = 'NOT_AUTH'
|
||||
|
||||
exports.COULDNT_ACCEPT_REQUEST = 'COULDNT_ACCEPT_REQUEST'
|
||||
|
||||
exports.COULDNT_SENT_REQUEST = 'COULDNT_SENT_REQUEST'
|
||||
|
||||
exports.COULDNT_PUT_REQUEST_RESPONSE = 'COULDNT_PUT_REQUEST_RESPONSE'
|
||||
|
||||
/**
|
||||
* Error thrown when trying to accept a request, and on retrieval of that
|
||||
* request invalid data (not resembling a request) is received.
|
||||
*/
|
||||
exports.TRIED_TO_ACCEPT_AN_INVALID_REQUEST =
|
||||
'TRIED_TO_ACCEPT_AN_INVALID_REQUEST'
|
||||
|
||||
exports.UNSUCCESSFUL_LOGOUT = 'UNSUCCESSFUL_LOGOUT'
|
||||
|
||||
exports.UNSUCCESSFUL_REQUEST_ACCEPT = 'UNSUCCESSFUL_REQUEST_ACCEPT'
|
||||
|
||||
/**
|
||||
* Error thrown when trying to send a handshake request to an user for which
|
||||
* there's already an successful handshake.
|
||||
*/
|
||||
exports.ALREADY_HANDSHAKED = 'ALREADY_HANDSHAKED'
|
||||
|
||||
/**
|
||||
* Error thrown when trying to send a handshake request to an user for which
|
||||
* there's already a handshake request on his current handshake node.
|
||||
*/
|
||||
exports.ALREADY_REQUESTED_HANDSHAKE = 'ALREADY_REQUESTED_HANDSHAKE'
|
||||
|
||||
/**
|
||||
* Error thrown when trying to send a handshake request to an user on an stale
|
||||
* handshake address.
|
||||
*/
|
||||
exports.STALE_HANDSHAKE_ADDRESS = 'STALE_HANDSHAKE_ADDRESS'
|
||||
|
||||
exports.TIMEOUT_ERR = 'TIMEOUT_ERR'
|
||||
|
||||
exports.ORDER_NOT_ANSWERED_IN_TIME = 'ORDER_NOT_ANSWERED_IN_TIME'
|
||||
|
|
@ -3,24 +3,27 @@
|
|||
*/
|
||||
const debounce = require('lodash/debounce')
|
||||
const logger = require('winston')
|
||||
const {
|
||||
Constants: { ErrorCode },
|
||||
Schema,
|
||||
Utils: CommonUtils
|
||||
} = require('shock-common')
|
||||
|
||||
const ErrorCode = require('../errorCode')
|
||||
const Key = require('../key')
|
||||
const Schema = require('../schema')
|
||||
const Utils = require('../utils')
|
||||
/**
|
||||
* @typedef {import('../SimpleGUN').UserGUNNode} UserGUNNode
|
||||
* @typedef {import('../SimpleGUN').GUNNode} GUNNode
|
||||
* @typedef {import('../SimpleGUN').ISEA} ISEA
|
||||
* @typedef {import('../SimpleGUN').ListenerData} ListenerData
|
||||
* @typedef {import('../schema').HandshakeRequest} HandshakeRequest
|
||||
* @typedef {import('../schema').Message} Message
|
||||
* @typedef {import('../schema').Outgoing} Outgoing
|
||||
* @typedef {import('../schema').PartialOutgoing} PartialOutgoing
|
||||
* @typedef {import('../schema').Chat} Chat
|
||||
* @typedef {import('../schema').ChatMessage} ChatMessage
|
||||
* @typedef {import('../schema').SimpleSentRequest} SimpleSentRequest
|
||||
* @typedef {import('../schema').SimpleReceivedRequest} SimpleReceivedRequest
|
||||
* @typedef {import('shock-common').Schema.HandshakeRequest} HandshakeRequest
|
||||
* @typedef {import('shock-common').Schema.Message} Message
|
||||
* @typedef {import('shock-common').Schema.Outgoing} Outgoing
|
||||
* @typedef {import('shock-common').Schema.PartialOutgoing} PartialOutgoing
|
||||
* @typedef {import('shock-common').Schema.Chat} Chat
|
||||
* @typedef {import('shock-common').Schema.ChatMessage} ChatMessage
|
||||
* @typedef {import('shock-common').Schema.SimpleSentRequest} SimpleSentRequest
|
||||
* @typedef {import('shock-common').Schema.SimpleReceivedRequest} SimpleReceivedRequest
|
||||
*/
|
||||
|
||||
const DEBOUNCE_WAIT_TIME = 500
|
||||
|
|
@ -360,7 +363,9 @@ const onOutgoing = cb => {
|
|||
const SEA = require('../../Mediator').mySEA
|
||||
const mySecret = await Utils.mySecret()
|
||||
|
||||
await Utils.asyncForEach(Object.entries(data), async ([id, out]) => {
|
||||
await CommonUtils.asyncForEach(
|
||||
Object.entries(data),
|
||||
async ([id, out]) => {
|
||||
if (typeof out !== 'object') {
|
||||
return
|
||||
}
|
||||
|
|
@ -391,7 +396,7 @@ const onOutgoing = cb => {
|
|||
)
|
||||
|
||||
if (typeof messages === 'object' && messages !== null) {
|
||||
await Utils.asyncForEach(
|
||||
await CommonUtils.asyncForEach(
|
||||
Object.entries(messages),
|
||||
async ([mid, msg]) => {
|
||||
if (typeof msg === 'object' && msg !== null) {
|
||||
|
|
@ -412,7 +417,8 @@ const onOutgoing = cb => {
|
|||
}
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
)
|
||||
|
||||
currentOutgoings = newOuts
|
||||
notifyOutgoingsListeners()
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
/** @format */
|
||||
const debounce = require('lodash/debounce')
|
||||
const logger = require('winston')
|
||||
const { Schema } = require('shock-common')
|
||||
|
||||
const Key = require('../key')
|
||||
const Schema = require('../schema')
|
||||
const Streams = require('../streams')
|
||||
|
||||
/**
|
||||
* @typedef {Readonly<Schema.SimpleReceivedRequest>} SimpleReceivedRequest
|
||||
* @typedef {Readonly<import('shock-common').Schema.SimpleReceivedRequest>} SimpleReceivedRequest
|
||||
* @typedef {(reqs: ReadonlyArray<SimpleReceivedRequest>) => void} Listener
|
||||
*/
|
||||
|
||||
|
|
@ -22,7 +22,7 @@ let currReceivedReqsMap = {}
|
|||
|
||||
/**
|
||||
* Unprocessed requests in current handshake node.
|
||||
* @type {Record<string, Schema.HandshakeRequest>}
|
||||
* @type {Record<string, import('shock-common').Schema.HandshakeRequest>}
|
||||
*/
|
||||
let currAddressData = {}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,14 +8,14 @@ const Streams = require('../streams')
|
|||
* @typedef {import('../SimpleGUN').GUNNode} GUNNode
|
||||
* @typedef {import('../SimpleGUN').ISEA} ISEA
|
||||
* @typedef {import('../SimpleGUN').ListenerData} ListenerData
|
||||
* @typedef {import('../schema').HandshakeRequest} HandshakeRequest
|
||||
* @typedef {import('../schema').Message} Message
|
||||
* @typedef {import('../schema').Outgoing} Outgoing
|
||||
* @typedef {import('../schema').PartialOutgoing} PartialOutgoing
|
||||
* @typedef {import('../schema').Chat} Chat
|
||||
* @typedef {import('../schema').ChatMessage} ChatMessage
|
||||
* @typedef {import('../schema').SimpleSentRequest} SimpleSentRequest
|
||||
* @typedef {import('../schema').SimpleReceivedRequest} SimpleReceivedRequest
|
||||
* @typedef {import('shock-common').Schema.HandshakeRequest} HandshakeRequest
|
||||
* @typedef {import('shock-common').Schema.Message} Message
|
||||
* @typedef {import('shock-common').Schema.Outgoing} Outgoing
|
||||
* @typedef {import('shock-common').Schema.PartialOutgoing} PartialOutgoing
|
||||
* @typedef {import('shock-common').Schema.Chat} Chat
|
||||
* @typedef {import('shock-common').Schema.ChatMessage} ChatMessage
|
||||
* @typedef {import('shock-common').Schema.SimpleSentRequest} SimpleSentRequest
|
||||
* @typedef {import('shock-common').Schema.SimpleReceivedRequest} SimpleReceivedRequest
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -5,6 +5,5 @@ const Actions = require('./actions')
|
|||
const Events = require('./events')
|
||||
const Jobs = require('./jobs')
|
||||
const Key = require('./key')
|
||||
const Schema = require('./schema')
|
||||
|
||||
module.exports = { Actions, Events, Jobs, Key, Schema }
|
||||
module.exports = { Actions, Events, Jobs, Key }
|
||||
|
|
|
|||
|
|
@ -4,9 +4,13 @@
|
|||
|
||||
const logger = require('winston')
|
||||
|
||||
const ErrorCode = require('../errorCode')
|
||||
const {
|
||||
Constants: {
|
||||
ErrorCode,
|
||||
Misc: { LAST_SEEN_NODE_INTERVAL }
|
||||
}
|
||||
} = require('shock-common')
|
||||
const Key = require('../key')
|
||||
const { LAST_SEEN_NODE_INTERVAL } = require('../utils')
|
||||
|
||||
/**
|
||||
* @typedef {import('../SimpleGUN').GUNNode} GUNNode
|
||||
|
|
|
|||
|
|
@ -2,10 +2,12 @@
|
|||
* @format
|
||||
*/
|
||||
const logger = require('winston')
|
||||
const {
|
||||
Constants: { ErrorCode },
|
||||
Schema
|
||||
} = require('shock-common')
|
||||
|
||||
const ErrorCode = require('../errorCode')
|
||||
const Key = require('../key')
|
||||
const Schema = require('../schema')
|
||||
const Utils = require('../utils')
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -6,11 +6,14 @@ const logger = require('winston')
|
|||
const isFinite = require('lodash/isFinite')
|
||||
const isNumber = require('lodash/isNumber')
|
||||
const isNaN = require('lodash/isNaN')
|
||||
const {
|
||||
Constants: { ErrorCode },
|
||||
Schema
|
||||
} = require('shock-common')
|
||||
|
||||
const LightningServices = require('../../../../utils/lightningServices')
|
||||
const ErrorCode = require('../errorCode')
|
||||
|
||||
const Key = require('../key')
|
||||
const Schema = require('../schema')
|
||||
const Utils = require('../utils')
|
||||
|
||||
const getUser = () => require('../../Mediator').getUser()
|
||||
|
|
@ -127,7 +130,7 @@ const listenerForAddr = (addr, SEA) => async (order, orderID) => {
|
|||
`onOrders() -> Will now place the encrypted invoice in order to response usergraph: ${addr}`
|
||||
)
|
||||
|
||||
/** @type {Schema.OrderResponse} */
|
||||
/** @type {import('shock-common').Schema.OrderResponse} */
|
||||
const orderResponse = {
|
||||
response: encInvoice,
|
||||
type: 'invoice'
|
||||
|
|
@ -157,7 +160,7 @@ const listenerForAddr = (addr, SEA) => async (order, orderID) => {
|
|||
)
|
||||
logger.error(err)
|
||||
|
||||
/** @type {Schema.OrderResponse} */
|
||||
/** @type {import('shock-common').Schema.OrderResponse} */
|
||||
const orderResponse = {
|
||||
response: err.message,
|
||||
type: 'err'
|
||||
|
|
|
|||
|
|
@ -1,15 +0,0 @@
|
|||
/**
|
||||
* @format
|
||||
* Contains types that are used throughout the application. Written in
|
||||
* typescript for easier implementation.
|
||||
*
|
||||
* Nominal types are archieved through the enum method as outlined here:
|
||||
* https://basarat.gitbook.io/typescript/main-1/nominaltyping
|
||||
*/
|
||||
enum _EncSpontPayment {
|
||||
_ = ''
|
||||
}
|
||||
/**
|
||||
* Spontaneous payment as found inside a chat message body.
|
||||
*/
|
||||
export type EncSpontPayment = _EncSpontPayment & string
|
||||
|
|
@ -1,531 +0,0 @@
|
|||
/**
|
||||
* @format
|
||||
*/
|
||||
const logger = require('winston')
|
||||
const isFinite = require('lodash/isFinite')
|
||||
const isNumber = require('lodash/isNumber')
|
||||
const isNaN = require('lodash/isNaN')
|
||||
|
||||
/**
|
||||
* @typedef {object} HandshakeRequest
|
||||
* @prop {string} from Public key of the requestor.
|
||||
* @prop {string} response Encrypted string where, if the recipient accepts the
|
||||
* request, his outgoing feed id will be put. Before that the sender's outgoing
|
||||
* feed ID will be placed here, encrypted so only the recipient can access it.
|
||||
* @prop {number} timestamp Unix time.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {object} Message
|
||||
* @prop {string} body
|
||||
* @prop {number} timestamp
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {object} ChatMessage
|
||||
* @prop {string} body
|
||||
* @prop {string} id
|
||||
* @prop {boolean} outgoing True if the message is an outgoing message,
|
||||
* otherwise it is an incoming message.
|
||||
* @prop {number} timestamp
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {any} item
|
||||
* @returns {item is ChatMessage}
|
||||
*/
|
||||
exports.isChatMessage = item => {
|
||||
if (typeof item !== 'object') {
|
||||
return false
|
||||
}
|
||||
|
||||
if (item === null) {
|
||||
return false
|
||||
}
|
||||
|
||||
const obj = /** @type {ChatMessage} */ (item)
|
||||
|
||||
if (typeof obj.body !== 'string') {
|
||||
return false
|
||||
}
|
||||
|
||||
if (typeof obj.id !== 'string') {
|
||||
return false
|
||||
}
|
||||
|
||||
if (typeof obj.outgoing !== 'boolean') {
|
||||
return false
|
||||
}
|
||||
|
||||
if (typeof obj.timestamp !== 'number') {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
/**
|
||||
* A simpler representation of a conversation between two users than the
|
||||
* outgoing/incoming feed paradigm. It combines both the outgoing and incoming
|
||||
* messages into one data structure plus metada about the chat.
|
||||
* @typedef {object} Chat
|
||||
* @prop {string} id Chats now have IDs because of disconnect.
|
||||
* RecipientPublicKey will no longer be unique.
|
||||
* @prop {string|null} recipientAvatar Base64 encoded image.
|
||||
* @prop {string} recipientPublicKey A way to uniquely identify each chat.
|
||||
* @prop {ChatMessage[]} messages Sorted from most recent to least recent.
|
||||
* @prop {string|null} recipientDisplayName
|
||||
* @prop {boolean} didDisconnect True if the recipient performed a disconnect.
|
||||
* @prop {number|undefined|null} lastSeenApp
|
||||
*/
|
||||
|
||||
/**
|
||||
* @param {any} item
|
||||
* @returns {item is Chat}
|
||||
*/
|
||||
exports.isChat = item => {
|
||||
if (typeof item !== 'object') {
|
||||
return false
|
||||
}
|
||||
|
||||
if (item === null) {
|
||||
return false
|
||||
}
|
||||
|
||||
const obj = /** @type {Chat} */ (item)
|
||||
|
||||
if (typeof obj.recipientAvatar !== 'string' && obj.recipientAvatar !== null) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (!Array.isArray(obj.messages)) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (typeof obj.recipientPublicKey !== 'string') {
|
||||
return false
|
||||
}
|
||||
|
||||
if (obj.recipientPublicKey.length === 0) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (typeof obj.didDisconnect !== 'boolean') {
|
||||
return false
|
||||
}
|
||||
|
||||
if (typeof obj.id !== 'string') {
|
||||
return false
|
||||
}
|
||||
|
||||
return obj.messages.every(msg => exports.isChatMessage(msg))
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {object} Outgoing
|
||||
* @prop {Record<string, Message>} messages
|
||||
* @prop {string} with Public key for whom the outgoing messages are intended.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {object} PartialOutgoing
|
||||
* @prop {string} with (Encrypted) Public key for whom the outgoing messages are
|
||||
* intended.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {object} StoredRequest
|
||||
* @prop {string} sentReqID
|
||||
* @prop {string} recipientPub
|
||||
* @prop {string} handshakeAddress
|
||||
* @prop {number} timestamp
|
||||
*/
|
||||
|
||||
/**
|
||||
* @param {any} item
|
||||
* @returns {item is StoredRequest}
|
||||
*/
|
||||
exports.isStoredRequest = item => {
|
||||
if (typeof item !== 'object') return false
|
||||
if (item === null) return false
|
||||
const obj = /** @type {StoredRequest} */ (item)
|
||||
if (typeof obj.recipientPub !== 'string') return false
|
||||
if (typeof obj.handshakeAddress !== 'string') return false
|
||||
if (typeof obj.handshakeAddress !== 'string') return false
|
||||
if (typeof obj.timestamp !== 'number') return false
|
||||
return true
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {object} SimpleSentRequest
|
||||
* @prop {string} id
|
||||
* @prop {string|null} recipientAvatar
|
||||
* @prop {boolean} recipientChangedRequestAddress True if the recipient changed
|
||||
* the request node address and therefore can't no longer accept the request.
|
||||
* @prop {string|null} recipientDisplayName
|
||||
* @prop {string} recipientPublicKey Fallback for when user has no display name.
|
||||
* @prop {number} timestamp
|
||||
*/
|
||||
|
||||
/**
|
||||
* @param {any} item
|
||||
* @returns {item is SimpleSentRequest}
|
||||
*/
|
||||
exports.isSimpleSentRequest = item => {
|
||||
if (typeof item !== 'object') {
|
||||
return false
|
||||
}
|
||||
|
||||
if (item === null) {
|
||||
return false
|
||||
}
|
||||
|
||||
const obj = /** @type {SimpleSentRequest} */ (item)
|
||||
|
||||
if (typeof obj.id !== 'string') {
|
||||
return false
|
||||
}
|
||||
|
||||
if (typeof obj.recipientAvatar !== 'string' && obj.recipientAvatar !== null) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (typeof obj.recipientChangedRequestAddress !== 'boolean') {
|
||||
return false
|
||||
}
|
||||
|
||||
if (
|
||||
typeof obj.recipientDisplayName !== 'string' &&
|
||||
obj.recipientDisplayName !== null
|
||||
) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (typeof obj.recipientPublicKey !== 'string') {
|
||||
return false
|
||||
}
|
||||
|
||||
if (typeof obj.timestamp !== 'number') {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {object} SimpleReceivedRequest
|
||||
* @prop {string} id
|
||||
* @prop {string|null} requestorAvatar
|
||||
* @prop {string|null} requestorDisplayName
|
||||
* @prop {string} requestorPK
|
||||
* @prop {number} timestamp
|
||||
*/
|
||||
|
||||
/**
|
||||
* @param {any} item
|
||||
* @returns {item is SimpleReceivedRequest}
|
||||
*/
|
||||
exports.isSimpleReceivedRequest = item => {
|
||||
if (typeof item !== 'object') {
|
||||
return false
|
||||
}
|
||||
|
||||
if (item === null) {
|
||||
return false
|
||||
}
|
||||
|
||||
const obj = /** @type {SimpleReceivedRequest} */ (item)
|
||||
|
||||
if (typeof obj.id !== 'string') {
|
||||
return false
|
||||
}
|
||||
|
||||
if (typeof obj.requestorAvatar !== 'string' && obj.requestorAvatar !== null) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (
|
||||
typeof obj.requestorDisplayName !== 'string' &&
|
||||
obj.requestorDisplayName !== null
|
||||
) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (typeof obj.requestorPK !== 'string') {
|
||||
return false
|
||||
}
|
||||
|
||||
if (typeof obj.timestamp !== 'number') {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {any} item
|
||||
* @returns {item is HandshakeRequest}
|
||||
*/
|
||||
exports.isHandshakeRequest = item => {
|
||||
if (typeof item !== 'object') {
|
||||
return false
|
||||
}
|
||||
|
||||
if (item === null) {
|
||||
return false
|
||||
}
|
||||
|
||||
const obj = /** @type {HandshakeRequest} */ (item)
|
||||
|
||||
if (typeof obj.from !== 'string') {
|
||||
return false
|
||||
}
|
||||
|
||||
if (typeof obj.response !== 'string') {
|
||||
return false
|
||||
}
|
||||
|
||||
if (typeof obj.timestamp !== 'number') {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {any} item
|
||||
* @returns {item is Message}
|
||||
*/
|
||||
exports.isMessage = item => {
|
||||
if (typeof item !== 'object') {
|
||||
return false
|
||||
}
|
||||
|
||||
if (item === null) {
|
||||
return false
|
||||
}
|
||||
|
||||
const obj = /** @type {Message} */ (item)
|
||||
|
||||
return typeof obj.body === 'string' && typeof obj.timestamp === 'number'
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {any} item
|
||||
* @returns {item is PartialOutgoing}
|
||||
*/
|
||||
exports.isPartialOutgoing = item => {
|
||||
if (typeof item !== 'object') {
|
||||
return false
|
||||
}
|
||||
|
||||
if (item === null) {
|
||||
return false
|
||||
}
|
||||
|
||||
const obj = /** @type {PartialOutgoing} */ (item)
|
||||
|
||||
return typeof obj.with === 'string'
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {any} item
|
||||
* @returns {item is Outgoing}
|
||||
*/
|
||||
exports.isOutgoing = item => {
|
||||
if (typeof item !== 'object') {
|
||||
return false
|
||||
}
|
||||
|
||||
if (item === null) {
|
||||
return false
|
||||
}
|
||||
|
||||
const obj = /** @type {Outgoing} */ (item)
|
||||
|
||||
const messagesAreMessages = Object.values(obj.messages).every(msg =>
|
||||
exports.isMessage(msg)
|
||||
)
|
||||
|
||||
return typeof obj.with === 'string' && messagesAreMessages
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {object} Order
|
||||
* @prop {string} from Public key of sender.
|
||||
* @prop {string} amount Encrypted
|
||||
* @prop {string} memo Encrypted
|
||||
* @prop {number} timestamp
|
||||
*/
|
||||
|
||||
/**
|
||||
* @param {any} item
|
||||
* @returns {item is Order}
|
||||
*/
|
||||
exports.isOrder = item => {
|
||||
if (typeof item !== 'object') {
|
||||
return false
|
||||
}
|
||||
|
||||
if (item === null) {
|
||||
return false
|
||||
}
|
||||
|
||||
const obj = /** @type {Order} */ (item)
|
||||
|
||||
if (typeof obj.amount !== 'string') {
|
||||
return false
|
||||
}
|
||||
|
||||
if (typeof obj.from !== 'string') {
|
||||
return false
|
||||
}
|
||||
|
||||
if (typeof obj.memo !== 'string') {
|
||||
return false
|
||||
}
|
||||
|
||||
return typeof obj.timestamp === 'number'
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {object} OrderResponse
|
||||
* @prop {'err'|'invoice'} type
|
||||
* @prop {string} response
|
||||
*/
|
||||
|
||||
/**
|
||||
* @param {*} o
|
||||
* @returns {o is OrderResponse}
|
||||
*/
|
||||
exports.isOrderResponse = o => {
|
||||
if (typeof o !== 'object') {
|
||||
return false
|
||||
}
|
||||
|
||||
if (o === null) {
|
||||
return false
|
||||
}
|
||||
|
||||
const obj = /** @type {OrderResponse} */ (o)
|
||||
|
||||
if (typeof obj.response !== 'string') {
|
||||
return false
|
||||
}
|
||||
|
||||
return obj.type === 'err' || obj.type === 'invoice'
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {import('./schema-types').EncSpontPayment} EncSpontPayment
|
||||
*/
|
||||
|
||||
const ENC_SPONT_PAYMENT_PREFIX = '$$__SHOCKWALLET__SPONT__PAYMENT'
|
||||
|
||||
/**
|
||||
* @param {string} s
|
||||
* @returns {s is EncSpontPayment}
|
||||
*/
|
||||
const isEncodedSpontPayment = s => s.indexOf(ENC_SPONT_PAYMENT_PREFIX) === 0
|
||||
|
||||
exports.isEncodedSpontPayment = isEncodedSpontPayment
|
||||
|
||||
/**
|
||||
* @typedef {object} SpontaneousPayment
|
||||
* @prop {number} amt
|
||||
* @prop {string} memo
|
||||
* @prop {string} preimage
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {EncSpontPayment} sp
|
||||
* @throws {Error} If decoding fails.
|
||||
* @returns {SpontaneousPayment}
|
||||
*/
|
||||
exports.decodeSpontPayment = sp => {
|
||||
try {
|
||||
const [preimage, amtStr, memo] = sp
|
||||
.slice((ENC_SPONT_PAYMENT_PREFIX + '__').length)
|
||||
.split('__')
|
||||
|
||||
if (typeof preimage !== 'string') {
|
||||
throw new TypeError('Could not parse preimage')
|
||||
}
|
||||
|
||||
if (typeof amtStr !== 'string') {
|
||||
throw new TypeError('Could not parse amt')
|
||||
}
|
||||
|
||||
if (typeof memo !== 'string') {
|
||||
throw new TypeError('Could not parse memo')
|
||||
}
|
||||
|
||||
const amt = Number(amtStr)
|
||||
|
||||
if (!isNumber(amt)) {
|
||||
throw new TypeError(`Could parse amount as a number, not a number?`)
|
||||
}
|
||||
|
||||
if (isNaN(amt)) {
|
||||
throw new TypeError(`Could not amount as a number, got NaN.`)
|
||||
}
|
||||
|
||||
if (!isFinite(amt)) {
|
||||
throw new TypeError(
|
||||
`Amount was correctly parsed, but got a non finite number.`
|
||||
)
|
||||
}
|
||||
|
||||
return {
|
||||
amt,
|
||||
memo,
|
||||
preimage
|
||||
}
|
||||
} catch (err) {
|
||||
logger.debug(`Encoded spontaneous payment: ${sp}`)
|
||||
logger.error(err)
|
||||
throw err
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {number} amt
|
||||
* @param {string} memo
|
||||
* @param {string} preimage
|
||||
* @returns {EncSpontPayment}
|
||||
*/
|
||||
exports.encodeSpontaneousPayment = (amt, memo, preimage) => {
|
||||
if (typeof amt !== 'number') {
|
||||
throw new TypeError('amt must be a number')
|
||||
}
|
||||
|
||||
if (typeof memo !== 'string') {
|
||||
throw new TypeError('memo must be an string')
|
||||
}
|
||||
|
||||
if (typeof preimage !== 'string') {
|
||||
throw new TypeError('preimage must be an string')
|
||||
}
|
||||
|
||||
if (amt <= 0) {
|
||||
throw new RangeError('Amt must be greater than zero')
|
||||
}
|
||||
|
||||
if (memo.length < 1) {
|
||||
throw new TypeError('Memo must be populated')
|
||||
}
|
||||
|
||||
if (preimage.length < 1) {
|
||||
throw new TypeError('preimage must be populated')
|
||||
}
|
||||
|
||||
const enc = `${ENC_SPONT_PAYMENT_PREFIX}__${amt}__${memo}__${preimage}`
|
||||
|
||||
if (isEncodedSpontPayment(enc)) {
|
||||
return enc
|
||||
}
|
||||
|
||||
throw new Error('isEncodedSpontPayment(enc) false')
|
||||
}
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
/** @format */
|
||||
const { Schema, Utils: CommonUtils } = require('shock-common')
|
||||
|
||||
const Key = require('../key')
|
||||
const Schema = require('../schema')
|
||||
const Utils = require('../utils')
|
||||
/**
|
||||
* @typedef {Record<string, string|null|undefined>} Avatars
|
||||
|
|
@ -97,7 +98,7 @@ const onDisplayName = (cb, pub) => {
|
|||
}
|
||||
|
||||
/**
|
||||
* @typedef {import('../schema').StoredRequest} StoredRequest
|
||||
* @typedef {import('shock-common').Schema.StoredRequest} StoredRequest
|
||||
* @typedef {(reqs: StoredRequest[]) => void} StoredRequestsListener
|
||||
*/
|
||||
|
||||
|
|
@ -121,7 +122,7 @@ const processStoredReqs = async () => {
|
|||
encryptedStoredReqs = []
|
||||
const mySecret = await Utils.mySecret()
|
||||
const SEA = require('../../Mediator').mySEA
|
||||
const finalReqs = await Utils.asyncMap(ereqs, async er => {
|
||||
const finalReqs = await CommonUtils.asyncMap(ereqs, async er => {
|
||||
/** @type {StoredRequest} */
|
||||
const r = {
|
||||
handshakeAddress: await SEA.decrypt(er.handshakeAddress, mySecret),
|
||||
|
|
|
|||
|
|
@ -2,12 +2,12 @@
|
|||
const uuidv1 = require('uuid/v1')
|
||||
const logger = require('winston')
|
||||
const debounce = require('lodash/debounce')
|
||||
const { Schema, Utils: CommonUtils } = require('shock-common')
|
||||
|
||||
const Schema = require('../schema')
|
||||
const Key = require('../key')
|
||||
const Utils = require('../utils')
|
||||
/**
|
||||
* @typedef {import('../schema').ChatMessage} Message
|
||||
* @typedef {import('shock-common').Schema.ChatMessage} Message
|
||||
* @typedef {import('../SimpleGUN').OpenListenerData} OpenListenerData
|
||||
*/
|
||||
|
||||
|
|
@ -98,7 +98,7 @@ const onOpenForPubFeedPair = ([pub, feed]) =>
|
|||
return
|
||||
}
|
||||
|
||||
const incoming = /** @type {Schema.Outgoing} */ (data)
|
||||
const incoming = /** @type {import('shock-common').Schema.Outgoing} */ (data)
|
||||
|
||||
// incomplete data, let's not assume anything
|
||||
if (
|
||||
|
|
@ -108,12 +108,12 @@ const onOpenForPubFeedPair = ([pub, feed]) =>
|
|||
return
|
||||
}
|
||||
|
||||
/** @type {Schema.ChatMessage[]} */
|
||||
/** @type {import('shock-common').Schema.ChatMessage[]} */
|
||||
const newMsgs = Object.entries(incoming.messages)
|
||||
// filter out messages with incomplete data
|
||||
.filter(([_, msg]) => Schema.isMessage(msg))
|
||||
.map(([id, msg]) => {
|
||||
/** @type {Schema.ChatMessage} */
|
||||
/** @type {import('shock-common').Schema.ChatMessage} */
|
||||
const m = {
|
||||
// we'll decrypt later
|
||||
body: msg.body,
|
||||
|
|
@ -144,8 +144,8 @@ const onOpenForPubFeedPair = ([pub, feed]) =>
|
|||
|
||||
const ourSecret = await SEA.secret(await Utils.pubToEpub(pub), user._.sea)
|
||||
|
||||
const decryptedMsgs = await Utils.asyncMap(newMsgs, async m => {
|
||||
/** @type {Schema.ChatMessage} */
|
||||
const decryptedMsgs = await CommonUtils.asyncMap(newMsgs, async m => {
|
||||
/** @type {import('shock-common').Schema.ChatMessage} */
|
||||
const decryptedMsg = {
|
||||
...m,
|
||||
body: await SEA.decrypt(m.body, ourSecret)
|
||||
|
|
|
|||
|
|
@ -2,9 +2,9 @@
|
|||
const uuidv1 = require('uuid/v1')
|
||||
const debounce = require('lodash/debounce')
|
||||
const logger = require('winston')
|
||||
const { Utils: CommonUtils } = require('shock-common')
|
||||
|
||||
const { USER_TO_INCOMING } = require('../key')
|
||||
const { asyncForEach } = require('../utils')
|
||||
/** @typedef {import('../SimpleGUN').OpenListenerData} OpenListenerData */
|
||||
|
||||
/**
|
||||
|
|
@ -49,7 +49,9 @@ const onOpen = debounce(async uti => {
|
|||
/** @type {PubToIncoming} */
|
||||
const newPubToIncoming = {}
|
||||
|
||||
await asyncForEach(Object.entries(uti), async ([pub, encFeedID]) => {
|
||||
await CommonUtils.asyncForEach(
|
||||
Object.entries(uti),
|
||||
async ([pub, encFeedID]) => {
|
||||
if (encFeedID === null) {
|
||||
newPubToIncoming[pub] = null
|
||||
return
|
||||
|
|
@ -58,7 +60,8 @@ const onOpen = debounce(async uti => {
|
|||
if (typeof encFeedID === 'string') {
|
||||
newPubToIncoming[pub] = await SEA.decrypt(encFeedID, mySec)
|
||||
}
|
||||
})
|
||||
}
|
||||
)
|
||||
|
||||
// avoid old data from overwriting new data if decrypting took longer to
|
||||
// process for the older open() call than for the newer open() call
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
*/
|
||||
/* eslint-disable init-declarations */
|
||||
const logger = require('winston')
|
||||
const { Constants } = require('shock-common')
|
||||
|
||||
const ErrorCode = require('../errorCode')
|
||||
const Key = require('../key')
|
||||
|
||||
/**
|
||||
|
|
@ -41,7 +41,7 @@ const timeout10 = promise => {
|
|||
|
||||
new Promise((_, rej) => {
|
||||
timeoutID = setTimeout(() => {
|
||||
rej(new Error(ErrorCode.TIMEOUT_ERR))
|
||||
rej(new Error(Constants.ErrorCode.TIMEOUT_ERR))
|
||||
}, 10000)
|
||||
})
|
||||
])
|
||||
|
|
@ -64,7 +64,7 @@ const timeout5 = promise => {
|
|||
|
||||
new Promise((_, rej) => {
|
||||
timeoutID = setTimeout(() => {
|
||||
rej(new Error(ErrorCode.TIMEOUT_ERR))
|
||||
rej(new Error(Constants.ErrorCode.TIMEOUT_ERR))
|
||||
}, 5000)
|
||||
})
|
||||
])
|
||||
|
|
@ -252,55 +252,6 @@ const recipientToOutgoingID = async recipientPub => {
|
|||
return null
|
||||
}
|
||||
|
||||
/**
|
||||
* @template T
|
||||
* @param {T[]} arr
|
||||
* @param {(item: T) => void} cb
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
const asyncForEach = async (arr, cb) => {
|
||||
const promises = arr.map(item => cb(item))
|
||||
|
||||
await Promise.all(promises)
|
||||
}
|
||||
|
||||
/**
|
||||
* @template T
|
||||
* @template U
|
||||
* @param {T[]} arr
|
||||
* @param {(item: T) => Promise<U>} cb
|
||||
* @returns {Promise<U[]>}
|
||||
*/
|
||||
const asyncMap = (arr, cb) => {
|
||||
if (arr.length === 0) {
|
||||
return Promise.resolve([])
|
||||
}
|
||||
|
||||
const promises = arr.map(item => cb(item))
|
||||
|
||||
return Promise.all(promises)
|
||||
}
|
||||
|
||||
/**
|
||||
* @template T
|
||||
* @param {T[]} arr
|
||||
* @param {(item: T) => Promise<boolean>} cb
|
||||
* @returns {Promise<T[]>}
|
||||
*/
|
||||
const asyncFilter = async (arr, cb) => {
|
||||
if (arr.length === 0) {
|
||||
return []
|
||||
}
|
||||
|
||||
/** @type {Promise<boolean>[]} */
|
||||
const promises = arr.map(item => cb(item))
|
||||
|
||||
/** @type {boolean[]} */
|
||||
const results = await Promise.all(promises)
|
||||
|
||||
return arr.filter((_, idx) => results[idx])
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import('../SimpleGUN').ListenerData} listenerData
|
||||
* @returns {listenerData is import('../SimpleGUN').ListenerObj}
|
||||
|
|
@ -308,14 +259,6 @@ const asyncFilter = async (arr, cb) => {
|
|||
const dataHasSoul = listenerData =>
|
||||
typeof listenerData === 'object' && listenerData !== null
|
||||
|
||||
/**
|
||||
* @param {string} pub
|
||||
* @returns {string}
|
||||
*/
|
||||
const defaultName = pub => 'anon' + pub.slice(0, 8)
|
||||
|
||||
const LAST_SEEN_NODE_INTERVAL = 10000
|
||||
|
||||
/**
|
||||
* @param {string} pub
|
||||
* @returns {Promise<boolean>}
|
||||
|
|
@ -341,15 +284,12 @@ const isNodeOnline = async pub => {
|
|||
return (
|
||||
isOnlineApp ||
|
||||
(typeof lastSeenNode === 'number' &&
|
||||
Date.now() - lastSeenNode < LAST_SEEN_NODE_INTERVAL * 2)
|
||||
Date.now() - lastSeenNode < Constants.Misc.LAST_SEEN_NODE_INTERVAL * 2)
|
||||
)
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
asyncMap,
|
||||
asyncFilter,
|
||||
dataHasSoul,
|
||||
defaultName,
|
||||
delay,
|
||||
pubToEpub,
|
||||
recipientPubToLastReqSentID,
|
||||
|
|
@ -358,8 +298,6 @@ module.exports = {
|
|||
tryAndWait,
|
||||
mySecret,
|
||||
promisifyGunNode: require('./promisifygun'),
|
||||
asyncForEach,
|
||||
timeout5,
|
||||
LAST_SEEN_NODE_INTERVAL,
|
||||
isNodeOnline
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,13 +0,0 @@
|
|||
const Events = {
|
||||
ON_AVATAR: "ON_AVATAR",
|
||||
ON_BLACKLIST: "ON_BLACKLIST",
|
||||
ON_CHATS: "ON_CHATS",
|
||||
ON_DISPLAY_NAME: "ON_DISPLAY_NAME",
|
||||
ON_HANDSHAKE_ADDRESS: "ON_HANDSHAKE_ADDRESS",
|
||||
ON_RECEIVED_REQUESTS: "ON_RECEIVED_REQUESTS",
|
||||
ON_SENT_REQUESTS: "ON_SENT_REQUESTS",
|
||||
ON_BIO: "ON_BIO",
|
||||
ON_SEED_BACKUP: "ON_SEED_BACKUP",
|
||||
};
|
||||
|
||||
module.exports = Events;
|
||||
|
|
@ -2,6 +2,9 @@ const { promisify } = require("util");
|
|||
const FS = require("fs");
|
||||
|
||||
module.exports = {
|
||||
/**
|
||||
* @param {string} path
|
||||
*/
|
||||
access: path =>
|
||||
new Promise(resolve => {
|
||||
FS.access(path, FS.constants.F_OK, err => {
|
||||
|
|
|
|||
13
yarn.lock
13
yarn.lock
|
|
@ -4486,6 +4486,11 @@ normalize-path@^3.0.0:
|
|||
resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65"
|
||||
integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==
|
||||
|
||||
normalizr@^3.6.0:
|
||||
version "3.6.0"
|
||||
resolved "https://registry.yarnpkg.com/normalizr/-/normalizr-3.6.0.tgz#b8bbc4546ffe43c1c2200503041642915fcd3e1c"
|
||||
integrity sha512-25cd8DiDu+pL46KIaxtVVvvEPjGacJgv0yUg950evr62dQ/ks2JO1kf7+Vi5/rMFjaSTSTls7aCnmRlUSljtiA==
|
||||
|
||||
npm-bundled@^1.0.1:
|
||||
version "1.0.6"
|
||||
resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.0.6.tgz#e7ba9aadcef962bb61248f91721cd932b3fe6bdd"
|
||||
|
|
@ -5562,6 +5567,14 @@ shellwords@^0.1.1:
|
|||
resolved "https://registry.yarnpkg.com/shellwords/-/shellwords-0.1.1.tgz#d6b9181c1a48d397324c84871efbcfc73fc0654b"
|
||||
integrity sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==
|
||||
|
||||
shock-common@^0.0.1:
|
||||
version "0.0.1"
|
||||
resolved "https://registry.yarnpkg.com/shock-common/-/shock-common-0.0.1.tgz#72092c565ab65198da13656b5027fbd44881bf72"
|
||||
integrity sha512-LV2WiJDr1E6TEWel095oLN6gxpGTmsg6CUeGB6DdLHbYEz0qSpcDG4MYp2mZGpj/DejNKwYg1EiX2qf7ArpIkQ==
|
||||
dependencies:
|
||||
lodash "^4.17.15"
|
||||
normalizr "^3.6.0"
|
||||
|
||||
signal-exit@^3.0.0, signal-exit@^3.0.2:
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue