Merge pull request #2622 from Luis-Fernando-Molina/develop

Contribution: Governance System, bug fixes for web3 calls.
This commit is contained in:
Luis Fernando Molina authored and GitHub committed 2021-11-14 09:03:02 -04:00
commit 1641fa3926
22 files changed
+469 -85

No files matched your search

+1
View File
@@ -17,6 +17,7 @@ exports.newEnvironment = function () {
DESKTOP_WEB_SOCKETS_INTERFACE_HOST: 'localhost',
PLATFORM_HTTP_INTERFACE_PORT: 34248,
DESKTOP_HTTP_INTERFACE_PORT: 33248,
NETWORK_HTTP_INTERFACE_PORT: 31248,
PATH_TO_DATA_STORAGE: path.join(basePath, './Platform/My-Data-Storage'),
PATH_TO_PROJECTS: path.join(basePath, './Projects'),
PATH_TO_LOG_FILES: path.join(basePath, './Platform/My-Log-Files'),
+7
View File
@@ -6,6 +6,7 @@ exports.newNetworkNode = function newNetworkNode() {
p2pNetworkPeers: undefined,
p2pNetworkNode: undefined,
webSocketsInterface: undefined,
httpInterface: undefined,
socialGraphService: undefined,
storage: undefined,
run: run
@@ -65,6 +66,12 @@ exports.newNetworkNode = function newNetworkNode() {
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)
/*
Other Network Nodes and Client Apps will communicate with this Network Node via it's HTTP Interface.
*/
thisObject.httpInterface = NT.projects.network.modules.httpInterface.newNetworkModulesHttpInterface()
thisObject.httpInterface.initialize()
console.log('Network Node Http Interface .................................................. Listening at port ' + JSON.parse(NT.networkNode.p2pNetworkNode.node.config).webPort)
}
}
}
+1
View File
@@ -47,6 +47,7 @@ exports.newNetworkRoot = function newNetworkRoot() {
fs: require('fs'),
path: require('path'),
util: require('util'),
http: require('http'),
nodeFetch: require('node-fetch'),
web3: require('web3'),
ws: require('ws'),
+6 -3
View File
@@ -90,7 +90,7 @@ exports.newWeb3Server = function newWeb3Server() {
let balance
let ABI = [{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_value","type":"uint256"}],"name":"approve","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"unpause","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"account","type":"address"},{"name":"amount","type":"uint256"}],"name":"mint","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_value","type":"uint256"}],"name":"burn","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"paused","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_subtractedValue","type":"uint256"}],"name":"decreaseApproval","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"balanceOf","outputs":[{"name":"balance","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"listAddress","type":"address"},{"name":"isBlackListed","type":"bool"}],"name":"blackListAddress","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"pause","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transfer","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_addedValue","type":"uint256"}],"name":"increaseApproval","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"},{"name":"_spender","type":"address"}],"name":"allowance","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_name","type":"string"},{"name":"_symbol","type":"string"},{"name":"_decimals","type":"uint256"},{"name":"_supply","type":"uint256"},{"name":"tokenOwner","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Mint","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"burner","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Burn","type":"event"},{"anonymous":false,"inputs":[],"name":"Pause","type":"event"},{"anonymous":false,"inputs":[],"name":"Unpause","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"previousOwner","type":"address"},{"indexed":true,"name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"blackListed","type":"address"},{"indexed":false,"name":"value","type":"bool"}],"name":"Blacklist","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"owner","type":"address"},{"indexed":true,"name":"spender","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"value","type":"uint256"}]Line truncated
let ABI = [{ "constant": true, "inputs": [], "name": "name", "outputs": [{ "name": "", "type": "string" }], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [{ "name": "_spender", "type": "address" }, { "name": "_value", "type": "uint256" }], "name": "approve", "outputs": [{ "name": "", "type": "bool" }], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [], "name": "totalSupply", "outputs": [{ "name": "", "type": "uint256" }], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [{ "name": "_from", "type": "address" }, { "name": "_to", "type": "address" }, { "name": "_value", "type": "uint256" }], "name": "transferFrom", "outputs": [{ "name": "", "type": "bool" }], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [], "name": "decimals", "outputs": [{ "name": "", "type": "uint256" }], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [], "name": "unpause", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [{ "name": "account", "type": "address" }, { "name": "amount", "type": "uint256" }], "name": "mint", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [{ "name": "_value", "type": "uint256" }], "name": "burn", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [], "name": "paused", "outputs": [{ "name": "", "type": "bool" }], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [{ "name": "_spender", "type": "address" }, { "name": "_subtractedValue", "type": "uint256" }], "name": "decreaseApproval", "outputs": [{ "name": "success", "type": "bool" }], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [{ "name": "_owner", "type": "address" }], "name": "balanceOf", "outputs": [{ "name": "balance", "type": "uint256" }], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [{ "name": "listAddress", "type": "address" }, { "name": "isBlackListed", "type": "bool" }], "name": "blackListAddress", "outputs": [{ "name": "success", "type": "bool" }], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [], "name": "pause", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [], "name": "owner", "outputs": [{ "name": "", "type": "address" }], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "symbol", "outputs": [{ "name": "", "type": "string" }], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [{ "name": "_to", "type": "address" }, { "name": "_value", "type": "uint256" }], "name": "transfer", "outputs": [{ "name": "", "type": "bool" }], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [{ "name": "_spender", "type": "address" }, { "name": "_addedValue", "type": "uint256" }], "name": "increaseApproval", "outputs": [{ "name": "success", "type": "bool" }], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [{ "name": "_owner", "type": "address" }, { "name": "_spender", "type": "address" }], "name": "allowance", "outputs": [{ "name": "", "type": "uint256" }], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [{ "name": "newOwner", "type": "address" }], "name": "transferOwnership", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "inputs": [{ "name": "_name", "type": "string" }, { "name": "_symbol", "type": "string" }, { "name": "_decimals", "type": "uint256" }, { "name": "_supply", "type": "uint256" }, { "name": "tokenOwner", "type": "address" }], "payable": false, "stateMutability": "nonpayable", "type": "constructor" }, { "anonymous": false, "inputs": [{ "indexed": true, "name": "from", "type": "address" }, { "indexed": true, "name": "to", "type": "address" }, { "indexed": false, "name": "value", "type": "uint256" }], "name": "Mint", "type": "event" }, { "anonymous": false, "inputs": [{ "indexed": true, "name": "burner", "type": "address" }, { "indexed": false, "name": "value", "type": "uint256" }], "name": "Burn", "type": "event" }, { "anonymous": false, "inputs": [], "name": "Pause", "type": "event" }, { "anonymous": false, "inputs": [], "name": "Unpause", "type": "event" }, { "anonymous": false, "inputs": [{ "indexed": true, "name": "previousOwner", "type": "address" }, { "indexed": true, "name": "newOwner", "tLine truncated
const contractInst = new web3.eth.Contract(ABI, contractAddress)
@@ -101,8 +101,11 @@ exports.newWeb3Server = function newWeb3Server() {
await getBalance()
return balance
return {
walletAddress: walletAddress,
balance: balance,
result: 'Ok'
}
}
async function getWalletBalances(host, port, interface, walletDefinition) {
Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

@@ -24,7 +24,7 @@ function newFoundationsTopSpace() {
logoImage = new Image()
loadImage('superalgos-header-background', backgroundImage)
loadImage('sa-beta12-logo-horiz-dark', logoImage)
loadImage('sa-v10-logo-horiz-dark', logoImage)
function loadImage(name, image) {
const PATH = 'Images/'
@@ -17236,7 +17236,7 @@
"signingAccountChild": {
"type": "P2P Network Node",
"name": "P2P Network Node # 1",
"config": "{\n \"codeName\": \"P2P-Network-Node-1\",\n \"host\": \"localhost\",\n \"webSocketsPort\": \"18042\"\n}",
"config": "{\n \"codeName\": \"P2P-Network-Node-1\",\n \"host\": \"localhost\",\n \"webSocketsPort\": \"18042\",\n \"webPort\": \"31248\"\n}",
"project": "Governance",
"id": "bb0f0417-9dfb-47a3-941f-dcfa82fbaea1",
"savedPayload": {
@@ -17292,7 +17292,7 @@
"signingAccountChild": {
"type": "P2P Network Node",
"name": "P2P Network Node # 2",
"config": "{\n \"codeName\": \"P2P-Network-Node-2\",\n \"host\": \"localhost\",\n \"webSocketsPort\": \"18043\"\n}",
"config": "{\n \"codeName\": \"P2P-Network-Node-2\",\n \"host\": \"localhost\",\n \"webSocketsPort\": \"18043\",\n \"webPort\": \"31248\"\n}",
"project": "Governance",
"id": "76fa8a24-9ab4-4eaf-82f2-458ba557b204",
"savedPayload": {
@@ -17348,7 +17348,7 @@
"signingAccountChild": {
"type": "P2P Network Node",
"name": "P2P Network Node # 3",
"config": "{\n \"codeName\": \"P2P-Network-Node-3\",\n \"host\": \"localhost\",\n \"webSocketsPort\": \"18044\"\n}",
"config": "{\n \"codeName\": \"P2P-Network-Node-3\",\n \"host\": \"localhost\",\n \"webSocketsPort\": \"18044\",\n \"webPort\": \"31248\"\n}",
"project": "Governance",
"id": "297e57c2-3c1a-4170-b710-d2705804205b",
"savedPayload": {
@@ -25,7 +25,7 @@
"config": true
},
"initialValues": {
"config": "{ \n\"codeName\": \"localhost\", \n\"host\": \"localhost\", \n\"webSocketsPort\": \"18042\"\n}"
"config": "{ \n\"codeName\": \"localhost\", \n\"host\": \"localhost\", \n\"webPort\": \"31248\", \n\"webSocketsPort\": \"18042\"\n}"
},
"addLeftIcons": true,
"level": 1,
@@ -484,10 +484,15 @@ function newGovernanceUserProfileSpace() {
console.log('[WARN] Error fetching blockchain tokens of user profile ' + userProfile.name)
userProfile.payload.blockchainTokens = undefined
} else {
let commandResponse = JSON.parse(data)
if (commandResponse.result !== "Ok") {
console.log('[WARN] Web3 Error fetching blockchain tokens of user profile ' + userProfile.name)
return
}
userProfile.payload.uiObject.setInfoMessage('Blockchain Balance Successfully Loaded.',
UI.projects.governance.globals.designer.SET_INFO_COUNTER_FACTOR
)
userProfile.payload.blockchainTokens = Number(data)
userProfile.payload.blockchainTokens = Number(commandResponse.balance)
console.log('[INFO] SA Balance of ' + userProfile.name + ' is ', userProfile.payload.blockchainTokens)
userProfile.payload.reputation = Math.min(reputationByAddress.get(blockchainAccount.toLowerCase()) | 0, userProfile.payload.blockchainTokens)
console.log('[INFO] Reputation of ' + userProfile.name + ' is ', userProfile.payload.reputation)
@@ -514,10 +519,15 @@ function newGovernanceUserProfileSpace() {
console.log('[WARN] Error fetching liquidity tokens for asset ' + asset + ' of user profile ' + userProfile.name)
userProfile.payload.blockchainTokens = undefined
} else {
let commandResponse = JSON.parse(data)
if (commandResponse.result !== "Ok") {
console.log('[WARN] Web3 Error fetching liquidity tokens for asset ' + asset + ' of user profile ' + userProfile.name)
return
}
userProfile.payload.uiObject.setInfoMessage('Pancake Balance Successfully Loaded for asset ' + asset,
UI.projects.governance.globals.designer.SET_INFO_COUNTER_FACTOR
)
userProfile.payload.liquidityTokens[asset] = Number(data)
userProfile.payload.liquidityTokens[asset] = Number(commandResponse.balance)
console.log('[INFO] Liquidity of ' + userProfile.name + ' for asset ' + asset + ' is ', userProfile.payload.liquidityTokens[asset])
}
}
+4 -2
View File
@@ -4,12 +4,14 @@ exports.newNetworkGlobalsMemory = function () {
*/
let thisObject = {
maps: {
EVENTS: new Map() // This is the registry of all events received that prevents processing them more than once.
EVENTS: new Map(), // This is the registry of all events received that prevents processing them more than once.
SIGNALS: new Map() // This is the registry of all signals received that prevents processing them more than once.
},
arrays: {
NETWORK_CLIENTS: [], // These are the Network Clients connected to this Network Node ordered by Ranking.
NETWORK_PEERS: [], // These are the Network Peers connected to this Network Node ordered by Ranking.
EVENTS: [] // This is the registry of all events in order that prevents ordering them more than once.
EVENTS: [], // This is the registry of all events in order that prevents ordering them more than once.
SIGNALS: [] // This is the registry of all signals in order that prevents ordering them more than once.
}
}
@@ -0,0 +1,52 @@
exports.newNetworkModulesHttpInterface = function newNetworkModulesHttpInterface() {
/*
This module represent the HTTP API of the
NNetwork Node. All HTTP request are processed
by this module.
*/
let thisObject = {
initialize: initialize,
finalize: finalize
}
return thisObject
function finalize() {
}
function initialize() {
let port = JSON.parse(NT.networkNode.p2pNetworkNode.node.config).webPort
/*
We will create an HTTP Server and leave it running forever.
*/
SA.nodeModules.http.createServer(onHttpRequest).listen(port)
}
async function onHttpRequest(httpRequest, httpResponse) {
try {
let requestPathAndParameters = httpRequest.url.split('?') // Remove version information
let requestPath = requestPathAndParameters[0].split('/')
let endpointOrFile = requestPath[1]
switch (endpointOrFile) {
case 'Signal':
{
let message = requestPath[2]
let response = await thisObject.clientInterface.messageReceived(message)
SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(response), httpResponse)
}
break
case 'Stats':
{
SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify([]), httpResponse)
}
break
default:
{
}
}
} catch (err) {
console.log(err.stack)
}
}
}
+31 -1
View File
@@ -1389,6 +1389,12 @@
"propertyName": "webSocketsInterface",
"functionName": "newNetworkModulesWebSocketsInterface",
"fileName": "WebSocketsInterface.js"
},
{
"name": "Http Interface",
"propertyName": "httpInterface",
"functionName": "newNetworkModulesHttpInterface",
"fileName": "HttpInterface.js"
}
],
"utilities": []
@@ -1528,6 +1534,12 @@
"functionName": "newSocialTradingModulesEvent",
"fileName": "Event.js"
},
{
"name": "Signal",
"propertyName": "signal",
"functionName": "newSocialTradingModulesSignal",
"fileName": "Signal.js"
},
{
"name": "Client Interface",
"propertyName": "clientInterface",
@@ -1595,6 +1607,24 @@
"propertyName": "eventTypes",
"functionName": "newSocialTradingGlobalsEventTypes",
"fileName": "EventTypes.js"
},
{
"name": "Signal Types",
"propertyName": "eventTypes",
"functionName": "newSocialTradingGlobalsSignalTypes",
"fileName": "SignalTypes.js"
},
{
"name": "Post Types",
"propertyName": "postTypes",
"functionName": "newSocialTradingGlobalsPostTypes",
"fileName": "PostTypes.js"
},
{
"name": "Reaction Types",
"propertyName": "reactionTypes",
"functionName": "newSocialTradingGlobalsReactionTypes",
"fileName": "ReactionTypes.js"
}
]
},
@@ -1605,7 +1635,7 @@
"name": "Http Interface",
"propertyName": "httpInterface",
"functionName": "newDesktopModulesHttpInterface",
"fileName": "httpInterface.js"
"fileName": "HttpInterface.js"
},
{
"name": "Web Sockets Interface",
@@ -1,15 +1,16 @@
exports.newSocialTradingModulesClientInterface = function newSocialTradingModulesClientInterface() {
/*
This module represents the Interface the Network Node have
with Network Clients connected to it. There are two things
with Network Clients connected to it. There are 3 things
Network Clients can do with this Network Node:
* Send an Event that happened at the Network Client to the Network.
* Make a Query to the Network Node for info needed at the Network Client.
* Send an Event that happened at the Network Client to the Network.
* Send a Signal that needs to be distributed.
This interface is one layer above the communication protocol interface
where actual messages are received through, like for instance the
websockets interface.
websockets interface or http interface.
*/
let thisObject = {
messageReceived: messageReceived,
@@ -47,7 +48,7 @@ exports.newSocialTradingModulesClientInterface = function newSocialTradingModule
return response
}
if (messageHeader.requestType !== 'Event' && messageHeader.requestType !== 'Query') {
if (messageHeader.requestType !== 'Event' && messageHeader.requestType !== 'Query' && messageHeader.requestType !== 'Signal') {
let response = {
result: 'Error',
message: 'Client Interface requestType Not Supported.'
@@ -56,12 +57,96 @@ exports.newSocialTradingModulesClientInterface = function newSocialTradingModule
}
switch (messageHeader.requestType) {
case 'Event': {
return await eventReceived(messageHeader.eventMessage, userProfile)
}
case 'Query': {
return await queryReceived(messageHeader.queryMessage, userProfile)
}
case 'Event': {
return await eventReceived(messageHeader.eventMessage, userProfile)
}
case 'Signal': {
return await signalReceived(messageHeader.eventMessage)
}
}
}
async function queryReceived(queryMessage, userProfile) {
/*
We expect here a JSON string with some or all of the following properties:
{
"queryType": 10,
"emitterUserProfileId": "a8de78f0-c3e4-4a2a-b7e8-f659073969db",
"targetUserProfileId": "a8de78f0-c3e4-4a2a-b7e8-f659073969db",
"emitterUserProfileHandle": "Luis-Fernando-Molina",
"targetUserProfileHandle": "Luis-Fernando-Molina",
"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,
"initialIndex": 35,
"amountRequested": 50,
"direction": "Past"
}
*/
let queryReceived
try {
queryReceived = JSON.parse(queryMessage)
} catch (err) {
let response = {
result: 'Error',
message: 'Client Interface queryMessage Not Correct JSON Format.'
}
return response
}
/*
At the Client Interface, queries need to be emitted by the same userProfile that is
connected at the Network Node.
*/
if (queryReceived.emitterUserProfileId !== userProfile.userProfileId) {
let response = {
result: 'Error',
message: 'Client Interface emitterUserProfileId !== userProfileId Connected to Network Node.'
}
return response
}
/*
Here we will process the query. This does not change the state of the Social Graph.
*/
try {
let query = NT.projects.socialTrading.modules.query.newSocialTradingModulesQuery()
query.initialize(queryReceived)
// console.log((new Date()).toISOString(), '- Client Interface', '- Query Message Received', queryMessage)
let response = {
result: 'Ok',
message: 'Client Interface Query Processed.',
data: query.execute()
}
// console.log((new Date()).toISOString(), '- Client Interface', '- Query Response Sent', JSON.stringify(response))
return response
} catch (err) {
/*
Any exception that happens while trying to execute the query.
*/
if (err.stack !== undefined) {
console.log('[ERROR] Client Interface -> err.stack = ' + err.stack)
}
let errorMessage = err.message
if (errorMessage === undefined) { errorMessage = err }
let response = {
result: 'Error',
message: 'Client Interface ' + errorMessage
}
return response
}
}
@@ -160,16 +245,15 @@ exports.newSocialTradingModulesClientInterface = function newSocialTradingModule
}
}
async function queryReceived(queryMessage, userProfile) {
async function signalReceived(signalMessage) {
/*
We expect here a JSON string with some or all of the following properties:
{
"queryType": 10,
"signalId": "a8de78f0-c3e4-4a2a-b7e8-f659073969db",
"signalType": 10,
"emitterUserProfileId": "a8de78f0-c3e4-4a2a-b7e8-f659073969db",
"targetUserProfileId": "a8de78f0-c3e4-4a2a-b7e8-f659073969db",
"emitterUserProfileHandle": "Luis-Fernando-Molina",
"targetUserProfileHandle": "Luis-Fernando-Molina",
"emitterBotProfileId": "a8de78f0-c3e4-4a2a-b7e8-f659073969db",
"targetBBotProfileId": "a8de78f0-c3e4-4a2a-b7e8-f659073969db",
"emitterPostHash": "a8de78f0-c3e4-4a2a-b7e8-f659073969db",
@@ -177,56 +261,60 @@ exports.newSocialTradingModulesClientInterface = function newSocialTradingModule
"timestamp": 124234234234,
"botAsset": "BTC",
"botExchange": "Binance",
"botEnabled": true,
"initialIndex": 35,
"amountRequested": 50,
"direction": "Past"
"botEnabled": true
}
*/
let queryReceived
let signalReceived
try {
queryReceived = JSON.parse(queryMessage)
signalReceived = JSON.parse(signalMessage)
} catch (err) {
let response = {
result: 'Error',
message: 'Client Interface queryMessage Not Correct JSON Format.'
message: 'Client Interface signalMessage Not Correct JSON Format.'
}
return response
}
/*
At the Client Interface, queries need to be emitted by the same userProfile that is
connected at the Network Node.
We will not accept signals that don't have an signalId.
*/
if (queryReceived.emitterUserProfileId !== userProfile.userProfileId) {
if (signalReceived.signalId === undefined) {
let response = {
result: 'Error',
message: 'Client Interface emitterUserProfileId !== userProfileId Connected to Network Node.'
message: 'signalId Not Provided.'
}
return response
}
/*
Here we will process the query. This does not change the state of the Social Graph.
We will not accept signals that have already been processed.
*/
if (NT.projects.network.globals.memory.maps.SIGNALS.get(signalReceived.signalId) !== undefined) {
let response = {
result: 'Error',
message: 'Client Interface Signal Already Exists.'
}
return response
}
/*
Here we will process the signal and change the state of the Social Graph.
*/
try {
let query = NT.projects.socialTrading.modules.query.newSocialTradingModulesQuery()
query.initialize(queryReceived)
// console.log((new Date()).toISOString(), '- Client Interface', '- Query Message Received', queryMessage)
let signal = NT.projects.socialTrading.modules.signal.newSocialTradingModulesSignal()
signal.initialize(signalReceived)
NT.projects.network.globals.memory.maps.SIGNALS.set(signalReceived.eventId, signal)
NT.projects.network.globals.memory.arrays.SIGNALS.push(signal)
let response = {
result: 'Ok',
message: 'Client Interface Query Processed.',
data: query.execute()
message: 'Client Interface Signal Processed.'
}
// console.log((new Date()).toISOString(), '- Client Interface', '- Query Response Sent', JSON.stringify(response))
return response
} catch (err) {
/*
Any exception that happens while trying to execute the query.
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] Client Interface -> err.stack = ' + err.stack)
+6 -7
View File
@@ -1,8 +1,7 @@
exports.newSocialTradingModulesEvent = function newSocialTradingModulesEvent() {
/*
An Event is anything that happens system wide that
needs to be delivered to relevant entities via
the Superalgos Network.
An Event is an action taken by users that triggers a
change at the social graph.
An Event (in contrast to a Query) produces a change
on the state of the social graph.
@@ -115,7 +114,7 @@ exports.newSocialTradingModulesEvent = function newSocialTradingModulesEvent() {
function postingEvents() {
/*
Is is related to Posting?
Is it related to Posting?
*/
if (
thisObject.eventType === SA.projects.socialTrading.globals.eventTypes.NEW_USER_POST ||
@@ -202,7 +201,7 @@ exports.newSocialTradingModulesEvent = function newSocialTradingModulesEvent() {
function followingEvents() {
/*
Is is a following?
Is it a following?
*/
if (
thisObject.eventType === SA.projects.socialTrading.globals.eventTypes.FOLLOW_USER_PROFILE ||
@@ -292,7 +291,7 @@ exports.newSocialTradingModulesEvent = function newSocialTradingModulesEvent() {
function reactionEvents() {
/*
Is is a Reaction?
Is it a Reaction?
*/
let targetPost
@@ -346,7 +345,7 @@ exports.newSocialTradingModulesEvent = function newSocialTradingModulesEvent() {
function botEvents() {
/*
Is is a Bot?
Is it a Bot?
*/
if (
thisObject.eventType === SA.projects.socialTrading.globals.eventTypes.ADD_BOT ||
@@ -72,6 +72,8 @@ exports.newSocialTradingModulesQueriesPostReplies = function newSocialTradingMod
targetPostHash: post.targetPostHash,
postType: post.postType,
timestamp: post.timestamp,
signalType: post.signalType,
signalData: post.signalData,
repliesCount: post.replies.size,
reactions: Array.from(post.reactions)
}
@@ -67,6 +67,8 @@ exports.newSocialTradingModulesQueriesUserProfileStats = function newSocialTradi
targetPostHash: post.targetPostHash,
postType: post.postType,
timestamp: post.timestamp,
signalType: post.signalType,
signalData: post.signalData,
repliesCount: post.replies.size,
reactions: Array.from(post.reactions)
}
@@ -0,0 +1,153 @@
exports.newSocialTradingModulesSignal = function newSocialTradingModulesSignal() {
/*
A Signal is an action taken by a bot that needs to be
delivered to all the followers of that bot respecting
the rule to deliver it fist to the bots belonging to
users with the highers ranking.
An Signal is attached to the Social Graph as a new post
from the Bot producing the signal.
*/
let thisObject = {
/* Unique Key */
signalId: undefined,
/* Referenced Entities Unique Keys */
emitterUserProfileId: undefined,
targetUserProfileId: undefined,
emitterBotProfileId: undefined,
targetBotProfileId: undefined,
emitterPostHash: undefined,
targetPostHash: undefined,
/* Signal Unique Properties */
signalType: undefined,
signalData: undefined,
timestamp: undefined,
/* Bot Related Properties */
botAsset: undefined,
botExchange: undefined,
botEnabled: undefined,
/* Framework Functions */
initialize: initialize,
finalize: finalize
}
return thisObject
function finalize() {
}
function initialize(signalReceived) {
/*
Store the message properties into this object properties.
*/
thisObject.signalId = signalReceived.signalId
thisObject.emitterUserProfileId = signalReceived.emitterUserProfileId
thisObject.targetUserProfileId = signalReceived.targetUserProfileId
thisObject.emitterBotProfileId = signalReceived.emitterBotProfileId
thisObject.targetBotProfileId = signalReceived.targetBotProfileId
thisObject.emitterPostHash = signalReceived.emitterPostHash
thisObject.targetPostHash = signalReceived.targetPostHash
thisObject.signalType = signalReceived.signalType
thisObject.signalData = signalReceived.signalData
thisObject.timestamp = signalReceived.timestamp
thisObject.botAsset = signalReceived.botAsset
thisObject.botExchange = signalReceived.botExchange
thisObject.botEnabled = signalReceived.botEnabled
/*
Local Variables
*/
let emitterUserProfile
let targetUserProfile
let emitterBotProfile
let targetBotProfile
/*
Validate Emitter User Profile.
*/
if (thisObject.emitterUserProfileId === undefined) {
throw ('Emitter User Profile Id Not Provided.')
}
emitterUserProfile = SA.projects.network.globals.memory.maps.USER_PROFILES_BY_ID.get(thisObject.emitterUserProfileId)
if (emitterUserProfile === undefined) {
throw ('Emitter User Profile Not Found.')
}
/*
Validate Target User Profile.
*/
if (thisObject.targetUserProfileId !== undefined) {
targetUserProfile = SA.projects.network.globals.memory.maps.USER_PROFILES_BY_ID.get(thisObject.targetUserProfileId)
if (targetUserProfile === undefined) {
throw ('Target User Profile Not Found.')
}
}
/*
Validate Emitter Bot Profile.
*/
if (thisObject.emitterBotProfileId !== undefined) {
emitterBotProfile = emitterUserProfile.bots.get(thisObject.emitterBotProfileId)
if (emitterBotProfile === undefined) {
throw ('Emitter Bot Profile Not Found.')
}
}
/*
Validate Target Bot Profile.
*/
if (thisObject.targetBotProfileId !== undefined) {
targetBotProfile = emitterUserProfile.bots.get(thisObject.targetBotProfileId)
if (targetBotProfile === undefined) {
throw ('Target Bot Profile Not Found.')
}
}
if (tradingSignals()) {
signalCounters()
return
}
function tradingSignals() {
/*
Is it related to Trading?
*/
if (
thisObject.signalType === SA.projects.socialTrading.globals.signalTypes.TRIGGER_ON ||
thisObject.signalType === SA.projects.socialTrading.globals.signalTypes.TRIGGER_OFF ||
thisObject.signalType === SA.projects.socialTrading.globals.signalTypes.TAKE_POSITION ||
thisObject.signalType === SA.projects.socialTrading.globals.signalTypes.CLOSE_POSITION
) {
/*
We will create a new Bot Post with the Signal info attached to it.
*/
if (emitterBotProfile === undefined) {
throw ('Emitter Bot Profile Id Not Provided.')
}
emitterBotProfile.addPost(
thisObject.emitterUserProfileId,
thisObject.targetUserProfileId,
thisObject.emitterBotProfileId,
thisObject.targetBotProfileId,
thisObject.emitterPostHash,
thisObject.targetPostHash,
SA.projects.socialTrading.globals.postTypes.SIGNAL_POST,
thisObject.timestamp,
thisObject.signalType,
thisObject.signalData
)
return true
}
}
function signalCounters() {
emitterUserProfile.emitterSignalsCount++
if (targetUserProfile !== undefined) {
targetUserProfile.targetSignalsCount++
}
if (emitterBotProfile !== undefined) {
emitterUserProfile.emitterSignalsCount++
}
if (targetBotProfile !== undefined) {
targetBotProfile.targetSignalsCount++
}
}
}
}
@@ -0,0 +1,13 @@
exports.newSocialTradingGlobalsPostTypes = function () {
let thisObject = {
/* Post Types */
NEW_POST: 0,
REPLY_TO_POST: 1,
REPOST: 2,
QUOTE_REPOST: 3,
SIGNAL_POST: 4
}
return thisObject
}
@@ -0,0 +1,15 @@
exports.newSocialTradingGlobalsReactionTypes = function () {
let thisObject = {
/* Reaction Types */
REACTION_LIKE: 0,
REACTION_LOVE: 1,
REACTION_HAHA: 2,
REACTION_WOW: 3,
REACTION_SAD: 4,
REACTION_ANGRY: 5,
REACTION_CARE: 6
}
return thisObject
}
@@ -0,0 +1,12 @@
exports.newSocialTradingGlobalsSignalTypes = function () {
let thisObject = {
/* Trading Signals */
TRIGGER_ON: 10,
TRIGGER_OFF: 11,
TAKE_POSITION: 12,
CLOSE_POSITION: 13
}
return thisObject
}
@@ -75,7 +75,9 @@ exports.newSocialTradingModulesSocialGraphBotProfile = function newSocialTrading
emitterPostHash,
targetPostHash,
postType,
timestamp
timestamp,
signalType,
signalData
) {
if (thisObject.posts.get(emitterPostHash) !== undefined) {
throw ('Post Already Exists.')
@@ -89,7 +91,9 @@ exports.newSocialTradingModulesSocialGraphBotProfile = function newSocialTrading
emitterPostHash,
targetPostHash,
postType,
timestamp
timestamp,
signalType,
signalData
)
thisObject.posts.set(emitterPostHash, post)
@@ -1,6 +1,6 @@
exports.newSocialTradingModulesSocialGraphPost = function newSocialTradingModulesSocialGraphPost() {
/*
Posts represent a collection of multimedia content sorted somewhere else
Posts represent a collection of multimedia content stored somewhere else
and identified by that content hash. Posts might belong to:
* a User Profile.
* a Bot Profile.
@@ -23,6 +23,9 @@ exports.newSocialTradingModulesSocialGraphPost = function newSocialTradingModule
/* Post Unique Properties */
postType: undefined,
timestamp: undefined,
/* Signal Related Properties */
signalType: undefined,
signalData: undefined,
/* Maps */
replies: undefined,
reactions: undefined,
@@ -34,33 +37,16 @@ exports.newSocialTradingModulesSocialGraphPost = function newSocialTradingModule
finalize: finalize
}
const POST_TYPES = {
NEW_POST: 0,
REPLY_TO_POST: 1,
REPOST_: 2,
QUOTE_REPOST_: 3
}
const REACTION_TYPES = {
REACTION_LIKE: 0,
REACTION_LOVE: 1,
REACTION_HAHA: 2,
REACTION_WOW: 3,
REACTION_SAD: 4,
REACTION_ANGRY: 5,
REACTION_CARE: 6
}
thisObject.replies = new Map()
thisObject.reactions = new Map()
thisObject.reactions.set(REACTION_TYPES.REACTION_LIKE, 0)
thisObject.reactions.set(REACTION_TYPES.REACTION_LOVE, 0)
thisObject.reactions.set(REACTION_TYPES.REACTION_HAHA, 0)
thisObject.reactions.set(REACTION_TYPES.REACTION_WOW, 0)
thisObject.reactions.set(REACTION_TYPES.REACTION_SAD, 0)
thisObject.reactions.set(REACTION_TYPES.REACTION_ANGRY, 0)
thisObject.reactions.set(REACTION_TYPES.REACTION_CARE, 0)
thisObject.reactions.set(SA.projects.socialTrading.globals.reactionTypes.REACTION_LIKE, 0)
thisObject.reactions.set(SA.projects.socialTrading.globals.reactionTypes.REACTION_LOVE, 0)
thisObject.reactions.set(SA.projects.socialTrading.globals.reactionTypes.REACTION_HAHA, 0)
thisObject.reactions.set(SA.projects.socialTrading.globals.reactionTypes.REACTION_WOW, 0)
thisObject.reactions.set(SA.projects.socialTrading.globals.reactionTypes.REACTION_SAD, 0)
thisObject.reactions.set(SA.projects.socialTrading.globals.reactionTypes.REACTION_ANGRY, 0)
thisObject.reactions.set(SA.projects.socialTrading.globals.reactionTypes.REACTION_CARE, 0)
return thisObject
@@ -77,7 +63,9 @@ exports.newSocialTradingModulesSocialGraphPost = function newSocialTradingModule
emitterPostHash,
targetPostHash,
postType,
timestamp
timestamp,
signalType,
signalData
) {
thisObject.emitterUserProfileId = emitterUserProfileId
@@ -88,13 +76,15 @@ exports.newSocialTradingModulesSocialGraphPost = function newSocialTradingModule
thisObject.targetPostHash = targetPostHash
thisObject.postType = postType
thisObject.timestamp = timestamp
thisObject.signalType = signalType
thisObject.signalData = signalData
/*
Let's find the Target Post
*/
if (
thisObject.postType === POST_TYPES.REPLY_TO_POST ||
thisObject.postType === POST_TYPES.REPOST_ ||
thisObject.postType === POST_TYPES.QUOTE_REPOST_
thisObject.postType === SA.projects.socialTrading.globals.postTypes.REPLY_TO_POST ||
thisObject.postType === SA.projects.socialTrading.globals.postTypes.REPOST ||
thisObject.postType === SA.projects.socialTrading.globals.postTypes.QUOTE_REPOST
) {
/*
Validate Target User Profile.
@@ -113,7 +103,7 @@ exports.newSocialTradingModulesSocialGraphPost = function newSocialTradingModule
Let's add this post to the replies of the Target Post
*/
if (
thisObject.postType === POST_TYPES.REPLY_TO_POST
thisObject.postType === SA.projects.socialTrading.globals.postTypes.REPLY_TO_POST
) {
targetPost.replies.set(thisObject.targetPostHash, thisObject.targetPostHash)
}