Merge branch 'develop' of https://github.com/Superalgos/Superalgos into develop

This commit is contained in:
EvaMaria70 committed 2021-11-08 10:40:23 +01:00
commit df0bce0ec2
39 files changed
+3637 -7400

No files matched your search

+49 -29
View File
@@ -1,10 +1,13 @@
exports.newDesktopApp = function newDesktopApp() {
let thisObject = {
socialGraph: undefined,
userProfiles: undefined,
p2pNetworkClient: undefined,
p2pNetwork: undefined,
p2pNetworkPeers: undefined,
webSocketsClient: undefined,
webSocketsInterface: undefined,
socialGraph: undefined,
run: run
}
@@ -13,37 +16,54 @@ exports.newDesktopApp = function newDesktopApp() {
return thisObject
async function run() {
/*
This is the Personal Social Graph for the user running this App.
*/
thisObject.socialGraph = DK.projects.socialTrading.modules.socialGraph.newSocialTradingModulesSocialGraph()
await thisObject.socialGraph.initialize()
/*
We can join now the P2P Network as a client app.
*/
thisObject.p2pNetwork = SA.projects.network.modules.p2pNetwork.newNetworkModulesP2PNetwork()
await thisObject.p2pNetwork.initialize('Network Client')
/*
Here we will pick a Network Node from all users profiles available that do have a Network Node running.
*/
let selectedNetworkNode = thisObject.p2pNetwork.p2pNodesToConnect[0]
/*
This is the Web Sockets client that interacts with the Superalgos Network.
*/
thisObject.webSocketsClient = SA.projects.network.modules.webSocketsNetworkClient.newNetworkModulesWebSocketsNetworkClient()
await thisObject.webSocketsClient.initialize('Network Client', selectedNetworkNode)
/*
These are the Network Interfaces by which the Web App interacts with this Desktop Client.
*/
thisObject.webSocketsInterface = DK.projects.socialTrading.modules.webSocketsInterface.newDesktopModulesWebSocketsInterface()
thisObject.webSocketsInterface.initialize()
console.log('Desktop Client Web Sockets Interface ....................................... Listening at port ' + global.env.DESKTOP_WEB_SOCKETS_INTERFACE_PORT)
setupNetwork()
setupServices()
async function setupNetwork() {
/*
We set up ourselves as a Network Client.
*/
thisObject.p2pNetworkClient = SA.projects.network.modules.p2pNetworkClient.newNetworkModulesP2PNetworkClient()
await thisObject.p2pNetworkClient.initialize()
/*
We will read all user profiles plugins and get from there our network identity.
*/
thisObject.userProfiles = SA.projects.network.modules.userProfiles.newNetworkModulesUserProfiles()
await thisObject.userProfiles.initialize(global.env.DESKTOP_APP_SIGNING_ACCOUNT, thisObject.p2pNetworkClient)
/*
We set up the P2P Network.
*/
thisObject.p2pNetwork = SA.projects.network.modules.p2pNetwork.newNetworkModulesP2PNetwork()
await thisObject.p2pNetwork.initialize('Network Client')
/*
Set up the connections to network nodes.
*/
thisObject.p2pNetworkPeers = SA.projects.network.modules.p2pNetworkPeers.newNetworkModulesP2PNetworkPeers()
await thisObject.p2pNetworkPeers.initialize(
'Network Client',
thisObject.p2pNetworkClient,
thisObject.p2pNetwork,
global.env.DESKTOP_APP_MAX_OUTGOING_PEERS
)
}
thisObject.httpInterface = DK.projects.socialTrading.modules.httpInterface.newDesktopModulesHttpInterface()
thisObject.httpInterface.initialize()
console.log('Desktop Client Http Interface .............................................. Listening at port ' + global.env.DESKTOP_HTTP_INTERFACE_PORT)
async function setupServices() {
/*
This is the Personal Social Graph for the user running this App.
*/
thisObject.socialGraph = DK.projects.socialTrading.modules.socialGraph.newSocialTradingModulesSocialGraph()
await thisObject.socialGraph.initialize()
/*
These are the Network Interfaces by which the Web App interacts with this Desktop Client.
*/
thisObject.webSocketsInterface = DK.projects.socialTrading.modules.webSocketsInterface.newDesktopModulesWebSocketsInterface()
thisObject.webSocketsInterface.initialize()
console.log('Desktop Client Web Sockets Interface ....................................... Listening at port ' + global.env.DESKTOP_WEB_SOCKETS_INTERFACE_PORT)
thisObject.httpInterface = DK.projects.socialTrading.modules.httpInterface.newDesktopModulesHttpInterface()
thisObject.httpInterface.initialize()
console.log('Desktop Client Http Interface .............................................. Listening at port ' + global.env.DESKTOP_HTTP_INTERFACE_PORT)
}
}
}
+2 -1
View File
@@ -12,8 +12,8 @@ exports.newEnvironment = function () {
BASE_PATH: basePath,
WEB_SERVER_URL: 'localhost',
PLATFORM_WEB_SOCKETS_INTERFACE_PORT: 18041,
DESKTOP_WEB_SOCKETS_INTERFACE_PORT: 17042,
NETWORK_WEB_SOCKETS_INTERFACE_PORT: 18042,
DESKTOP_WEB_SOCKETS_INTERFACE_PORT: 18043,
DESKTOP_WEB_SOCKETS_INTERFACE_HOST: 'localhost',
PLATFORM_HTTP_INTERFACE_PORT: 34248,
DESKTOP_HTTP_INTERFACE_PORT: 34249,
@@ -28,6 +28,7 @@ exports.newEnvironment = function () {
PATH_TO_MY_WORKSPACES: path.join(basePath, './Platform/My-Workspaces'),
PATH_TO_FONTS: path.join(basePath, './Platform/WebServer/Fonts'),
DESKTOP_APP_SIGNING_ACCOUNT: 'Social-Trading-Desktop-App-1',
DESKTOP_APP_MAX_OUTGOING_PEERS: 2,
MOBILE_APP_SIGNING_ACCOUNT: 'Social-Trading-Mobile-App-1',
SERVER_APP_SIGNING_ACCOUNT: 'Social-Trading-Server-App-1',
PLATFORM_APP_SIGNING_ACCOUNT: 'Algo-Traders-Platform-1',
+53 -28
View File
@@ -1,11 +1,13 @@
exports.newNetworkNode = function newNetworkNode() {
let thisObject = {
userProfiles: undefined,
p2pNetwork: undefined,
p2pNetworkPeers: undefined,
p2pNetworkNode: undefined,
webSocketsInterface: undefined,
socialGraphService: undefined,
storage: undefined,
p2pNetwork: undefined,
p2pNetworkPeers: undefined,
run: run
}
@@ -14,32 +16,55 @@ exports.newNetworkNode = function newNetworkNode() {
return thisObject
async function run() {
/*
The Social Graph Service is the first and for now, the only service this Network Node provides.
*/
thisObject.socialGraphService = NT.projects.socialTrading.modules.socialGraph.newNetworkModulesSocialGraph()
await thisObject.socialGraphService.initialize()
/*
The Sotrage deals with persisting the Social Graph.
*/
thisObject.storage = NT.projects.socialTrading.modules.storage.newSocialTradingModulesStorage()
thisObject.storage.initialize()
/*
Let's discover who is at the p2p network.
*/
thisObject.p2pNetwork = SA.projects.network.modules.p2pNetwork.newNetworkModulesP2PNetwork()
await thisObject.p2pNetwork.initialize('Network Peer')
/*
We can join now the P2P Network as a new peer there.
*/
thisObject.p2pNetworkPeers = SA.projects.network.modules.p2pNetworkPeers.newNetworkModulesP2PNetworkPeers()
await thisObject.p2pNetworkPeers.initialize()
/*
Other Network Nodes and Client Apps will communicate with this Network Node via it's Websocket Interface.
*/
thisObject.webSocketsInterface = NT.projects.network.modules.webSocketsInterface.newNetworkModulesWebSocketsInterface()
thisObject.webSocketsInterface.initialize()
console.log('Network Node Web Sockets Interface ....................................... Listening at port ' + JSON.parse(NT.networkNode.p2pNetwork.thisNetworkNode.node.config).webSocketsPort)
await setupNetwork()
await setupServices()
async function setupNetwork() {
/*
We set up ourselves as a Network Node.
*/
thisObject.p2pNetworkNode = SA.projects.network.modules.p2pNetworkNode.newNetworkModulesP2PNetworkNode()
await thisObject.p2pNetworkNode.initialize()
/*
We will read all user profiles plugins and get from there our network identity.
*/
thisObject.userProfiles = SA.projects.network.modules.userProfiles.newNetworkModulesUserProfiles()
await thisObject.userProfiles.initialize(global.env.P2P_NETWORK_NODE_SIGNING_ACCOUNT, thisObject.p2pNetworkNode)
/*
Let's discover who is at the p2p network.
*/
thisObject.p2pNetwork = SA.projects.network.modules.p2pNetwork.newNetworkModulesP2PNetwork()
await thisObject.p2pNetwork.initialize('Network Peer')
/*
Set up the connections to network nodes.
*/
thisObject.p2pNetworkPeers = SA.projects.network.modules.p2pNetworkPeers.newNetworkModulesP2PNetworkPeers()
await thisObject.p2pNetworkPeers.initialize(
'Network Peer',
thisObject.p2pNetworkNode,
thisObject.p2pNetwork,
global.env.P2P_NETWORK_NODE_MAX_OUTGOING_PEERS
)
}
async function setupServices() {
/*
The Social Graph Service is the first and for now, the only service this Network Node provides.
*/
thisObject.socialGraphService = NT.projects.socialTrading.modules.socialGraph.newNetworkModulesSocialGraph()
await thisObject.socialGraphService.initialize()
/*
The Sotrage deals with persisting the Social Graph.
*/
thisObject.storage = NT.projects.socialTrading.modules.storage.newSocialTradingModulesStorage()
thisObject.storage.initialize()
/*
Other Network Nodes and Client Apps will communicate with this Network Node via it's Websocket Interface.
*/
thisObject.webSocketsInterface = NT.projects.network.modules.webSocketsInterface.newNetworkModulesWebSocketsInterface()
thisObject.webSocketsInterface.initialize()
console.log('Network Node Web Sockets Interface ....................................... Listening at port ' + JSON.parse(NT.networkNode.p2pNetworkNode.node.config).webSocketsPort)
}
}
}
File diff suppressed because it is too large. Load diff
@@ -13,6 +13,17 @@
"actionFunction": "payload.executeAction",
"actionProject": "Community-Plugins"
},
{
"action": "Add Specified Plugin Data Mine",
"label": "Add Specified Plugin Data Mine",
"iconPathOn": "data-mine",
"iconPathOff": "data-mine",
"iconProject": "Data-Mining",
"actionProject": "Community-Plugins",
"relatedUiObject": "Data Mine",
"dontShowAtFullscreen": true,
"actionFunction": "payload.executeAction"
},
{
"action": "Delete UI Object",
"actionProject": "Visual-Scripting",
@@ -27,6 +38,9 @@
"addLeftIcons": true,
"level": 1,
"propertyNameAtParent": "pluginDataMines",
"editors": {
"list": true
},
"attachingRules": {
"compatibleTypes": "->Plugin Project->"
},
@@ -38,6 +38,11 @@ function newCommunityPluginsActionSwitch() {
UI.projects.communityPlugins.functionLibraries.pluginsFunctions.addMissingPluginDataMines(action.node, action.rootNodes)
}
break
case 'Add Specified Plugin Data Mine':
{
UI.projects.communityPlugins.functionLibraries.pluginsFunctions.addSpecifiedPluginDataMine(action.node, action.rootNodes)
}
break
case 'Add Missing Plugin Trading Mines':
{
UI.projects.communityPlugins.functionLibraries.pluginsFunctions.addMissingPluginTradingMines(action.node, action.rootNodes)
@@ -3,6 +3,7 @@ function newPluginsFunctionLibraryPluginsFunctions() {
addMissingPluginProjects: addMissingPluginProjects,
addMissingPluginTypes: addMissingPluginTypes,
addMissingPluginDataMines: addMissingPluginDataMines,
addSpecifiedPluginDataMine: addSpecifiedPluginDataMine,
addMissingPluginTradingMines: addMissingPluginTradingMines,
addMissingPluginTradingSystems: addMissingPluginTradingSystems,
addMissingPluginTradingEngines: addMissingPluginTradingEngines,
@@ -65,6 +66,32 @@ function newPluginsFunctionLibraryPluginsFunctions() {
}
}
function addSpecifiedPluginDataMine(node, rootNodes) {
let action = { node: node }
let projectName = UI.projects.communityPlugins.utilities.plugins.getProjectName(node)
if (projectName === "" || projectName === undefined) {
if (node.payload.parentNode !== undefined) {
node.payload.parentNode.payload.uiObject.setErrorMessage("Config codeName must have the name of the project.")
return
}
}
UI.projects.communityPlugins.utilities.plugins.getPluginFileNames(projectName, 'Data-Mines', onNamesArrived)
function onNamesArrived(fileNames) {
let eventSubscriptionId = node.payload.uiObject.container.eventHandler.listenToEvent('listSelectorClicked', onListSelect)
node.payload.uiObject.listSelector.activate(action, fileNames, eventSubscriptionId)
function onListSelect(event) {
let selectedArray = []
selectedArray.push(event.selectedNode)
UI.projects.communityPlugins.utilities.plugins.addMissingPluginFiles(node, selectedArray, 'Data-Mines', 'Data Mine', 'Data-Mining')
node.payload.uiObject.container.eventHandler.stopListening('listSelectorClicked')
}
}
}
function addMissingPluginTradingMines(node, rootNodes) {
let projectName = UI.projects.communityPlugins.utilities.plugins.getProjectName(node)
if (projectName === "" || projectName === undefined) {
Binary file not shown.

After

Width:  |  Height:  |  Size: 9.7 KiB

File diff suppressed because it is too large. Load diff
@@ -34,7 +34,7 @@
"config": true
},
"initialValues": {
"config": "{ \n\"startDate\": \"2020-01-01\"\n}"
"config": "{ \n\"startDate\": \"2021-01-01\"\n}"
},
"level": 3,
"attachingRules": {
@@ -3,8 +3,8 @@
"pageNumber": 17,
"type": "Tutorial Step - Let's Talk Backups",
"definition": {
"text": "Backups are very powerful, and there are multiple use cases! When you click on the backup button, the node and its offspring are saved on a JSON file!",
"updated": 1615546227075,
"text": "Backups are very powerful, and there are various use cases! When you click on the button, the node and its offspring are saved on a JSON file!",
"updated": 1636302782978,
"icon": {
"name": "backup-entity",
"project": "Foundations"
@@ -6,7 +6,7 @@
"text": "What if the nodes are far away from each other, maybe even in different hierarchies? Watch the video to learn a few tricks!",
"updated": 1616098998366,
"icon": {
"name": "Mouse\\mouse-right-click",
"name": "mouse-right-click",
"project": "Foundations"
},
"translations": [
@@ -6,8 +6,8 @@
"text": "If you haven't yet, go ahead and establish a reference from the Trading System Reference to the Lightning Strike Trading System!",
"updated": 1615808208398,
"icon": {
"name": "Trading\\trading-system",
"project": "Foundations"
"name": "trading-system",
"project": "Algorithmic-Trading"
},
"translations": [
{
@@ -5,8 +5,8 @@
"definition": {
"text": "Go to your File Explorer app and look for the following paths relative to the root Superalgos folder...",
"icon": {
"name": "Plugins\\plugins",
"project": "Foundations"
"name": "plugins",
"project": "Community-Plugins"
},
"updated": 1615906049600,
"translations": [
@@ -6,8 +6,8 @@
"text": "Plugins are data structures that ship with the system and that you may call into any workspace using the Plugins hierarchy.",
"updated": 1615914003358,
"icon": {
"name": "Plugins\\plugins",
"project": "Foundations"
"name": "plugins",
"project": "Community-Plugins"
},
"translations": [
{
@@ -3,12 +3,12 @@
"pageNumber": 41,
"type": "Tutorial Step - How Plugins Work",
"definition": {
"text": "Find the Plugin Trading Systems node and expand it! Note the Plugin File node named Masters-Lightning-Strike...",
"text": "Find the Plugin Trading Systems node inside the Algorithmic Trading project and expand it! Note the Plugin File node named Masters-Lightning-Strike...",
"icon": {
"name": "expand-structure-of-nodes",
"project": "Foundations"
},
"updated": 1615919140092,
"updated": 1636303001726,
"translations": [
{
"language": "IT",
@@ -5,7 +5,7 @@
"definition": {
"icon": {
"name": "tutorial",
"project": "Education"
"project": "Foundations"
},
"text": "I'm an interactive tutorial, the first in a series designed to facilitate your onboarding and teach you all the basics!",
"translations": [
@@ -48,8 +48,9 @@
{
"language": "RU",
"text": "Я - интерактивное учебное пособие, первое в серии, предназначенное для облегчения Вашей адаптации и обучения всем основам.",
"updated": 1635448912724},
{
"updated": 1635448912724
},
{
"language": "TR",
"text": "Ben interaktif bir öğreticiyim, Superalgos'u öğrenmenize yardımcı olmak,işinizi kolaylaştırmak ve size tüm temel bilgileri öğretmek için tasarlanmış bir serinin ilk öğreticisiyim.",
"updated": 1635575887053
@@ -101,8 +102,9 @@
{
"language": "RU",
"text": "Я помогу Вам начать, покажу панель инструментов, с помощью которых Вы сможете комфортно передвигаться и раскрыть все интересные вещи, которые Superalgos может сделать для Вас.",
"updated": 1635449021102},
{
"updated": 1635449021102
},
{
"language": "TR",
"text": "Başlamanıza yardımcı olacağım, rahatça hareket etmenize yardımcı olacak araçları göstereceğim ve Superalgos'un sizin için yapabileceği tüm harika şeyleri keşfetmenize yardımcı olacağım.",
"updated": 1635575910092
@@ -153,8 +155,9 @@
{
"language": "RU",
"text": "Это учебное пособие является окончательным инструментом для адаптации в системе Superalgos. Начинать ознакомление с этой системой каким-либо другим образом, является ошибкой, так как никакой другой ресурс не поможет Вам ускорить процесс. Вам следовало бы ознакомиться с полным учебным пособием, прежде чем пытаться реализовать свои собственные идеи!",
"updated": 1635449358224},
{
"updated": 1635449358224
},
{
"language": "TR",
"text": "Öğreticiler, Superalgos'a alıştırma aracıdır! Superalgos'a başka bir şekilde başlamak bir hatadır, çünkü başka hiçbir kaynak sizi daha fazla hızlandıramaz. Kendi fikirlerinizi uygulamaya çalışmadan önce tüm dersleri yapmalısınız!",
"updated": 1635576039599
@@ -216,4 +219,4 @@
]
}
]
}
}
@@ -60,7 +60,7 @@
"paragraphs": [
{
"style": "Text",
"text": "If you are accessing the Client from a remote machine, you must adjust the Network Node configuration before continuing.",
"text": "If you are accessing the Client from a remote machine, you must adjust the Network Node configuration.",
"translations": [
{
"language": "ID",
@@ -108,12 +108,13 @@
"text": "İstemciye ( Client ) uzak bir makineden erişiyorsanız, devam etmeden önce Ağ Düğümü ( Node ) yapılandırmasını ayarlamanız gerekir.",
"updated": 1635579070105
}
]
],
"updated": 1636299988021
},
{
"style": "List",
"text": "Click Configure on the top-right corner of the Network Node menu.",
"updated": 1610612485562,
"text": "Click Configure on the top-right corner of the Network Node menu.",
"updated": 1636300153084,
"translations": [
{
"language": "ID",
@@ -4,8 +4,8 @@
"type": "Tutorial Step - Visual Scripting on Steroids",
"definition": {
"icon": {
"project": "Foundations",
"name": "indicator-bot"
"name": "indicator-bot",
"project": "Data-Mining"
},
"text": "Talking about block-building, we are now in the confines of the Masters Data Mine. To your left, the definition of one of the bots you sent mining minutes ago.",
"translations": [
@@ -4,8 +4,8 @@
"type": "Tutorial Step - Aim High, Trade Big!",
"definition": {
"icon": {
"project": "Foundations",
"name": "network-node"
"name": "network",
"project": "Network"
},
"text": "Picture an army of bots working with multiple exchanges, markets, and strategies, running on a network <i>à la</i> trading farm.",
"translations": [
@@ -4,7 +4,7 @@
"type": "Tutorial Step - Machines Learn Too!",
"definition": {
"icon": {
"name": "tensorflow-project",
"name": "tensorflow",
"project": "TensorFlow"
},
"text": "The latest version of Superalgos features an experimental integration of TensorFlow to leverage ML from within the app!",
@@ -4,8 +4,8 @@
"type": "Tutorial Step - What Is It We Are Testing?",
"definition": {
"icon": {
"name": "Trading\\trading-system",
"project": "Foundations"
"name": "trading-system",
"project": "Algorithmic-Trading"
},
"text": "We've run a backtest but we haven't discussed the Trading System we are testing! Let's go through the basics!",
"translations": [
@@ -4,8 +4,8 @@
"type": "Tutorial Step - Simplifying Complexity",
"definition": {
"icon": {
"name": "Trading\\trading-system",
"project": "Foundations"
"name": "trading-system",
"project": "Algorithmic-Trading"
},
"text": "We haven't discussed trading systems as a framework, but a feature relevant to this explanation is that they may handle multiple strategies.",
"translations": [
@@ -4,8 +4,8 @@
"type": "Tutorial Step - Find the Node Challenge",
"definition": {
"icon": {
"name": "Trading\\trading-engine",
"project": "Foundations"
"name": "trading-engine",
"project": "Algorithmic-Trading"
},
"text": "The Trading Engine administers the complexity entailed in automated trading by making information accessible to users and trading systems.",
"translations": [
@@ -4,8 +4,8 @@
"type": "Tutorial Step - Get In Touch!",
"definition": {
"icon": {
"name": "Announcement\\telegram-bot",
"project": "Foundations"
"name": "telegram-bot",
"project": "Social-Bots"
},
"text": "Drop by to say hi, get help, and meet the Community! You may <a href=\"https://discord.gg/CGeKC6WQQb\" target=\"_blank\" style=\"color: blue;\">join the new Discord Server</a> or the original Telegram groups below, where it all started!",
"updated": 1619810146066,
@@ -3,8 +3,8 @@
"pageNumber": "106.2",
"type": "Tutorial Step - Ultimate Social Trading",
"definition": {
"text": "The Superalgos Platform is designed to serve algo-traders. But the project is expanding its scope to cater to all crypto users!",
"updated": 1630855795499,
"text": "The Superalgos Platform is designed to serve algo traders. But the project is expanding its scope to cater to all crypto users!",
"updated": 1636302029793,
"icon": {
"name": "User\\user-influencer",
"project": "Governance"
@@ -20,8 +20,8 @@
"paragraphs": [
{
"style": "List",
"text": "Incentivized by the protocol, algo-traders will compete to produce and disseminate trading signals.",
"updated": 1630856058462,
"text": "Incentivized by the protocol, algo traders will compete to produce and disseminate trading signals.",
"updated": 1636302022130,
"translations": [
{
"language": "DE",
@@ -55,8 +55,8 @@
},
{
"style": "Callout",
"text": "Both algo-traders and influencers get paid by the protocol, while crypto users get all products and services free of charge. Quite disruptive, right?",
"updated": 1630856187731,
"text": "Both algo traders and influencers get paid by the protocol, while crypto users get all products and services free of charge. Quite disruptive, right?",
"updated": 1636302065775,
"translations": [
{
"language": "DE",
@@ -47,6 +47,8 @@ function newListSelector() {
const SIZE = 36
const FONT_SIZE = 24
const MAX_LABELS = 7
let VISIBLE_LABELS = 7
let selected = 0
@@ -107,7 +109,7 @@ function newListSelector() {
deactivate()
}
if (optionsList.length < VISIBLE_LABELS) {
if (optionsList.length < MAX_LABELS) {
VISIBLE_LABELS = optionsList.length
}
@@ -0,0 +1,441 @@
{
"type": "User Profile",
"name": "ozichris",
"config": "{\n \"signature\": {\n \"message\": \"ozichris\",\n \"messageHash\": \"0x7838947e4042d7f2205426117ff0d8f9dedce58a21fa1bc6bf63d168af01111a\",\n \"v\": \"0x1c\",\n \"r\": \"0x4e361f80b832c869331ffefad059a5fb17f31bdc5972099c70584d7172ad5e9a\",\n \"s\": \"0x3cfeb08058c922f73b8f982e8359cde99e82ed700a05b47ef2f04aa8ff7d6204\",\n \"signature\": \"0x4e361f80b832c869331ffefad059a5fb17f31bdc5972099c70584d7172ad5e9a3cfeb08058c922f73b8f982e8359cde99e82ed700a05b47ef2f04aa8ff7d62041c\"\n }\n}",
"project": "Governance",
"tokenPowerSwitch": {
"type": "Token Power Switch",
"name": "New Token Power Switch",
"config": "{}",
"project": "Governance",
"tokenPowerSwitch": [],
"onboardingPrograms": {
"type": "Onboarding Programs",
"name": "New Onboarding Programs",
"config": "{\n \"percentage\": 0\n }",
"project": "Governance",
"airdropProgram": {
"type": "Airdrop Program",
"name": "New Airdrop Program",
"config": "{}",
"project": "Governance",
"tokensAwarded": {
"type": "Tokens Awarded",
"name": "New Tokens Awarded",
"project": "Governance",
"id": "ff2ea74e-0eae-4d18-95e5-6e9824080d7d",
"savedPayload": {
"position": {
"x": 14849.750000000002,
"y": 5655.3468758305435
},
"targetPosition": {
"x": 14774.750000000002,
"y": 5785.250686398209
},
"floatingObject": {
"isPinned": false,
"isFrozen": false,
"isCollapsed": false,
"angleToParent": 1,
"distanceToParent": 3,
"arrangementStyle": 0
},
"uiObject": {
"isRunning": false
}
}
},
"id": "3c38adeb-50ff-49d7-b41d-65d3e74db09c",
"savedPayload": {
"position": {
"x": 14774.750000000002,
"y": 5785.250686398209
},
"targetPosition": {
"x": 14699.750000000002,
"y": 5915.154496965874
},
"floatingObject": {
"isPinned": false,
"isFrozen": false,
"isCollapsed": false,
"angleToParent": 1,
"distanceToParent": 3,
"arrangementStyle": 0
},
"uiObject": {
"isRunning": false
}
}
},
"id": "383dc489-8105-4cee-9179-c10d657dc94e",
"savedPayload": {
"position": {
"x": 14699.750000000002,
"y": 5915.154496965874
},
"targetPosition": {
"x": 14624.750000000002,
"y": 6045.05830753354
},
"floatingObject": {
"isPinned": false,
"isFrozen": false,
"isCollapsed": false,
"angleToParent": 1,
"distanceToParent": 3,
"arrangementStyle": 0
},
"uiObject": {
"isRunning": false
}
}
},
"communityBuildingPrograms": {
"type": "Community Building Programs",
"name": "New Community Building Programs",
"config": "{}",
"project": "Governance",
"referralProgram": {
"type": "Referral Program",
"name": "New Referral Program",
"config": "{}",
"project": "Governance",
"userReferrers": [
{
"type": "User Referrer",
"name": "",
"config": "{}",
"project": "Governance",
"id": "98a74abf-a944-4d9b-bbae-f6164db93172",
"savedPayload": {
"position": {
"x": 14923.380477900713,
"y": 5900.169433590179
},
"targetPosition": {
"x": 14884.557621135335,
"y": 6045.05830753354
},
"floatingObject": {
"isPinned": false,
"isFrozen": false,
"isCollapsed": false,
"angleToParent": 2,
"distanceToParent": 3,
"arrangementStyle": 0
},
"uiObject": {
"isRunning": false
},
"referenceParent": {
"type": "User Profile",
"name": "ssplatt",
"id": "f61e7149-36d7-4867-9c90-93b8f0b3d795"
},
"referenceParentCombinedNodePath": [
[
"ssplatt",
"User Profile"
]
]
}
}
],
"tokensAwarded": {
"type": "Tokens Awarded",
"name": "New Tokens Awarded",
"project": "Governance",
"id": "fad9fc7e-53f1-4046-9da3-e8588294ffe6",
"savedPayload": {
"position": {
"x": 15014.461431703001,
"y": 5970.05830753354
},
"targetPosition": {
"x": 14884.557621135335,
"y": 6045.05830753354
},
"floatingObject": {
"isPinned": false,
"isFrozen": false,
"isCollapsed": false,
"angleToParent": 1,
"distanceToParent": 3,
"arrangementStyle": 0
},
"uiObject": {
"isRunning": false
}
}
},
"tokensBonus": {
"type": "Tokens Bonus",
"name": "New Tokens Bonus",
"project": "Governance",
"id": "4921b2ad-80b1-469e-9a8f-72805ed4a77e",
"savedPayload": {
"position": {
"x": 15029.446495078695,
"y": 6083.881164298918
},
"targetPosition": {
"x": 14884.557621135335,
"y": 6045.05830753354
},
"floatingObject": {
"isPinned": false,
"isFrozen": false,
"isCollapsed": false,
"angleToParent": 2,
"distanceToParent": 3,
"arrangementStyle": 0
},
"uiObject": {
"isRunning": false
}
}
},
"id": "b3ba73f6-d0a4-43a6-a74f-cb5e58e317a1",
"savedPayload": {
"position": {
"x": 14884.557621135335,
"y": 6045.05830753354
},
"targetPosition": {
"x": 14754.653810567668,
"y": 6120.05830753354
},
"floatingObject": {
"isPinned": false,
"isFrozen": false,
"isCollapsed": false,
"angleToParent": 1,
"distanceToParent": 3,
"arrangementStyle": 0
},
"uiObject": {
"isRunning": false
}
}
},
"mentorshipProgram": {
"type": "Mentorship Program",
"name": "New Mentorship Program",
"config": "{}",
"project": "Governance",
"userMentors": [
{
"type": "User Mentor",
"name": "",
"config": "{}",
"project": "Governance",
"id": "5498c76d-2b1a-4cf1-8df5-6db097b218b7",
"savedPayload": {
"position": {
"x": 14974.542684511029,
"y": 6288.784974866583
},
"targetPosition": {
"x": 14829.653810567668,
"y": 6249.962118101205
},
"floatingObject": {
"isPinned": false,
"isFrozen": false,
"isCollapsed": false,
"angleToParent": 2,
"distanceToParent": 3,
"arrangementStyle": 0
},
"uiObject": {
"isRunning": false
},
"referenceParent": {
"type": "User Profile",
"name": "Julian-Molina",
"id": "45acddfe-2389-4db6-a634-97e2318298bb"
},
"referenceParentCombinedNodePath": [
[
"Julian-Molina",
"User Profile"
]
]
}
}
],
"tokensAwarded": {
"type": "Tokens Awarded",
"name": "New Tokens Awarded",
"project": "Governance",
"id": "ee3809b5-8295-46c4-9a61-bf7c2f3a6b84",
"savedPayload": {
"position": {
"x": 14904.653810567668,
"y": 6379.865928668871
},
"targetPosition": {
"x": 14829.653810567668,
"y": 6249.962118101205
},
"floatingObject": {
"isPinned": false,
"isFrozen": false,
"isCollapsed": false,
"angleToParent": 1,
"distanceToParent": 3,
"arrangementStyle": 0
},
"uiObject": {
"isRunning": false
}
}
},
"tokensBonus": {
"type": "Tokens Bonus",
"name": "New Tokens Bonus",
"project": "Governance",
"id": "0f881823-90d8-4f72-b304-a5a38e6aa575",
"savedPayload": {
"position": {
"x": 14790.83095380229,
"y": 6394.850992044566
},
"targetPosition": {
"x": 14829.653810567668,
"y": 6249.962118101205
},
"floatingObject": {
"isPinned": false,
"isFrozen": false,
"isCollapsed": false,
"angleToParent": 2,
"distanceToParent": 3,
"arrangementStyle": 0
},
"uiObject": {
"isRunning": false
}
}
},
"id": "6fc9d3b3-8aa8-4906-8585-b3f55cbf31fb",
"savedPayload": {
"position": {
"x": 14829.653810567668,
"y": 6249.962118101205
},
"targetPosition": {
"x": 14754.653810567668,
"y": 6120.05830753354
},
"floatingObject": {
"isPinned": false,
"isFrozen": false,
"isCollapsed": false,
"angleToParent": 2,
"distanceToParent": 3,
"arrangementStyle": 0
},
"uiObject": {
"isRunning": false
}
}
},
"id": "dc67bf81-3116-48c3-b81b-ea767757a8bd",
"savedPayload": {
"position": {
"x": 14754.653810567668,
"y": 6120.05830753354
},
"targetPosition": {
"x": 14624.750000000002,
"y": 6045.05830753354
},
"floatingObject": {
"isPinned": false,
"isFrozen": false,
"isCollapsed": false,
"angleToParent": 2,
"distanceToParent": 3,
"arrangementStyle": 0
},
"uiObject": {
"isRunning": false
}
}
},
"id": "38695838-cef1-4a8b-a24e-90b03fbd8d2b",
"savedPayload": {
"position": {
"x": 14624.750000000002,
"y": 6045.05830753354
},
"targetPosition": {
"x": 14474.750000000002,
"y": 6045.05830753354
},
"floatingObject": {
"isPinned": false,
"isFrozen": false,
"isCollapsed": false,
"angleToParent": 1,
"distanceToParent": 4,
"arrangementStyle": 0
},
"uiObject": {
"isRunning": false
}
}
},
"tokensMined": {
"type": "Tokens Mined",
"name": "New Tokens Mined",
"project": "Governance",
"id": "e77237a9-93ad-4591-9df0-69f4606ba87b",
"savedPayload": {
"position": {
"x": 14324.750000000002,
"y": 6045.05830753354
},
"targetPosition": {
"x": 14474.750000000002,
"y": 6045.05830753354
},
"floatingObject": {
"isPinned": false,
"isFrozen": false,
"isCollapsed": false,
"angleToParent": 1,
"distanceToParent": 4,
"arrangementStyle": 0
},
"uiObject": {
"isRunning": false
}
}
},
"id": "aef0429e-f08d-4779-a44c-11725d952c04",
"savedPayload": {
"position": {
"x": 14474.750000000002,
"y": 6045.05830753354
},
"targetPosition": {
"x": 14474.750000000002,
"y": 6045.05830753354
},
"floatingObject": {
"isPinned": false,
"isFrozen": false,
"isCollapsed": true,
"angleToParent": 1,
"distanceToParent": 1,
"arrangementStyle": 0
},
"uiObject": {
"isRunning": false
}
}
}
@@ -12,6 +12,9 @@ exports.newNetworkModulesWebSocketsInterface = function newNetworkModulesWebSock
and sending messages to those entities.
*/
let thisObject = {
socketServer: undefined,
clientInterface: undefined,
peerInterface: undefined,
networkClients: undefined,
networkPeers: undefined,
callersMap: undefined,
@@ -19,10 +22,6 @@ exports.newNetworkModulesWebSocketsInterface = function newNetworkModulesWebSock
finalize: finalize
}
let socketServer
let clientInterface
let peerInterface
let web3 = new SA.nodeModules.web3()
return thisObject
@@ -32,19 +31,19 @@ exports.newNetworkModulesWebSocketsInterface = function newNetworkModulesWebSock
thisObject.networkPeers = undefined
callersMap = undefined
socketServer = undefined
clientInterface = undefined
peerInterface = undefined
thisObject.socketServer = undefined
thisObject.clientInterface = undefined
thisObject.peerInterface = undefined
web3 = undefined
}
function initialize() {
let port = JSON.parse(NT.networkNode.p2pNetwork.thisNetworkNode.node.config).webSocketsPort
let port = JSON.parse(NT.networkNode.p2pNetworkNode.node.config).webSocketsPort
socketServer = new SA.nodeModules.ws.Server({ port: port })
clientInterface = NT.projects.socialTrading.modules.clientInterface.newSocialTradingModulesClientInterface()
peerInterface = NT.projects.socialTrading.modules.peerInterface.newSocialTradingModulesPeerInterface()
thisObject.socketServer = new SA.nodeModules.ws.Server({ port: port })
thisObject.clientInterface = NT.projects.socialTrading.modules.clientInterface.newSocialTradingModulesClientInterface()
thisObject.peerInterface = NT.projects.socialTrading.modules.peerInterface.newSocialTradingModulesPeerInterface()
thisObject.networkClients = []
thisObject.networkPeers = []
@@ -55,7 +54,7 @@ exports.newNetworkModulesWebSocketsInterface = function newNetworkModulesWebSock
function setUpWebSocketServer() {
try {
socketServer.on('connection', onConnectionOpened)
thisObject.socketServer.on('connection', onConnectionOpened)
function onConnectionOpened(socket)
/*
@@ -65,7 +64,8 @@ exports.newNetworkModulesWebSocketsInterface = function newNetworkModulesWebSock
let caller = {
socket: socket,
userProfile: undefined,
role: undefined
role: undefined,
node: undefined
}
caller.socket.id = SA.projects.foundations.utilities.miscellaneousFunctions.genereteUniqueId()
@@ -123,19 +123,19 @@ exports.newNetworkModulesWebSocketsInterface = function newNetworkModulesWebSock
let response
switch (caller.role) {
case 'Network Client': {
response = await clientInterface.messageReceived(messageHeader.payload, caller.userProfile)
response = await thisObject.clientInterface.messageReceived(messageHeader.payload, caller.userProfile)
response.messageId = messageHeader.messageId
caller.socket.send(JSON.stringify(response))
break
}
case 'Network Peer': {
response = await peerInterface.messageReceived(messageHeader.payload)
response = await thisObject.peerInterface.messageReceived(messageHeader.payload)
response.messageId = messageHeader.messageId
caller.socket.send(JSON.stringify(response))
break
}
}
if (response.result === 'Ok' && messageHeader.payload.requestType === 'Event') {
if (response.result === 'Ok' && JSON.parse(messageHeader.payload).requestType === 'Event') {
broadcastToPeers(messageHeader, caller)
broadcastToClients(messageHeader, caller)
}
@@ -251,6 +251,32 @@ exports.newNetworkModulesWebSocketsInterface = function newNetworkModulesWebSock
}
}
/*
The caller needs to provide it's Node.
*/
if (messageHeader.callerNode === undefined) {
let response = {
result: 'Error',
message: 'node Not Provided.'
}
caller.socket.send(JSON.stringify(response))
caller.socket.close()
return
}
/*
The caller's Node needs to be parseable.
*/
try {
caller.node = JSON.parse(messageHeader.callerNode)
} catch (err) {
let response = {
result: 'Error',
message: 'node Not Coorrect JSON Format.'
}
caller.socket.send(JSON.stringify(response))
caller.socket.close()
return
}
/*
The caller needs to provide it's User Profile Handle.
*/
if (messageHeader.callerProfileHandle === undefined) {
@@ -262,7 +288,6 @@ exports.newNetworkModulesWebSocketsInterface = function newNetworkModulesWebSock
caller.socket.close()
return
}
caller.userProfileHandle = messageHeader.callerProfileHandle
/*
The caller needs to provide a callerTimestamp.
@@ -492,14 +517,24 @@ exports.newNetworkModulesWebSocketsInterface = function newNetworkModulesWebSock
}
function broadcastToPeers(messageHeader, caller) {
/*
The Boradcast to network peers is not done via
the network peers incomming connections, but
on the outgoing connections only.
*/
let callerIdToAVoid
if (caller.role === 'Network Peer') {
callerIdToAVoid = caller.socket.id
callerIdToAVoid = caller.node.id
}
for (let i = 0; i < thisObject.networkPeers.length; i++) {
let networkPeer = thisObject.networkPeers[i]
if (networkPeer.socket.id === callerIdToAVoid) { continue }
networkPeer.socket.send(messageHeader)
for (let i = 0; i < NT.networkNode.p2pNetworkPeers.peers.length; i++) {
let peer = NT.networkNode.p2pNetworkPeers.peers[i]
if (peer.p2pNetworkNode.node.id === callerIdToAVoid) { continue }
peer.webSocketsClient.sendMessage(messageHeader.payload)
.catch(onError)
function onError() {
console.log('[ERROR] Web Sockets Interface -> broadcastToPeers -> Sending Message Failed.')
}
}
}
@@ -511,7 +546,12 @@ exports.newNetworkModulesWebSocketsInterface = function newNetworkModulesWebSock
for (let i = 0; i < thisObject.networkClients.length; i++) {
let networkClient = thisObject.networkClients[i]
if (networkClient.socket.id === callerIdToAVoid) { continue }
networkClient.socket.send(messageHeader)
networkClient.socket.send(messageHeader.payload)
.catch(onError)
function onError() {
console.log('[ERROR] Web Sockets Interface -> broadcastToPeers -> Sending Message Failed.')
}
}
}
-10
View File
@@ -4,9 +4,7 @@ exports.newNetworkModulesP2PNetwork = function newNetworkModulesP2PNetwork() {
of this current node to other peers.
*/
let thisObject = {
joinTheNetworkAsNetworkPeer: joinTheNetworkAsNetworkPeer,
p2pNodesToConnect: undefined,
thisNetworkNode: undefined,
/* Framework Functions */
initialize: initialize,
finalize: finalize
@@ -38,18 +36,10 @@ exports.newNetworkModulesP2PNetwork = function newNetworkModulesP2PNetwork() {
let p2pNetworkNode = SA.projects.network.globals.memory.arrays.P2P_NETWORK_NODES[i]
if (thisP2PNodeId !== p2pNetworkNode.node.id) {
thisObject.p2pNodesToConnect.push(p2pNetworkNode)
} else {
thisObject.thisNetworkNode = p2pNetworkNode
}
}
break
}
}
}
function joinTheNetworkAsNetworkPeer() {
/*
To join the network we will need to thorugh the list of Network Nodes and pick one to connect to.
*/
}
}
@@ -0,0 +1,27 @@
exports.newNetworkModulesP2PNetworkClient = function newNetworkModulesP2PNetworkClient() {
/*
This module represents the P2P Network Client running at the moment.
*/
let thisObject = {
node: undefined,
blockchainAccount: undefined,
userProfile: undefined,
/* Framework Functions */
initialize: initialize,
finalize: finalize
}
return thisObject
function finalize() {
thisObject.node = undefined
thisObject.blockchainAccount = undefined
thisObject.userProfile = undefined
}
async function initialize() {
}
}
+59 -39
View File
@@ -1,9 +1,10 @@
exports.newNetworkModulesP2PNetworkPeers = function newNetworkModulesP2PNetworkPeers() {
/*
This module holds the P2P Nodes we are coonected to and that are connected to us.
This module holds the P2P Nodes we are coonected to.
*/
let thisObject = {
outgoingConnectedPeers: undefined,
peers: undefined,
sendMessage: sendMessage,
/* Framework Functions */
initialize: initialize,
@@ -16,63 +17,82 @@ exports.newNetworkModulesP2PNetworkPeers = function newNetworkModulesP2PNetworkP
return thisObject
function finalize() {
thisObject.outgoingConnectedPeers = undefined
thisObject.peers = undefined
clearInterval(intervalIdConnectToPeers)
}
async function initialize() {
async function initialize(
callerRole,
p2pNetworkIdentity,
p2pNetwork,
maxOutgoingPeers
) {
thisObject.outgoingConnectedPeers = []
thisObject.peers = []
connectToPeers()
intervalIdConnectToPeers = setInterval(connectToPeers, RECONNECT_DELAY);
}
async function connectToPeers() {
async function connectToPeers() {
if (thisObject.peers.length >= maxOutgoingPeers) { return }
if (thisObject.outgoingConnectedPeers.count >= global.env.P2P_NETWORK_NODE_MAX_OUTGOING_PEERS) { return }
for (let i = 0; i < p2pNetwork.p2pNodesToConnect.length; i++) {
if (thisObject.peers.length >= maxOutgoingPeers) { break }
for (let i = 0; i < NT.networkNode.p2pNetwork.p2pNodesToConnect.length; i++) {
if (thisObject.outgoingConnectedPeers.count >= global.env.P2P_NETWORK_NODE_MAX_OUTGOING_PEERS) { break }
let peer = {}
peer.p2pNetworkNode = NT.networkNode.p2pNetwork.p2pNodesToConnect[i]
if (isOutgoingConnectedPeer(peer) === true) { continue }
peer.webSocketsClient = SA.projects.network.modules.webSocketsNetworkClient.newNetworkModulesWebSocketsNetworkClient()
await peer.webSocketsClient.initialize('Network Peer', peer.p2pNetworkNode, onConnectionClosed)
.then(addPeer)
.catch(onError)
let peer = {
p2pNetworkNode: undefined,
webSocketsClient: undefined
}
function addPeer() {
thisObject.outgoingConnectedPeers.push(peer)
}
peer.p2pNetworkNode = p2pNetwork.p2pNodesToConnect[i]
if (isConnectedPeer(peer) === true) { continue }
peer.webSocketsClient = SA.projects.network.modules.webSocketsNetworkClient.newNetworkModulesWebSocketsNetworkClient()
await peer.webSocketsClient.initialize(callerRole, p2pNetworkIdentity, peer.p2pNetworkNode, onConnectionClosed)
.then(addPeer)
.catch(onError)
function onError(err) {
if (err !== undefined) {
console.log('[ERROR] P2P Network Peers -> onError -> While connecting to node -> ' + peer.p2pNetworkNode.userProfile.userProfileHandle + ' -> ' + peer.p2pNetworkNode.node.name + ' -> ' + err.message)
} else {
console.log('[WARN] P2P Network Peers -> onError -> Peer Not Available at the Moment -> ' + peer.p2pNetworkNode.userProfile.userProfileHandle + ' -> ' + peer.p2pNetworkNode.node.name)
function addPeer() {
thisObject.peers.push(peer)
}
function onError(err) {
if (err !== undefined) {
console.log('[ERROR] P2P Network Peers -> onError -> While connecting to node -> ' + peer.p2pNetworkNode.userProfile.userProfileHandle + ' -> ' + peer.p2pNetworkNode.node.name + ' -> ' + err.message)
} else {
console.log('[WARN] P2P Network Peers -> onError -> Peer Not Available at the Moment -> ' + peer.p2pNetworkNode.userProfile.userProfileHandle + ' -> ' + peer.p2pNetworkNode.node.name)
}
}
function onConnectionClosed(webSocketsClientId) {
for (let i = 0; i < thisObject.peers.length; i++) {
let connectedPeer = thisObject.peers[i]
if (connectedPeer.webSocketsClient.id === webSocketsClientId) {
thisObject.peers.splice(i, 1)
return
}
}
}
}
function onConnectionClosed(webSocketsClientId) {
for (let i = 0; i < thisObject.outgoingConnectedPeers.length; i++) {
let connectedPeer = thisObject.outgoingConnectedPeers[i]
if (connectedPeer.webSocketsClient.id === webSocketsClientId) {
thisObject.outgoingConnectedPeers.splice(i, 1)
return
function isConnectedPeer(peer) {
for (let i = 0; i < thisObject.peers.length; i++) {
let connectedPeer = thisObject.peers[i]
if (connectedPeer.p2pNetworkNode.node.id === peer.p2pNetworkNode.node.id) {
return true
}
}
}
}
}
function isOutgoingConnectedPeer(peer) {
for (let i = 0; i < thisObject.outgoingConnectedPeers.length; i++) {
let connectedPeer = thisObject.outgoingConnectedPeers[i]
if (connectedPeer.p2pNetworkNode.node.id === peer.p2pNetworkNode.node.id) {
return true
}
}
}
async function sendMessage(message) {
/*
This function will send the message from a random picked network node
selected from the array of already connected peers.
*/
let peerIndex = Math.max(Math.round(Math.random() * thisObject.peers.length) - 1, 0)
let peer = thisObject.peers[peerIndex]
return await peer.webSocketsClient.sendMessage(message)
}
}
+13 -3
View File
@@ -18,7 +18,7 @@ exports.newNetworkModulesUserProfiles = function newNetworkModulesUserProfiles()
}
async function initialize() {
async function initialize(signingAccountChildCodeName, p2pNetworkIdentity) {
let pluginFileNames = await SA.projects.communityPlugins.utilities.plugins.getPluginFileNames(
'Governance',
@@ -65,7 +65,7 @@ exports.newNetworkModulesUserProfiles = function newNetworkModulesUserProfiles()
let signatureObject = config.signature
let web3 = new SA.nodeModules.web3()
let blockchainAccount = web3.eth.accounts.recover(signatureObject)
SA.projects.network.globals.memory.maps.USER_PROFILES_BY_BLOKCHAIN_ACCOUNT.set(blockchainAccount, userProfile)
SA.projects.network.globals.memory.maps.USER_PROFILES_BY_BLOKCHAIN_ACCOUNT.set(blockchainAccount, userProfile)
/*
If the Signing Account is for a P2P node, we will add the node to the array of available nodes at the p2p network.
*/
@@ -85,12 +85,22 @@ exports.newNetworkModulesUserProfiles = function newNetworkModulesUserProfiles()
}
if (config.webSocketsPort === undefined) {
continue
}
}
let p2pNetworkNode = SA.projects.network.modules.p2pNetworkNode.newNetworkModulesP2PNetworkNode()
p2pNetworkNode.initialize(signingAccount.signingAccountChild, userProfile, blockchainAccount)
SA.projects.network.globals.memory.arrays.P2P_NETWORK_NODES.push(p2pNetworkNode)
}
/*
Now, we will extract the information from the User Profile, specifically of our identity at the p2p network.
*/
if (
signingAccount.signingAccountChild.id === SA.secrets.map.get(signingAccountChildCodeName).signingAccountChildId
) {
p2pNetworkIdentity.node = signingAccount.signingAccountChild
p2pNetworkIdentity.blockchainAccount = blockchainAccount
p2pNetworkIdentity.userProfile = userProfile
}
}
}
}
@@ -2,16 +2,19 @@ exports.newNetworkModulesWebSocketsNetworkClient = function newNetworkModulesWeb
let thisObject = {
id: undefined,
socket: undefined,
isConnected: undefined,
host: undefined,
port: undefined,
callerRole: undefined,
p2pNetworkNode: undefined,
p2pNetworkIdentity: undefined,
onConnectionClosedCallBack: undefined,
sendMessage: sendMessage,
initialize: initialize,
finalize: finalize
}
let socketClient
let web3
let called = {}
let onMessageFunctionsMap = new Map()
@@ -19,33 +22,44 @@ exports.newNetworkModulesWebSocketsNetworkClient = function newNetworkModulesWeb
return thisObject
function finalize() {
socketClient.close()
socketClient = undefined
networkInterface = undefined
peerInterface = undefined
thisObject.socket.close()
thisObject.socket = undefined
thisObject.id = undefined
thisObject.isConnected = undefined
thisObject.host = undefined
thisObject.port = undefined
thisObject.callerRole = undefined
thisObject.p2pNetworkNode = undefined
thisObject.p2pNetworkIdentity = undefined
thisObject.onConnectionClosedCallBack = undefined
web3 = undefined
called = undefined
onMessageFunctionsMap = undefined
}
async function initialize(callerRole, p2pNetworkNode, onConnectionClosedCallBack) {
async function initialize(callerRole, p2pNetworkIdentity, p2pNetworkNode, onConnectionClosedCallBack) {
thisObject.callerRole = callerRole
thisObject.p2pNetworkIdentity = p2pNetworkIdentity
thisObject.p2pNetworkNode = p2pNetworkNode
thisObject.onConnectionClosedCallBack = onConnectionClosedCallBack
web3 = new SA.nodeModules.web3()
thisObject.id = SA.projects.foundations.utilities.miscellaneousFunctions.genereteUniqueId()
thisObject.host = JSON.parse(p2pNetworkNode.node.config).host
thisObject.port = JSON.parse(p2pNetworkNode.node.config).webSocketsPort
thisObject.host = JSON.parse(thisObject.p2pNetworkNode.node.config).host
thisObject.port = JSON.parse(thisObject.p2pNetworkNode.node.config).webSocketsPort
socketClient = new SA.nodeModules.ws('ws://' + thisObject.host + ':' + thisObject.port)
await setUpWebsocketClient(callerRole, p2pNetworkNode, onConnectionClosedCallBack)
thisObject.socket = new SA.nodeModules.ws('ws://' + thisObject.host + ':' + thisObject.port)
await setUpWebSocketClient()
console.log('Websockets Client Connected to Network Node via Web Sockets .............. Connected to ' + p2pNetworkNode.userProfile.userProfileHandle + ' -> ' + p2pNetworkNode.node.name + ' -> ' + thisObject.host + ':' + thisObject.port)
console.log('Websockets Client Connected to Network Node via Web Sockets ................ Connected to ' + thisObject.p2pNetworkNode.userProfile.userProfileHandle + ' -> ' + thisObject.p2pNetworkNode.node.name + ' -> ' + thisObject.host + ':' + thisObject.port)
thisObject.isConnected = true
}
async function setUpWebsocketClient(callerRole, p2pNetworkNode, onConnectionClosedCallBack) {
async function setUpWebSocketClient() {
return new Promise(connectToNewtwork)
@@ -53,9 +67,9 @@ exports.newNetworkModulesWebSocketsNetworkClient = function newNetworkModulesWeb
try {
socketClient.onopen = () => { onConnectionOpened() }
socketClient.onclose = () => { onConnectionClosed() }
socketClient.onerror = err => { onError(err) }
thisObject.socket.onopen = () => { onConnectionOpened() }
thisObject.socket.onclose = () => { onConnectionClosed() }
thisObject.socket.onerror = err => { onError(err) }
function onConnectionOpened() {
@@ -79,18 +93,19 @@ exports.newNetworkModulesWebSocketsNetworkClient = function newNetworkModulesWeb
it's own identity, and later we will sign it's own handle
to prove ours.
*/
socketClient.onmessage = socketMessage => { stepOneResponse(socketMessage) }
thisObject.socket.onmessage = socketMessage => { stepOneResponse(socketMessage) }
callerTimestamp = (new Date()).valueOf()
let message = {
messageType: 'Handshake',
callerRole: callerRole,
callerRole: thisObject.callerRole,
callerProfileHandle: SA.secrets.map.get(global.env.DESKTOP_APP_SIGNING_ACCOUNT).userProfileHandle,
callerTimestamp: callerTimestamp,
callerNode: JSON.stringify(thisObject.p2pNetworkIdentity.node),
step: 'One'
}
socketClient.send(JSON.stringify(message))
thisObject.socket.send(JSON.stringify(message))
}
function stepOneResponse(socketMessage) {
@@ -116,7 +131,7 @@ exports.newNetworkModulesWebSocketsNetworkClient = function newNetworkModulesWeb
We will check that the blockchain account taken from the signature matches
the one we have on record for the user profile of the Network Node we are calling.
*/
if (called.blockchainAccount !== p2pNetworkNode.blockchainAccount) {
if (called.blockchainAccount !== thisObject.p2pNetworkNode.blockchainAccount) {
console.log('[ERROR] Web Sockets Client -> stepOneResponse -> The Network Node called does not have the expected Profile Handle.')
reject()
return
@@ -138,7 +153,7 @@ exports.newNetworkModulesWebSocketsNetworkClient = function newNetworkModulesWeb
We will check that the Network Node that responded has the same User Profile Handle
that we have on record, otherwise something is wrong and we should not proceed.
*/
if (signedMessage.calledProfileHandle !== p2pNetworkNode.userProfile.userProfileHandle) {
if (signedMessage.calledProfileHandle !== thisObject.p2pNetworkNode.userProfile.userProfileHandle) {
console.log('[ERROR] Web Sockets Client -> stepOneResponse -> The Network Node called does not have the expected Profile Handle.')
reject()
return
@@ -175,7 +190,7 @@ exports.newNetworkModulesWebSocketsNetworkClient = function newNetworkModulesWeb
Here we will sign a message with the Network Node profile
handle and timestamp to prove our own identity.
*/
socketClient.onmessage = socketMessage => { stepTwoResponse(socketMessage) }
thisObject.socket.onmessage = socketMessage => { stepTwoResponse(socketMessage) }
let signature = web3.eth.accounts.sign(JSON.stringify(signedMessage), SA.secrets.map.get(global.env.DESKTOP_APP_SIGNING_ACCOUNT).privateKey)
@@ -184,7 +199,7 @@ exports.newNetworkModulesWebSocketsNetworkClient = function newNetworkModulesWeb
signature: JSON.stringify(signature),
step: 'Two'
}
socketClient.send(JSON.stringify(message))
thisObject.socket.send(JSON.stringify(message))
}
function stepTwoResponse(socketMessage) {
@@ -200,7 +215,7 @@ exports.newNetworkModulesWebSocketsNetworkClient = function newNetworkModulesWeb
Network Node and from now on, all response messages will be received
at this following function.
*/
socketClient.onmessage = socketMessage => { onMenssage(socketMessage) }
thisObject.socket.onmessage = socketMessage => { onMenssage(socketMessage) }
resolve()
}
}
@@ -208,10 +223,10 @@ exports.newNetworkModulesWebSocketsNetworkClient = function newNetworkModulesWeb
function onConnectionClosed() {
if (thisObject.isConnected === true) {
console.log('Websockets Client Connected to Network Node via Web Sockets .............. Disconnected from ' + p2pNetworkNode.userProfile.userProfileHandle + ' -> ' + p2pNetworkNode.node.name + ' -> ' + thisObject.host + ':' + thisObject.port)
console.log('Websockets Client Disconnected from Network Node via Web Sockets ......... Disconnected from ' + thisObject.p2pNetworkNode.userProfile.userProfileHandle + ' -> ' + thisObject.p2pNetworkNode.node.name + ' -> ' + thisObject.host + ':' + thisObject.port)
}
if (onConnectionClosedCallBack !== undefined) {
onConnectionClosedCallBack(thisObject.id)
if (thisObject.onConnectionClosedCallBack !== undefined) {
thisObject.onConnectionClosedCallBack(thisObject.id)
}
thisObject.isConnected = false
}
@@ -229,7 +244,7 @@ exports.newNetworkModulesWebSocketsNetworkClient = function newNetworkModulesWeb
}
} catch (err) {
console.log('[ERROR] Web Sockets Client -> setUpWebsocketClient -> err.stack = ' + err.stack)
console.log('[ERROR] Web Sockets Client -> setUpWebSocketClient -> err.stack = ' + err.stack)
}
}
@@ -241,7 +256,7 @@ exports.newNetworkModulesWebSocketsNetworkClient = function newNetworkModulesWeb
function sendSocketMessage(resolve, reject) {
if (socketClient.readyState !== 1) { // 1 means connected and ready.
if (thisObject.socket.readyState !== 1) { // 1 means connected and ready.
console.log('[ERROR] Web Sockets Client -> sendMessage -> Cannot send message while connection is closed.')
reject('Websockets Connection Not Ready.')
return
@@ -253,7 +268,7 @@ exports.newNetworkModulesWebSocketsNetworkClient = function newNetworkModulesWeb
payload: message
}
onMessageFunctionsMap.set(socketMessage.messageId, onMenssageFunction)
socketClient.send(
thisObject.socket.send(
JSON.stringify(socketMessage)
)
@@ -279,8 +294,44 @@ exports.newNetworkModulesWebSocketsNetworkClient = function newNetworkModulesWeb
/*
We get the function that is going to resolve or reject the promise given.
*/
onMenssageFunction = onMessageFunctionsMap.get(response.messageId)
onMessageFunctionsMap.delete(response.messageId)
onMenssageFunction(response)
let onMenssageFunction = onMessageFunctionsMap.get(response.messageId)
if (onMenssageFunction !== undefined) {
/*
The message received is a response to a message sent.
*/
onMessageFunctionsMap.delete(response.messageId)
onMenssageFunction(response)
} else {
/*
The message received is a not response to a message sent.
*/
let messageHeader
try {
messageHeader = JSON.parse(message)
} catch (err) {
console.log('[ERROR] Web Sockets Client -> onMenssage -> message = ' + message)
console.log('[ERROR] Web Sockets Client -> onMenssage -> err.stack = ' + err.stack)
thisObject.socket.close()
return
}
switch (thisObject.callerRole) {
case 'Network Client': {
/*
This is the use case of a network client receiving a notification of
somethinig that happened at the network that is relevant to itself.
*/
break
}
case 'Network Peer': {
/*
No use cases so far were a Network Peer would send a message through an
incomming websockets connection, without having received a request first.
*/
break
}
}
}
}
}
+6
View File
@@ -1419,6 +1419,12 @@
"propertyName": "p2pNetworkPeers",
"functionName": "newNetworkModulesP2PNetworkPeers",
"fileName": "P2PNetworkPeers.js"
},
{
"name": "P2P Network Client",
"propertyName": "p2pNetworkClient",
"functionName": "newNetworkModulesP2PNetworkClient",
"fileName": "P2PNetworkClient.js"
}
],
"utilities": [
@@ -14,7 +14,6 @@ exports.newSocialTradingModulesSocialGraph = function newSocialTradingModulesSoc
no need to ask it to a network node.
*/
let thisObject = {
userProfiles: undefined,
initialize: initialize,
finalize: finalize
}
@@ -26,7 +25,6 @@ exports.newSocialTradingModulesSocialGraph = function newSocialTradingModulesSoc
}
async function initialize() {
thisObject.userProfiles = SA.projects.network.modules.userProfiles.newNetworkModulesUserProfiles()
await thisObject.userProfiles.initialize()
}
}
@@ -58,11 +58,11 @@ exports.newSocialTradingModulesWebAppInterface = function newSocialTradingModule
response = {
result: 'Ok',
message: 'Web App Interface Query Processed.',
data: await DK.desktopApp.webSocketsClient.sendMessage(JSON.stringify(messageHeader))
data: await DK.desktopApp.p2pNetworkPeers.sendMessage(JSON.stringify(messageHeader))
}
} else {
let events = await DK.desktopApp.webSocketsClient.sendMessage(JSON.stringify(messageHeader))
let events = await DK.desktopApp.p2pNetworkPeers.sendMessage(JSON.stringify(messageHeader))
for (let i = 0; i < events.length; i++) {
let event = events[i]
if (event.eventType === SA.projects.socialTrading.globals.eventTypes.NEW_USER_POST) {
@@ -8,9 +8,9 @@ exports.newSocialTradingModulesPeerInterface = function newSocialTradingModulesP
websockets interface.
*/
let thisObject = {
messageReceived: messageReceived,
initialize: initialize,
finalize: finalize,
run: run
finalize: finalize
}
return thisObject
@@ -22,8 +22,130 @@ exports.newSocialTradingModulesPeerInterface = function newSocialTradingModulesP
function initialize() {
}
async function messageReceived(message) {
let messageHeader
try {
messageHeader = JSON.parse(message)
} catch (err) {
let response = {
result: 'Error',
message: 'Peer Interface message Not Correct JSON Format.'
}
return response
}
function run() {
if (messageHeader.requestType === undefined) {
let response = {
result: 'Error',
message: 'Peer Interface requestType Not Provided.'
}
return response
}
if (messageHeader.requestType !== 'Event' && messageHeader.requestType !== 'Query') {
let response = {
result: 'Error',
message: 'Peer Interface requestType Not Supported.'
}
return response
}
switch (messageHeader.requestType) {
case 'Event': {
return await eventReceived(messageHeader.eventMessage)
}
case 'Query': {
let response = {
result: 'Error',
message: 'Peer Interface requestType Query Not Supported.'
}
return response
}
}
}
async function eventReceived(eventMessage) {
/*
We expect here a JSON string with some or all of the following properties:
{
"eventId": "a8de78f0-c3e4-4a2a-b7e8-f659073969db",
"eventType": 10,
"emitterUserProfileId": "a8de78f0-c3e4-4a2a-b7e8-f659073969db",
"targetUserProfileId": "a8de78f0-c3e4-4a2a-b7e8-f659073969db",
"emitterBotProfileId": "a8de78f0-c3e4-4a2a-b7e8-f659073969db",
"targetBBotProfileId": "a8de78f0-c3e4-4a2a-b7e8-f659073969db",
"emitterPostHash": "a8de78f0-c3e4-4a2a-b7e8-f659073969db",
"targetPostHash": "a8de78f0-c3e4-4a2a-b7e8-f659073969db",
"timestamp": 124234234234,
"botAsset": "BTC",
"botExchange": "Binance",
"botEnabled": true
}
*/
let eventReceived
try {
eventReceived = JSON.parse(eventMessage)
} catch (err) {
let response = {
result: 'Error',
message: 'Peer Interface eventMessage Not Correct JSON Format.'
}
return response
}
/*
We will not accept events that don't have an eventId.
*/
if (eventReceived.eventId === undefined) {
let response = {
result: 'Error',
message: 'eventId Not Provided.'
}
return response
}
/*
We will not accept events that have already been processed.
*/
if (NT.projects.network.globals.memory.maps.EVENTS.get(eventReceived.eventId) !== undefined) {
let response = {
result: 'Ok',
message: 'Peer Interface Event Already Exists.'
}
return response
}
/*
Here we will process the event and change the state of the Social Graph.
*/
try {
let event = NT.projects.socialTrading.modules.event.newSocialTradingModulesEvent()
event.initialize(eventReceived)
NT.projects.network.globals.memory.maps.EVENTS.set(eventReceived.eventId, event)
NT.projects.network.globals.memory.arrays.EVENTS.push(event)
let response = {
result: 'Ok',
message: 'Peer Interface Event Processed.'
}
return response
} catch (err) {
/*
Any exception that happens while trying to change the state of the Social Graph,
will be returned to the caller without doing anything else here.
*/
if (err.stack !== undefined) {
console.log('[ERROR] Peer Interface -> err.stack = ' + err.stack)
}
let errorMessage = err.message
if (errorMessage === undefined) { errorMessage = err }
let response = {
result: 'Error',
message: 'Peer Interface ' + errorMessage
}
return response
}
}
}
@@ -9,7 +9,7 @@ exports.newNetworkModulesSocialGraph = function newNetworkModulesSocialGraph() {
their posts.
*/
let thisObject = {
userProfiles: undefined,
/* Framework Functions */
initialize: initialize,
finalize: finalize
@@ -22,7 +22,6 @@ exports.newNetworkModulesSocialGraph = function newNetworkModulesSocialGraph() {
}
async function initialize() {
thisObject.userProfiles = SA.projects.network.modules.userProfiles.newNetworkModulesUserProfiles()
await thisObject.userProfiles.initialize()
}
}