From 37ea7f735e53ea7dbfc863d0c985f025029823c2 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Mon, 14 Jun 2021 16:20:31 +0200 Subject: [PATCH 1/9] Governance: Reading token balance from the blockchain. --- .../User-Profiles/Luis-Fernando-Molina.json | 2 +- .../UI/Function-Libraries/UserReferrals.js | 10 +++++- .../Governance/UI/Function-Libraries/Votes.js | 9 ++++- .../Spaces/User-Profile-Space/UserProfile.js | 34 +++++++++++++++++++ 4 files changed, 52 insertions(+), 3 deletions(-) diff --git a/Projects/Governance/Plugins/User-Profiles/Luis-Fernando-Molina.json b/Projects/Governance/Plugins/User-Profiles/Luis-Fernando-Molina.json index 61df8041c..323766f68 100644 --- a/Projects/Governance/Plugins/User-Profiles/Luis-Fernando-Molina.json +++ b/Projects/Governance/Plugins/User-Profiles/Luis-Fernando-Molina.json @@ -1,7 +1,7 @@ { "type": "User Profile", "name": "Luis-Fernando-Molina", - "config": "{\n \"tokens\": 10000000\n}", + "config": "{\n \"tokens\": 10000000,\n\"blockchainAccount\": \"0x9546eAA9380A224a56d7067D712296E9D40d40e1\"\n}", "project": "Governance", "contributionClaims": { "type": "Contribution Claims", diff --git a/Projects/Governance/UI/Function-Libraries/UserReferrals.js b/Projects/Governance/UI/Function-Libraries/UserReferrals.js index bcb6d724d..a3c1927eb 100644 --- a/Projects/Governance/UI/Function-Libraries/UserReferrals.js +++ b/Projects/Governance/UI/Function-Libraries/UserReferrals.js @@ -117,7 +117,13 @@ function newGovernanceFunctionLibraryUserReferrals() { function distributeForProfile(userProfile) { if (userProfile === undefined || userProfile.payload === undefined) { return } - let referringPower = UI.projects.foundations.utilities.nodeConfig.loadConfigProperty(userProfile.payload, 'tokens') + let referringPower + if (userProfile.payload.blockchainTokens === undefined) { + referringPower = UI.projects.foundations.utilities.nodeConfig.loadConfigProperty(userProfile.payload, 'tokens') + } else { + referringPower = userProfile.payload.blockchainTokens + } + let referringCount = 0 userProfile.payload.referring.ownPower = referringPower distributeUserReferrals(userProfile, referringPower, referringCount) @@ -157,6 +163,8 @@ function newGovernanceFunctionLibraryUserReferrals() { } function calculateAwardedForProfile(userProfile) { + if (userProfile.payload === undefined) { return } + let totalPowerRewardRation = tokensReward / totalReferralsPower if (totalPowerRewardRation < 1) { totalPowerRewardRation = 1 } diff --git a/Projects/Governance/UI/Function-Libraries/Votes.js b/Projects/Governance/UI/Function-Libraries/Votes.js index 790517151..cd5d296f5 100644 --- a/Projects/Governance/UI/Function-Libraries/Votes.js +++ b/Projects/Governance/UI/Function-Libraries/Votes.js @@ -115,7 +115,14 @@ function newGovernanceFunctionLibraryVotes() { } function distributeForProfile(userProfile) { - let votes = UI.projects.foundations.utilities.nodeConfig.loadConfigProperty(userProfile.payload, 'tokens') + if (userProfile.payload === undefined) { return } + let votes + if (userProfile.payload.blockchainTokens === undefined) { + votes = UI.projects.foundations.utilities.nodeConfig.loadConfigProperty(userProfile.payload, 'tokens') + } else { + votes = userProfile.payload.blockchainTokens + } + distributeVotes(userProfile, votes) } diff --git a/Projects/Governance/UI/Spaces/User-Profile-Space/UserProfile.js b/Projects/Governance/UI/Spaces/User-Profile-Space/UserProfile.js index 827d8fcd0..1b2144f17 100644 --- a/Projects/Governance/UI/Spaces/User-Profile-Space/UserProfile.js +++ b/Projects/Governance/UI/Spaces/User-Profile-Space/UserProfile.js @@ -39,6 +39,40 @@ function newGovernanceUserProfileSpace() { function physics() { if (UI.projects.foundations.spaces.designSpace.workspace === undefined) { return } + let userProfiles = UI.projects.foundations.spaces.designSpace.workspace.getHierarchyHeadsByNodeType('User Profile') + + /* + We will get all the user Profiles tokens from the blockchain, making a call + every 5 seconds so as not to exceed the rate limit. + */ + let timer = 0 + for (let i = 0; i < userProfiles.length; i++) { + let userProfile = userProfiles[i] + if (userProfile.payload === undefined) { continue } + + if (userProfile.payload.blockchainTokens === undefined) { + let blockchainAccount = UI.projects.foundations.utilities.nodeConfig.loadConfigProperty(userProfile.payload, 'blockchainAccount') + if (blockchainAccount !== undefined && blockchainAccount !== "") { + setTimeout(getBlockchainTokens, timer, userProfile) + timer = timer + 5000 + } + } + } + + function getBlockchainTokens(userProfile) { + let blockchainAccount = UI.projects.foundations.utilities.nodeConfig.loadConfigProperty(userProfile.payload, 'blockchainAccount') + const url = "https://api.bscscan.com/api?module=account&action=tokenbalance&contractaddress=0xfb981ed9a92377ca4d75d924b9ca06df163924fd&address=" + blockchainAccount + "&tag=latest&apikey=YourApiKeyToken" + + fetch(url).then(function (response) { + return response.json(); + }).then(function (data) { + console.log(data) + userProfile.payload.uiObject.setInfoMessage(data) + userProfile.payload.blockchainTokens = Number(data.result) / 1000000000000000000 + }).catch(function (err) { + userProfile.payload.uiObject.setErrorMessage(err.message) + }); + } } function draw() { From f0acdf1303e8436eced5857b8fcb4fb8d0e6b563 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Mon, 14 Jun 2021 22:09:26 +0200 Subject: [PATCH 2/9] Bug Fixed breaking BSC Scan rate limit --- Projects/Governance/Icons/signature.png | Bin 0 -> 17538 bytes .../Schemas/App-Schema/Signature.json | 33 ++++++++++++++++++ .../Schemas/App-Schema/user-profile.json | 7 ++++ .../Spaces/User-Profile-Space/UserProfile.js | 9 ++++- 4 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 Projects/Governance/Icons/signature.png create mode 100644 Projects/Governance/Schemas/App-Schema/Signature.json diff --git a/Projects/Governance/Icons/signature.png b/Projects/Governance/Icons/signature.png new file mode 100644 index 0000000000000000000000000000000000000000..ef69b801e39ddc506bbda6ef930d53d5b8f706d8 GIT binary patch literal 17538 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 Profile->" + } +} \ No newline at end of file diff --git a/Projects/Governance/Schemas/App-Schema/user-profile.json b/Projects/Governance/Schemas/App-Schema/user-profile.json index 53f1dafea..d966c9166 100644 --- a/Projects/Governance/Schemas/App-Schema/user-profile.json +++ b/Projects/Governance/Schemas/App-Schema/user-profile.json @@ -35,6 +35,13 @@ "label": "Add User Referrer", "relatedUiObject": "User Referrer" }, + { + "action": "Add UI Object", + "actionProject": "Signature", + "actionFunction": "payload.executeAction", + "label": "Add Signature", + "relatedUiObject": "Add Signature" + }, { "action": "Delete UI Object", "actionProject": "Foundations", diff --git a/Projects/Governance/UI/Spaces/User-Profile-Space/UserProfile.js b/Projects/Governance/UI/Spaces/User-Profile-Space/UserProfile.js index 1b2144f17..2480eb542 100644 --- a/Projects/Governance/UI/Spaces/User-Profile-Space/UserProfile.js +++ b/Projects/Governance/UI/Spaces/User-Profile-Space/UserProfile.js @@ -14,6 +14,8 @@ function newGovernanceUserProfileSpace() { thisObject.container.initialize(MODULE_NAME) thisObject.container.isDraggeable = false + waitingForResponses = 0 + return thisObject function initialize() { @@ -40,7 +42,7 @@ function newGovernanceUserProfileSpace() { function physics() { if (UI.projects.foundations.spaces.designSpace.workspace === undefined) { return } let userProfiles = UI.projects.foundations.spaces.designSpace.workspace.getHierarchyHeadsByNodeType('User Profile') - + if (waitingForResponses !== 0) { return } /* We will get all the user Profiles tokens from the blockchain, making a call every 5 seconds so as not to exceed the rate limit. @@ -62,6 +64,7 @@ function newGovernanceUserProfileSpace() { function getBlockchainTokens(userProfile) { let blockchainAccount = UI.projects.foundations.utilities.nodeConfig.loadConfigProperty(userProfile.payload, 'blockchainAccount') const url = "https://api.bscscan.com/api?module=account&action=tokenbalance&contractaddress=0xfb981ed9a92377ca4d75d924b9ca06df163924fd&address=" + blockchainAccount + "&tag=latest&apikey=YourApiKeyToken" + waitingForResponses++ fetch(url).then(function (response) { return response.json(); @@ -69,8 +72,12 @@ function newGovernanceUserProfileSpace() { console.log(data) userProfile.payload.uiObject.setInfoMessage(data) userProfile.payload.blockchainTokens = Number(data.result) / 1000000000000000000 + waitingForResponses-- }).catch(function (err) { + userProfile.payload.blockchainTokens = 0 + console.log(err) userProfile.payload.uiObject.setErrorMessage(err.message) + waitingForResponses-- }); } } From 12faa5b099cceb7a2762bbafb47ed73d75786886 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Tue, 15 Jun 2021 17:32:37 +0200 Subject: [PATCH 3/9] Governance: Signing of Profiles implemented --- Client/httpInterface.js | 19 ++++ Client/web3Server.js | 59 +++++++++-- .../UI/Function-Libraries/Accounts.js | 2 +- ...05-automating-actions-using-utilities.json | 2 +- .../UI/Spaces/Panel-Space/Layer.js | 4 +- .../UI/Spaces/Panel-Space/LayersPanel.js | 4 +- .../Foundations/UI/Utilities/NodeConfig.js | 4 +- ...{signature.png => profile-constructor.png} | Bin .../User-Profiles/Luis-Fernando-Molina.json | 4 +- .../App-Schema/governance-project.json | 7 ++ ...ignature.json => profile-constructor.json} | 15 ++- .../Schemas/App-Schema/user-profile.json | 7 -- .../UI/Function-Libraries/ActionSwitch.js | 5 + .../Function-Libraries/ProfileConstructor.js | 97 ++++++++++++++++++ .../UI/Function-Libraries/UserReferrals.js | 4 +- .../Governance/UI/Function-Libraries/Votes.js | 2 +- .../Spaces/User-Profile-Space/UserProfile.js | 58 +++++++++-- Projects/ProjectsSchema.json | 5 + 18 files changed, 256 insertions(+), 42 deletions(-) rename Projects/Governance/Icons/{signature.png => profile-constructor.png} (100%) rename Projects/Governance/Schemas/App-Schema/{Signature.json => profile-constructor.json} (62%) create mode 100644 Projects/Governance/UI/Function-Libraries/ProfileConstructor.js diff --git a/Client/httpInterface.js b/Client/httpInterface.js index ed08eb406..de123c106 100644 --- a/Client/httpInterface.js +++ b/Client/httpInterface.js @@ -132,6 +132,25 @@ exports.newHttpInterface = function newHttpInterface(WEB_SERVER, DATA_FILE_SERVE respondWithContent(JSON.stringify(serverResponse), httpResponse) return } + case 'signData': { + + let serverResponse = await WEB3_SERVER.signData( + params.privateKey, + params.data + ) + + respondWithContent(JSON.stringify(serverResponse), httpResponse) + return + } + case 'recoverAddress': { + + let serverResponse = await WEB3_SERVER.recoverAddress( + params.signature + ) + + respondWithContent(JSON.stringify(serverResponse), httpResponse) + return + } default: { respondWithContent(JSON.stringify({ error: 'Method ' + params.method + ' is invalid.' }), httpResponse) } diff --git a/Client/web3Server.js b/Client/web3Server.js index 0e838d04c..cf8979128 100644 --- a/Client/web3Server.js +++ b/Client/web3Server.js @@ -6,6 +6,8 @@ exports.newWeb3Server = function newWeb3Server() { getNetworkClientStatus: getNetworkClientStatus, createWalletAccount: createWalletAccount, getWalletBalances: getWalletBalances, + signData: signData, + recoverAddress: recoverAddress, initialize: initialize, finalize: finalize, run: run @@ -56,7 +58,7 @@ exports.newWeb3Server = function newWeb3Server() { return status } } catch (err) { - return { error: 'Could not connect to ' + key + '. ' + err.message + '.' } + return { error: 'Could not connect to ' + key + '. ' + err.stack + '.' } } } @@ -73,7 +75,7 @@ exports.newWeb3Server = function newWeb3Server() { } } catch (err) { - return { error: 'Could not create the account. ' + err.message } + return { error: 'Could not create the account. ' + err.stack } } } @@ -116,22 +118,22 @@ exports.newWeb3Server = function newWeb3Server() { for (let j = 0; j < walletAccount.tokenBalances.length; j++) { let tokenBalance = walletAccount.tokenBalances[j] - if (tokenBalance.referenceParent === undefined) { continue } - if (tokenBalance.referenceParent.parentNode === undefined) { continue } - if (tokenBalance.referenceParent.smartContracts === undefined) { continue } + if (tokenBalance.referenceParent === undefined) { continue } + if (tokenBalance.referenceParent.parentNode === undefined) { continue } + if (tokenBalance.referenceParent.smartContracts === undefined) { continue } if (tokenBalance.referenceParent.config.codeName === undefined) { tokenBalance.error = 'Reference Parent without config.codeName defined.' continue - } + } if (tokenBalance.referenceParent.smartContracts.config.address === undefined) { tokenBalance.error = 'Reference Parent Smart Contract without config.address defined.' continue - } + } let tokenContractAddress = tokenBalance.referenceParent.smartContracts.config.address - // The minimum ABI to get ERC20 Token balance + // The minimum ABI to get ERC20 Token balance let minABI = [ // balanceOf { @@ -152,8 +154,8 @@ exports.newWeb3Server = function newWeb3Server() { ]; let contract = new web3.eth.Contract(minABI, tokenContractAddress); - - try { + + try { tokenBalance.value = await contract.methods.balanceOf(walletAccount.config.address).call() } catch (err) { if (err.message.indexOf('Provided address') >= 0) { @@ -170,7 +172,7 @@ exports.newWeb3Server = function newWeb3Server() { return responseData } } catch (err) { - return { error: 'Could not connect to ' + key + '. ' + err.message + '.' } + return { error: 'Could not connect to ' + key + '. ' + err.stack + '.' } } } @@ -202,4 +204,39 @@ exports.newWeb3Server = function newWeb3Server() { } } } + + async function signData(privateKey, data) { + try { + + let web3 = new Web3() + let signature = web3.eth.accounts.sign(data, privateKey) + + return { + signature: signature, + result: 'Ok' + } + + } catch (err) { + return { error: 'Could not sign the data. ' + err.stack } + } + } + + async function recoverAddress(signature) { + try { + + console.log("STRING:", signature) + let signatureObject = JSON.parse(signature) + console.log("OBJECT:", signatureObject) + let web3 = new Web3() + let address = web3.eth.accounts.recover(signatureObject) + + return { + address: address, + result: 'Ok' + } + + } catch (err) { + return { error: 'Could not recover address. ' + err.stack } + } + } } \ No newline at end of file diff --git a/Projects/Ethereum/UI/Function-Libraries/Accounts.js b/Projects/Ethereum/UI/Function-Libraries/Accounts.js index cd1e36151..f57475578 100644 --- a/Projects/Ethereum/UI/Function-Libraries/Accounts.js +++ b/Projects/Ethereum/UI/Function-Libraries/Accounts.js @@ -11,7 +11,7 @@ function newEthereumFunctionLibraryAccounts() { let params = { method: 'createWalletAccount', - entropy: walletAccountNode.id + entropy: walletAccountNode.id + (new Date()).valueOf() } let url = 'WEB3' // we don't need to ask this to any specific superalgos node. diff --git a/Projects/Foundations/Schemas/Docs-Topics/H/How/How-to-Automate-Actions-at-The-Design-Space/how-to-automate-actions-at-the-design-space-005-automating-actions-using-utilities.json b/Projects/Foundations/Schemas/Docs-Topics/H/How/How-to-Automate-Actions-at-The-Design-Space/how-to-automate-actions-at-the-design-space-005-automating-actions-using-utilities.json index 0234ae4f4..827da3839 100644 --- a/Projects/Foundations/Schemas/Docs-Topics/H/How/How-to-Automate-Actions-at-The-Design-Space/how-to-automate-actions-at-the-design-space-005-automating-actions-using-utilities.json +++ b/Projects/Foundations/Schemas/Docs-Topics/H/How/How-to-Automate-Actions-at-The-Design-Space/how-to-automate-actions-at-the-design-space-005-automating-actions-using-utilities.json @@ -52,7 +52,7 @@ }, { "style": "Javascript", - "text": "UI.projects.foundations.utilities.nodeConfig.savePropertyAtNodeConfig(node.payload,'showPanels', true)" + "text": "UI.projects.foundations.utilities.nodeConfig.saveConfigProperty(node.payload,'showPanels', true)" }, { "style": "Text", diff --git a/Projects/Foundations/UI/Spaces/Panel-Space/Layer.js b/Projects/Foundations/UI/Spaces/Panel-Space/Layer.js index 7f39e9267..d25a92cdf 100644 --- a/Projects/Foundations/UI/Spaces/Panel-Space/Layer.js +++ b/Projects/Foundations/UI/Spaces/Panel-Space/Layer.js @@ -511,7 +511,7 @@ function newLayer() { } } } else { - UI.projects.foundations.utilities.nodeConfig.savePropertyAtNodeConfig(thisObject.payload, 'showPanels', panelsVisibleButton.showPanels) + UI.projects.foundations.utilities.nodeConfig.saveConfigProperty(thisObject.payload, 'showPanels', panelsVisibleButton.showPanels) } } } @@ -560,7 +560,7 @@ function newLayer() { } } - UI.projects.foundations.utilities.nodeConfig.savePropertyAtNodeConfig(thisObject.payload, 'status', thisObject.status) + UI.projects.foundations.utilities.nodeConfig.saveConfigProperty(thisObject.payload, 'status', thisObject.status) let eventData = thisObject thisObject.container.eventHandler.raiseEvent('Status Changed', eventData) } diff --git a/Projects/Foundations/UI/Spaces/Panel-Space/LayersPanel.js b/Projects/Foundations/UI/Spaces/Panel-Space/LayersPanel.js index 1eb9b2b7f..000986a47 100644 --- a/Projects/Foundations/UI/Spaces/Panel-Space/LayersPanel.js +++ b/Projects/Foundations/UI/Spaces/Panel-Space/LayersPanel.js @@ -114,7 +114,7 @@ function newLayersPanel() { } function saveObjectStateVisibleLayers() { - UI.projects.foundations.utilities.nodeConfig.savePropertyAtNodeConfig(thisObject.payload, 'visibleLayers', desiredVisibleLayers) + UI.projects.foundations.utilities.nodeConfig.saveConfigProperty(thisObject.payload, 'visibleLayers', desiredVisibleLayers) } function saveObjectStatePanelLocation() { @@ -122,7 +122,7 @@ function newLayersPanel() { upOrDown: thisObject.upDownButton.status, leftOrRight: thisObject.leftRightButton.status } - UI.projects.foundations.utilities.nodeConfig.savePropertyAtNodeConfig(thisObject.payload, 'panelLocation', panelLocation) + UI.projects.foundations.utilities.nodeConfig.saveConfigProperty(thisObject.payload, 'panelLocation', panelLocation) } function readObjectState() { diff --git a/Projects/Foundations/UI/Utilities/NodeConfig.js b/Projects/Foundations/UI/Utilities/NodeConfig.js index 3a0dda7f7..865c3aba1 100644 --- a/Projects/Foundations/UI/Utilities/NodeConfig.js +++ b/Projects/Foundations/UI/Utilities/NodeConfig.js @@ -1,12 +1,12 @@ function newFoundationsUtilitiesNodeConfig() { let thisObject = { - savePropertyAtNodeConfig: savePropertyAtNodeConfig, + saveConfigProperty: saveConfigProperty, loadConfigProperty: loadConfigProperty } return thisObject - function savePropertyAtNodeConfig(payload, propertyName, value) { + function saveConfigProperty(payload, propertyName, value) { try { let config = JSON.parse(payload.node.config) config[propertyName] = value diff --git a/Projects/Governance/Icons/signature.png b/Projects/Governance/Icons/profile-constructor.png similarity index 100% rename from Projects/Governance/Icons/signature.png rename to Projects/Governance/Icons/profile-constructor.png diff --git a/Projects/Governance/Plugins/User-Profiles/Luis-Fernando-Molina.json b/Projects/Governance/Plugins/User-Profiles/Luis-Fernando-Molina.json index 323766f68..80afbc6f3 100644 --- a/Projects/Governance/Plugins/User-Profiles/Luis-Fernando-Molina.json +++ b/Projects/Governance/Plugins/User-Profiles/Luis-Fernando-Molina.json @@ -1,7 +1,7 @@ { "type": "User Profile", "name": "Luis-Fernando-Molina", - "config": "{\n \"tokens\": 10000000,\n\"blockchainAccount\": \"0x9546eAA9380A224a56d7067D712296E9D40d40e1\"\n}", + "config": "{\n \"tokens\": 10000000,\n \"signature\": {\n \"message\": \"Luis-Fernando-Molina\",\n \"messageHash\": \"0x443abf3389e332a62d21b84dd12e271cb428d334195d3aeb986ca85ee53cccb9\",\n \"v\": \"0x1b\",\n \"r\": \"0x90293b042c180aa21b05f0356f31688c597be4ff2df136f63a2b8a899c658eb0\",\n \"s\": \"0x42abf909024d34217430e42ebadc96b7834218cc86a4c295a2ae419ff2fca6e3\",\n \"signature\": \"0x90293b042c180aa21b05f0356f31688c597be4ff2df136f63a2b8a899c658eb042abf909024d34217430e42ebadc96b7834218cc86a4c295a2ae419ff2fca6e31b\"\n }\n}", "project": "Governance", "contributionClaims": { "type": "Contribution Claims", @@ -3932,7 +3932,7 @@ "floatingObject": { "isPinned": false, "isFrozen": false, - "isCollapsed": true, + "isCollapsed": false, "angleToParent": 1, "distanceToParent": 3, "arrangementStyle": 0 diff --git a/Projects/Governance/Schemas/App-Schema/governance-project.json b/Projects/Governance/Schemas/App-Schema/governance-project.json index b5e72eeca..03d3ba270 100644 --- a/Projects/Governance/Schemas/App-Schema/governance-project.json +++ b/Projects/Governance/Schemas/App-Schema/governance-project.json @@ -36,6 +36,13 @@ "relatedUiObject": "User Profile", "actionFunction": "payload.executeAction" }, + { + "action": "Add UI Object", + "actionProject": "Foundations", + "actionFunction": "payload.executeAction", + "label": "Add Profile Constructor", + "relatedUiObject": "Profile Constructor" + }, { "action": "Delete UI Object", "actionProject": "Foundations", diff --git a/Projects/Governance/Schemas/App-Schema/Signature.json b/Projects/Governance/Schemas/App-Schema/profile-constructor.json similarity index 62% rename from Projects/Governance/Schemas/App-Schema/Signature.json rename to Projects/Governance/Schemas/App-Schema/profile-constructor.json index 0977983ea..40dae30b2 100644 --- a/Projects/Governance/Schemas/App-Schema/Signature.json +++ b/Projects/Governance/Schemas/App-Schema/profile-constructor.json @@ -1,5 +1,5 @@ { - "type": "Signature", + "type": "Profile Constructor", "menuItems": [ { "action": "Configure", @@ -8,6 +8,16 @@ "iconPathOn": "configuration", "iconPathOff": "configuration" }, + { + "action": "Build Profile", + "actionProject": "Governance", + "label": "Build Profile", + "askConfirmation": true, + "confirmationLabel": "Confirm to Proceed", + "workDoneLabel": "Done", + "relatedUiObject": "Profile Constructor", + "actionFunction": "payload.executeAction" + }, { "action": "Delete UI Object", "actionProject": "Foundations", @@ -19,11 +29,12 @@ "actionFunction": "payload.executeAction" } ], + "isHierarchyHead": true, "editors": { "config": true }, "initialValues": { - "config": "{ \"privateKey\": \"\"}" + "config": "{ \"githubUsername\": \"\"}" }, "addLeftIcons": true, "level": 2, diff --git a/Projects/Governance/Schemas/App-Schema/user-profile.json b/Projects/Governance/Schemas/App-Schema/user-profile.json index d966c9166..53f1dafea 100644 --- a/Projects/Governance/Schemas/App-Schema/user-profile.json +++ b/Projects/Governance/Schemas/App-Schema/user-profile.json @@ -35,13 +35,6 @@ "label": "Add User Referrer", "relatedUiObject": "User Referrer" }, - { - "action": "Add UI Object", - "actionProject": "Signature", - "actionFunction": "payload.executeAction", - "label": "Add Signature", - "relatedUiObject": "Add Signature" - }, { "action": "Delete UI Object", "actionProject": "Foundations", diff --git a/Projects/Governance/UI/Function-Libraries/ActionSwitch.js b/Projects/Governance/UI/Function-Libraries/ActionSwitch.js index 378790fc2..4dd5ba618 100644 --- a/Projects/Governance/UI/Function-Libraries/ActionSwitch.js +++ b/Projects/Governance/UI/Function-Libraries/ActionSwitch.js @@ -28,6 +28,11 @@ function newGovernanceActionSwitch() { UI.projects.governance.functionLibraries.votes.installVotes(action.node, action.rootNodes) break } + case 'Build Profile': + { + UI.projects.governance.functionLibraries.profileConstructor.buildProfile(action.node, action.rootNodes) + break + } case 'Add Missing Plugin User Profiles': { UI.projects.governance.functionLibraries.pluginsFunctions.addMissingPluginUserProfiles(action.node, action.rootNodes) diff --git a/Projects/Governance/UI/Function-Libraries/ProfileConstructor.js b/Projects/Governance/UI/Function-Libraries/ProfileConstructor.js new file mode 100644 index 000000000..48106de7e --- /dev/null +++ b/Projects/Governance/UI/Function-Libraries/ProfileConstructor.js @@ -0,0 +1,97 @@ +function newGovernanceFunctionLibraryProfileConstructor() { + let thisObject = { + buildProfile: buildProfile + } + + return thisObject + + function buildProfile( + node, + rootNodes + ) { + /* + Some validations first... + */ + if (node.payload.referenceParent === undefined) { + node.payload.uiObject.setErrorMessage("You need to reference the node that contains the data to be signed.") + return + } + let data = UI.projects.foundations.utilities.nodeConfig.loadConfigProperty(node.payload, 'githubUsername') + + if (data === undefined || data === "") { + node.payload.referenceParent.payload.uiObject.setErrorMessage("githubUsername config property missing.") + return + } + + createNewAccount() + signUserProfileData() + + function createNewAccount() { + let params = { + method: 'createWalletAccount', + entropy: node.id + (new Date()).valueOf() + } + + let url = 'WEB3' // we don't need to ask this to any specific superalgos node. + + httpRequest(JSON.stringify(params), url, onResponse) + + function onResponse(err, data) { + /* Lets check the result of the call through the http interface */ + if (err.result !== GLOBAL.DEFAULT_OK_RESPONSE.result) { + node.payload.uiObject.setErrorMessage('Call via HTTP Interface failed.') + walletAccountNode.payload.uiObject.menu.internalClick('Delete UI Object') + return + } + + let response = JSON.parse(data) + + /* Lets check the result of the method call */ + if (response.result !== GLOBAL.DEFAULT_OK_RESPONSE.result) { + node.payload.uiObject.setErrorMessage('Call to WEB3 Server failed. ' + response.error) + return + } + + UI.projects.foundations.utilities.nodeConfig.saveConfigProperty(node.payload, 'address', response.address) + UI.projects.foundations.utilities.nodeConfig.saveConfigProperty(node.payload, 'privateKey', response.privateKey) + } + } + + function signUserProfileData() { + + let privateKey = UI.projects.foundations.utilities.nodeConfig.loadConfigProperty(node.payload, 'privateKey') + if (privateKey === undefined || privateKey === "") { return } + + let request = { + url: 'WEB3', + params: { + method: "signData", + privateKey: privateKey, + data: data + } + } + + httpRequest(JSON.stringify(request.params), request.url, onResponse) + + function onResponse(err, data) { + /* Lets check the result of the call through the http interface */ + if (err.result !== GLOBAL.DEFAULT_OK_RESPONSE.result) { + node.payload.uiObject.setErrorMessage('Call via HTTP Interface failed.') + return + } + + let response = JSON.parse(data) + + /* Lets check the result of the method call */ + if (response.result !== GLOBAL.DEFAULT_OK_RESPONSE.result) { + node.payload.uiObject.setErrorMessage('Call to WEB3 Server failed. ' + response.error) + console.log('Call to WEB3 Server failed. ' + response.error) + return + } + UI.projects.foundations.utilities.nodeConfig.saveConfigProperty(node.payload.referenceParent.payload, 'signature', response.signature) + + node.payload.uiObject.setInfoMessage("Profile Account has been successfully created.") + } + } + } +} diff --git a/Projects/Governance/UI/Function-Libraries/UserReferrals.js b/Projects/Governance/UI/Function-Libraries/UserReferrals.js index a3c1927eb..289f56a35 100644 --- a/Projects/Governance/UI/Function-Libraries/UserReferrals.js +++ b/Projects/Governance/UI/Function-Libraries/UserReferrals.js @@ -117,9 +117,9 @@ function newGovernanceFunctionLibraryUserReferrals() { function distributeForProfile(userProfile) { if (userProfile === undefined || userProfile.payload === undefined) { return } - let referringPower + let referringPower if (userProfile.payload.blockchainTokens === undefined) { - referringPower = UI.projects.foundations.utilities.nodeConfig.loadConfigProperty(userProfile.payload, 'tokens') + return } else { referringPower = userProfile.payload.blockchainTokens } diff --git a/Projects/Governance/UI/Function-Libraries/Votes.js b/Projects/Governance/UI/Function-Libraries/Votes.js index cd5d296f5..13da3b0a0 100644 --- a/Projects/Governance/UI/Function-Libraries/Votes.js +++ b/Projects/Governance/UI/Function-Libraries/Votes.js @@ -118,7 +118,7 @@ function newGovernanceFunctionLibraryVotes() { if (userProfile.payload === undefined) { return } let votes if (userProfile.payload.blockchainTokens === undefined) { - votes = UI.projects.foundations.utilities.nodeConfig.loadConfigProperty(userProfile.payload, 'tokens') + return } else { votes = userProfile.payload.blockchainTokens } diff --git a/Projects/Governance/UI/Spaces/User-Profile-Space/UserProfile.js b/Projects/Governance/UI/Spaces/User-Profile-Space/UserProfile.js index 2480eb542..f9dd1c21d 100644 --- a/Projects/Governance/UI/Spaces/User-Profile-Space/UserProfile.js +++ b/Projects/Governance/UI/Spaces/User-Profile-Space/UserProfile.js @@ -53,18 +53,58 @@ function newGovernanceUserProfileSpace() { if (userProfile.payload === undefined) { continue } if (userProfile.payload.blockchainTokens === undefined) { - let blockchainAccount = UI.projects.foundations.utilities.nodeConfig.loadConfigProperty(userProfile.payload, 'blockchainAccount') - if (blockchainAccount !== undefined && blockchainAccount !== "") { - setTimeout(getBlockchainTokens, timer, userProfile) + //userProfile.payload.blockchainTokens = UI.projects.foundations.utilities.nodeConfig.loadConfigProperty(userProfile.payload, 'tokens') + getBlockchainAccount(userProfile) + } + } + + function getBlockchainAccount(userProfile) { + let signature = UI.projects.foundations.utilities.nodeConfig.loadConfigProperty(userProfile.payload, 'signature') + if (signature === undefined || signature === "") { return } + + let request = { + url: 'WEB3', + params: { + method: "recoverAddress", + signature: JSON.stringify(signature) + } + } + + httpRequest(JSON.stringify(request.params), request.url, onResponse) + + function onResponse(err, data) { + /* Lets check the result of the call through the http interface */ + if (err.result !== GLOBAL.DEFAULT_OK_RESPONSE.result) { + userProfile.payload.uiObject.setErrorMessage('Call via HTTP Interface failed.') + return + } + + let response = JSON.parse(data) + + /* Lets check the result of the method call */ + if (response.result !== GLOBAL.DEFAULT_OK_RESPONSE.result) { + userProfile.payload.uiObject.setErrorMessage('Call to WEB3 Server failed. ' + response.error) + console.log('Call to WEB3 Server failed. ' + response.error) + return + } + + let blockchainAccount = response.address + if ( + blockchainAccount !== undefined && + blockchainAccount !== "" && + userProfile.payload.blockchainTokens === undefined + ) { + waitingForResponses++ + userProfile.payload.blockchainTokens = 0 // We need to set this value here so that the next call to BSCSCAN is not done more than once. + setTimeout(getBlockchainTokens, timer, userProfile, blockchainAccount) timer = timer + 5000 } } } - function getBlockchainTokens(userProfile) { - let blockchainAccount = UI.projects.foundations.utilities.nodeConfig.loadConfigProperty(userProfile.payload, 'blockchainAccount') + function getBlockchainTokens(userProfile, blockchainAccount) { + console.log('blockchainAccount ', blockchainAccount) const url = "https://api.bscscan.com/api?module=account&action=tokenbalance&contractaddress=0xfb981ed9a92377ca4d75d924b9ca06df163924fd&address=" + blockchainAccount + "&tag=latest&apikey=YourApiKeyToken" - waitingForResponses++ fetch(url).then(function (response) { return response.json(); @@ -74,9 +114,9 @@ function newGovernanceUserProfileSpace() { userProfile.payload.blockchainTokens = Number(data.result) / 1000000000000000000 waitingForResponses-- }).catch(function (err) { - userProfile.payload.blockchainTokens = 0 - console.log(err) - userProfile.payload.uiObject.setErrorMessage(err.message) + const message = err.message + ' - ' + 'Can not access BSC SCAN servers. Using tokens Config Property instead of blockchain data.' + console.log(message) + userProfile.payload.uiObject.setErrorMessage(message, 1000) waitingForResponses-- }); } diff --git a/Projects/ProjectsSchema.json b/Projects/ProjectsSchema.json index 7ba6c94d5..246b26fca 100644 --- a/Projects/ProjectsSchema.json +++ b/Projects/ProjectsSchema.json @@ -997,6 +997,11 @@ "name": "User Referrals", "propertyName": "userrReferrals", "functionName": "newGovernanceFunctionLibraryUserReferrals" + }, + { + "name": "Profile Constructor", + "propertyName": "profileConstructor", + "functionName": "newGovernanceFunctionLibraryProfileConstructor" } ], "utilities": [], From 02e23d2ab54c16e5323860122419dced369b0bcd Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Wed, 16 Jun 2021 00:45:25 +0200 Subject: [PATCH 4/9] Governance: Programs Structure --- .../claims-program.png} | Bin .../Icons/Programs/mentorship-program.png | Bin 0 -> 14216 bytes .../Icons/Programs/referral-program.png | Bin 0 -> 20204 bytes .../Icons/Programs/staking-program.png | Bin 0 -> 12357 bytes .../Icons/Programs/support-program.png | Bin 0 -> 20366 bytes .../voting-program.png} | Bin .../Governance/Icons/User/user-mentor.png | Bin 0 -> 19433 bytes .../Governance/Icons/User/user-support.png | Bin 0 -> 10670 bytes Projects/Governance/Icons/token-switch.png | Bin 0 -> 20111 bytes .../Plugins/User-Profiles/Julian-Molina.json | 599 +-- .../User-Profiles/Luis-Fernando-Molina.json | 4066 +---------------- .../Token-Distribution-Superalgos.json | 12 +- .../asset-contributions-folder.json | 2 +- ...bution-claims.json => claims-program.json} | 6 +- .../feature-contributions-folder.json | 2 +- .../App-Schema/mentorship-program.json | 51 + .../position-contributions-folder.json | 2 +- .../Schemas/App-Schema/referring-program.json | 51 + .../Schemas/App-Schema/staking-program.json | 34 + .../Schemas/App-Schema/support-program.json | 51 + .../Schemas/App-Schema/tokensSwitch.json | 126 + .../Schemas/App-Schema/user-mentor.json | 40 + .../Schemas/App-Schema/user-profile.json | 44 +- .../Schemas/App-Schema/user-referrer.json | 4 +- .../Schemas/App-Schema/userSupport.json | 40 + .../Schemas/App-Schema/votes-switch.json | 2 +- ...-distribution.json => voting-program.json} | 15 +- .../contribution-claims.json | 2 +- .../U/User/User-Profile/user-profile.json | 2 +- .../votes-distribution.json | 2 +- .../UI/Function-Libraries/Claims.js | 8 +- .../UI/Function-Libraries/Tokens.js | 4 +- .../Governance/UI/Function-Libraries/Votes.js | 12 +- 33 files changed, 802 insertions(+), 4375 deletions(-) rename Projects/Governance/Icons/{contribution-claims.png => Programs/claims-program.png} (100%) create mode 100644 Projects/Governance/Icons/Programs/mentorship-program.png create mode 100644 Projects/Governance/Icons/Programs/referral-program.png create mode 100644 Projects/Governance/Icons/Programs/staking-program.png create mode 100644 Projects/Governance/Icons/Programs/support-program.png rename Projects/Governance/Icons/{Votes/votes-distribution.png => Programs/voting-program.png} (100%) create mode 100644 Projects/Governance/Icons/User/user-mentor.png create mode 100644 Projects/Governance/Icons/User/user-support.png create mode 100644 Projects/Governance/Icons/token-switch.png rename Projects/Governance/Schemas/App-Schema/{contribution-claims.json => claims-program.json} (94%) create mode 100644 Projects/Governance/Schemas/App-Schema/mentorship-program.json create mode 100644 Projects/Governance/Schemas/App-Schema/referring-program.json create mode 100644 Projects/Governance/Schemas/App-Schema/staking-program.json create mode 100644 Projects/Governance/Schemas/App-Schema/support-program.json create mode 100644 Projects/Governance/Schemas/App-Schema/tokensSwitch.json create mode 100644 Projects/Governance/Schemas/App-Schema/user-mentor.json create mode 100644 Projects/Governance/Schemas/App-Schema/userSupport.json rename Projects/Governance/Schemas/App-Schema/{votes-distribution.json => voting-program.json} (72%) diff --git a/Projects/Governance/Icons/contribution-claims.png b/Projects/Governance/Icons/Programs/claims-program.png similarity index 100% rename from Projects/Governance/Icons/contribution-claims.png rename to Projects/Governance/Icons/Programs/claims-program.png diff --git a/Projects/Governance/Icons/Programs/mentorship-program.png b/Projects/Governance/Icons/Programs/mentorship-program.png new file mode 100644 index 0000000000000000000000000000000000000000..b6f5da755fbf44e1e48ea703d5941a86733f7764 GIT binary patch literal 14216 zcmaL8XIN8P6EM1V5=f-0G*KkzQIxKLASel-f>Mtl9SKVBDn)782%@4Qb`X##N|CA* z5fFlkg3^)R0xG@N(2~12@Auv3xqoi{WbeJ&%&ci^X4Y*JBVArDF)jcA?`gdgX92*# zM+_iv!oP*9zgFSj4!@I@ex^Roet`~`oq(33&jlyqX)gyCr?XBDj@K^LI2{8(Rr>S^ zEwig#6TKdHZT}_>&wg+1Ex)MB`_1;|VT9*2z1LuWbPe~1{3f15U6pzak?l7MbUXj4 z7OQ&d{Mz-g6-6j}&%THE%+2?AHZ|j%3dS98BoU_fYixg}D|YKCkM|%igYos`UEZR~ z0>iZ~k?ECl$yl#a1^=VZhUYf)-W=ZI{WkgS6nlC-`DeTnu*@#-x0#NlPQ>g^noSn@ z&OY|<(Xd~C%Y!YH=gz*Jz4$78<4+(N(+0YHS-FWZht5Z*DigH#@z#vs|`ZyF8< z=*h1tj+B3HzY@Py5*X+plu~uvzoH%Wz7WFVz$c`4BM}g5YtcrfUIZemaVIR$cA~Xw z+W7}U)M7r!J*nFIttt~|-U6V;}P5UH)j8Z*ic00+=l#(>BpzzMNAE4wPa5PE4K zZDc#}$MD|`t<{=&%67pTQw2z z%%7tu&m4ARS~3e`jk#A>MR_qG^_Rr)7mgZ|1Tgb*X1U5@?Gs!B_-Dq=j)sRtVQ`?> z3<4z+YB&3A$5sq@Zm#m%X3JXqZbvaLT)}eVT zgW9fyD}K#fK52{}l%YnG7)7t|1XAi=gog6qM*!vh=l-3?k2|S-yw3+h%Ctvr}pt-&P81Z=nNN$dmZitH-}CRmPaeLs-od;!@TKwc;09r7{`tP zBKo=C>s$9m?_JIjz}WU=L4FwABxuJ`NA;v4sD@O9=pH)yKg@&lA>11=9F;8HT! zORDI}>+p-!EcICVSQ-;stsU6Ido}ST4GVHsweY|XOU45ZLH0e{MeKpRo%AlC4yr%S zJmZyFhphqWq5)iRIeCai-e(E)c+hWevV;z7=@ewuGv6kEISPjtb?pwss-2AG181dK zpJvaIswB|5wr{=Y`Av$n-C_T3YRMV-*I5~;kt;F--q|&V86X`t%+@(-n_~NYo=iLt*@zZ#L zhh2|d1TjaH1gji)$%k$v%Z24(JOCv;+98uDj*_D*hROr}T}NoAD!2pR$)kV~JUe~w z4oSifFiiq?VTu*^fU8#PYdmXf2t~T)8WPIGfzZXJ>~U zNkC7xGtV#q6y{_ZH&O4-Tb3hC> z-ijfBBDj}=R8V~!=jkX)04Ig1LSa+R9AKrpHe3sb?zuyi*o%N0qkC}z08T-mPA)@k-o2CP|}er zSV;`|cvW)1R=~VjO4tTcWmz5vS%48ru>7fbH=#=4S2Q(np+F|c@30u5CUiN6B9Qvd zFW~0K{XspSeEUwa*B;D&X}b7zLR`I$_|Zi%D66kCKLiEj*)(PZK>2$P`^2nxw(ptG zsN(iODEotN*2huR!#Y<<;fcc>L$`Ig4)6{mgmC=z)q*KdZM%oUh+1 zd{x3+x5f$xvCk`MPV>_vKXQ^~*4RJi61Y9;Jlg5Y{NgGVq$@G}w9taxG;KV+VlemP z3zwA;ti#XoA5`fsCmNXhyYp$DCS9{3r!!w6uFyd%WOY!8{rtB>E=fSKu1dAEPQi;` z_T$4vWGSOH`T!31uZ;HXiXz?={JHwie1G=7dz6iBNDWhvn~5abB|p zSg;opCoFKO99b=;P}@vTbB!-b$(^5V2&EyvVwMV%QaJ>1e$tX$ADWhvkUmcIYE!?n z<`>|1Zt{olG5>?*{^R#JKx6yW3?a6YW-0jNt#8g!JtL0#$d9Hu@fNTsPSAXY7zfJ>FLx7!=p=1B20a9hWi|D{k9?$oX-^b{gdM zOVIBw@g*&>f(=q}9s6Pv-j9pW>N!znB6VpEoBoqqD(X5@vrwO`g+@eNe%JPQjYDl^ z%kAijha$u4*z|6a1ZhX@^4kp1dm+vr`PjID`GG^%(`T45R)juH?(Hh#^D=8 z8A`OfGXxn8Zd`ExdCe<8tlVtv%L7`uy&-mFf!u3Jh;MEq4|^Y@`4QAb_y&>hGK>H>pbe`^z z%a4B^or)=tN5wJmqXDCj$x@mem&TJ@Sm5>GvP*q@?lei%kCpZB{|o zIG87x6>iWIIL*cBpsn@mV9-mi_!eco^rYCkyr=HJNIL#A(+@oV5>5h_UnU`4k~51N zKF>eB=s)KAYBnD;f^(#=Vy|aSf)f^O^QP8UT+B>xonuqpSg=) zfY@t}aO{y!v;c1W?R?e){mP2vv9~J=58r+)ou7Hkeu1Iq;&W9SBxDkX`>lpTiS*hV z|0bbO-8F}-M0u3iNyPeL2uMbIQL7(FEnl5h+O-s?^ZooUU_Ju@@O(uY_>~ zU^3fo7+@}cUXMUG$g&o2HT85FkT_gA#;*J!k!rsFm;0}M{4}fPzK7`+g3aYCl1UPb z-*%iOD_xl%>=1065lo(9P16m1EE_7yU&xn1U%zDz@99D2j+IdZW zy+>UvD-rhX-DQ_@SBx5rJ;Fg_Co*oo^6A>Z*VsTw#`M!(`p%w`K9%4lq4Ue0w=Uam z>|M;9`~E6(uB=x)SA|*qIq=%{naVEE&nM8_rYjc|xmK9l2n2lAWaf{OpO*)9&)=}S zJzkMn6+T7)uWWeNilWbVOBA*tatCue^K%udH~ao>lz4q6b53R1UO9V9qae-{6YGd1 z@d?bGy!FATo<4K{Cs?$WUCl>7^`(gP+TiAThql(A?&BnfGeG4zXX9kl;*8T7vMJ)p z?|ItAmix;VFx$#*zdHS3znxdN?;`0zbcHtRmCIfAuL!vp*w^zk)}sPbkK!c}>gK3U!9r!wNOR1j87?0I zlC&Kqp^AZg1^EHaVqj2-{c#oleBs7iZih5sSO=ZjRc#pYd<^3lQ@uYLpA|g7Z^$5PRiKrp9;Bf}fcX!)At?f2`WZ%=n(>r7D zK``6!#0ddL*X?jPb5ub9V2nHABT!R2G4N-A16U z@uxC-vSz`#8I9v4Cp$7-k}Snp5+I_LiV<&_V2_rT&gZQ_9q|5~qKR%j zzeb>pgCR$j-Q|5g=fewCS^>S1M85P3X)HnUK0QAvIK38Ny`8a*kKnF1hR43?MHmbT z8s&c9(lHwj>>E2I=LV|K@5}3BtEF;e63_=pbWDx8Rx0ju$~X(Q3aq*+{urx4G5k8W%$2StlwSFq1F``#vlAwU1I;ZTu7^NI@&m{cX_ zBXhZh88~!g%-(|Kam^lRxH-^-3Gd~JyJ~hIIgOn_mXP(c3u=ldUSnWk_5}!Nd5jiu z<%}GwrQkjnCLywf+7CmiLco=c-b__ z4@|)kO3cwO6dYsiW{i6Nff-UyUZkq0bA~LZK?-&TOmi@HPx4u+2IpHH9yjFtas~2S z1`rYE7>lIi)g%?4b#a*YAftR5-inplrJV0SyTq>kSI zLJK!1?SK*9pyG(C;O0KZ>Dh3!`+GXrp?JSsATH#YPi-%}rRwg^Ym8OyLKtHb^poDQ z8*L$O^{O4xBS^1o^$&w(A|G8LJ|7SMce&90q|?-d)Z>{!)^QVs^oWUnn~s;0M#enpEGH}_}-uN zKrDIUOz}`^c2-G{O$!uFxN%k@jPoM&p*7qwdOR?-&Udl5Qz`BHZ$ZQV7{AXfD5=u- zR$Utc43z%ZOnYwq{F?piCXZ{8iVcS}e5hq#X_32V9)LkM(UIVPMed+iXkjTOl{h_oc z?F6NrA@{))e`CmGDi+Wbp>?bY52Bwh`8PIu7~{&tczW&1)kn=!;A@k1?FKgQi7?0ebB*Ql=soXv)n}?{mDZYez_PL!Inebr z8=ejX8Dg+Fo!g*r)7zobMLY|eT&EETiM?QHChn{AOiU@FZLlD zjw?%_Z%bZr_sg1TpZz)FPqBWqn_xCLCV?tE+{EFJP8FMjJ9;|iVno>vC7Jf^;K$wV zz#@YwgM+q2g3Vkiy%B(TmXpGr#>PM%5I|etxaY#;BD0V?CHl1MH!*~<_itYSx*z}w zt`0;Sj{M~>=>(B?glVWJFE1vWZ*pmZF#8=Gs|u}<{*`hEZ|P6<6vvSSJm0Xo5Uq`* zyG`{3H=>a?zG?008e`yC&%5~S>pPmCFx!_UYWLyNXM9*+x_N@&$wePaR``vjTUc+W z6(R;(9Cca%7h+ZP_aG~KgJ2*6yq!Y;(_oV!sqV}Zq(X-%y(H~yb%Wh0LTfl z6GYg$Ek``U?AWaJnETId)GM6&)Mk@wJ0GZu(ywQ5({^%gI5IPb7#&_bdZ(0CW(L}h z^UWN*cPcL(7tx2dQ_8)$w-o zZHl*qtvZ)>*>DWx*VkacG5}(~nu@;q)w@mVrg`)Yi|YM!&7{Fou{41{`xO?vW<+-; zyRLYo2h*~z=ly(THU0jaK&2nB!~*5jN6J!3-#SAu=o83YL5ll;v27VAu@6I_A@1xe zbYsz9944w{JB03EV;H_EoOP#DHuwXf*(lV6;b`ty98_fFh-P>8&lyoX<|DZUbV)*S zEM|@0;RB7Y3%c29QT7fd;;*u=kE<8u$%FHLFp5sBJGZ7T9Je>T_sV|)7TNL;(02eb zwmFe4aco(ECp`ta8j_3`MfQrKzBSTtjYrKrMa!&@B0EgJFBY-mvakCVVNIM5psTJ^ zr0n@Me;Y;e*7nr#TU4H2O4#3oqNt&_*cgtro^dikYmL|r{@u&`ps=KkNx^AbX?Z=fZ*nKVLl?rt$ zQ6DoF)FY5?zr!3r`SN1_w*ivtU3I`8=;@qE%u3mmNfRI7s*tu+I07P1Zn`k&LB#U< zK|p&4V*A!f-R#dPz0li=+!u!dVh`HZ*_}<&5j)bMU9IN@(XT;XoCBDf21MKc)V8P4 ziE!b3&dpRxh1Y3!`|(`}h|0cxz)aN?kdvIBHFJXrK-S*Wsbm7V4`w&&#epz;;HfFrCkEzCet_7sct(%jlgh771qWjDF|mQ*fD#YAwz&k$SUD8KuKHtML~;>^1|Xcg z`v(rtjNB%H=M@KKz)ukhe5a{~bMU8PZZFb5;^m%nYL$JHG7DiwthP+(I# z%{&l++KyCHP}nWJNf0b^!-T?2?Z^#N9*nb};qA@L97AXdiw2d#6c2p+A_xco2+%(E z?1ZTV0N|ux^I@i`lKaCU7#andR`hV~^e;8s7XQ7HU1MT;tBEK89hA6k=AQ4F?294< zsCGdB4sG(oklorsIJdWSk&3QsZLVF{vvfEDb^D}T@_h3>uWIB*3lHY-azc|aRE&@= z``wZTDrmorIJZAicNvNoIW_G6Oa9<(Mo7|1A{IUEI?%75lI*bA z!&B+$pcoocw2$Y2CQXh?+8GuZPM$(&KNP`=KX44V4bV$IF}>bJN&RLCZ2V=jeE|5M zxgr8!7Orsp1Fz3(W=bq*tQQ4~8pqeqNLK}WuhsE5)6HgN_VTwEts^HTVNO$x6j1y6 zQj7!)q+0*2xX6^*wa5)=_^`_gT(M@Wi@(`dcms74SKv`~Ew`^qeoFGBsQ@ew)+G7L zL2=H1dW6+vYnQ(q#&Q8EQ9Ml(3ghWXkGkO#bVcopW;4_ybGI_?9{Wn6@0Z%-#Mf@9 z^3cpEVBTK|>o5>UwW1JLBDiaAx}t84r(Ymb-OAbV^HlxWo7tRJP=Aap%w%SS%GG0M zw$E?)(t$35^(0_3x{3kUtek2l+Ma2b~E+EX=eRKA&#K`Wifen&osLX9zna$PUf9mV6Paoy<_X#Vbk@OvsYh3z(GzRjOn_)5_Z*HAczQ~=T4y!*}7OO)(+yF#tB_UIk9BU zs}I6w1m-sguds?m4&vf~c3P^Qr4Pk-LhlJu2jkhMNUPRk}h`B z%>Mc25f@RO$UhO*{YEhFdAH5wd#Q)M$g#8SoviN->k9Kr84`-VM_Z1uV+L~L9*N{! zP!#Y4aVoP^Ij`P;@OR;vVdbmAZDmiPBn-X%n4Fn3O|lYbJXaCTh6eEJ@5`wxtRK~1 zYM1xw!3bHy^DHd!$w<>r0VKOAq&#P0v2kmKSH5t_4EtSIh1&D!w7>Ubskr^DFK?hE zL62cjy5cGXv}VSluJT`MiB@Zcls)Y_RW`2Y0e%^aOz%?OpsxC#N)@6;d){5=6 z?g;=p$N9?q=zPE<3pSTC7N`^*1Y8xQO{ z4e-R%d>)}oBi)SoPxMQV}*btF0lSgtto)FfNq%E6i`8I^w`$n%ma}sUp3sisB-IZ=a3^lwKQJ z??2qn|3_z--C+4a-#_f#WRBg&aOY|=j~$@&Kr?cvJ4$u4M_SHvJ0H+7*&OJtGuwJP zB8!7u?Y_3AyZg|S2RB7|i1z-i6D1gWN0h&jKX@t}vY1@_?O{9eM=pMvT{n^jd$>T+ zO6x)dq_okZfkKXv>Ap7{q$vF1B|e{&T>tI!z^*!9UYT=pRV-=lXrl4-G@6bfvlicyBeTh7T4^Vn7vj@6*d_i8Q z7z1*ujQuk{sSCQmwkm`~DU9l7*9CyDU2f>3wE8%u;d+~uu3{|#+pny#re1tyc zhNgTswp=Oc*hY9Z;%+ZT9a=-iRn9$vF_a=>>@M}y7lqT!b+Vk1Smg#b|8RK?99xmv z#m@EvSyLESF?w4sD6!CLAG{Ib=pbh|JN_eiC5+ym$u`H5E9&-MxFUiUg1jd~Ym0z! zH`U`3OhzmP!+8UGx&rUW1J5rZB*yEgdX{lMmT26iF8yV1N}D|AYi^JLm6uxPo6Vq7 z-l`cnAq^S9&^aOTj65H4&n5#>?BRNH%{WU&271&mK5K0Q-s zC<7L{kDc`?Tja9?IK%mkATXmXt)lt_2qbTzEb?CW{G?AC*^PYY^OKWsdmRJmqtR{C zxt4qqPtGdWimkhYyb0-TO-=c9@BWdqn*@3D%iYTz5~>Qd##82>(wEYi{r{G~fUT9A zt!Bb(rzRw?oI4LHi_Cs2IZj6#qV-~L`?OQJ1Y?Y}41Ktv2Q5wXy?ay4D@p^KImnOv z3fZc`tWVdL>Pkg<=*Ags9cEZ`QVQ#?PidVKM=WIHTz<664P18J-$j6oYHz(`abu^eG0%6K5c0CXJkDMO}IgK2yFNAS@ z{@sQlJ%>^p%ag0Z(01vjRyMkb5Sx}>jL`vuLVI4B-ulfxMq@wiPzzIw09 z24gpZskZyj_q7ug^K7;jEavvd1A&Wj-U$cZKASg@}Jg2WNbh%Zs3 zh$FflUpyRh_zp(=^-5Ubdh044-Q(_e=m^=Fde_MV4!Q=51F1BuL(yBSX8vpgdi;yZ`p5TnWEHO=OE47tcnj z7EBu2taU;CsCZBAn*D}IE28(Xo>n&<)rJ)NCZo5Nh4Nf0%Y3nPjh|T|c5tq^Z?uEy zO6T=}?|@PGt2JElWo^pfBZ)P=JV~-er#h)W$K*4lm)r69#dvlRJTTmW0n^S>HqA8o zpGh7Q0>R&f&b~Gt;BlUNeglj_xINF5!8lMLa-@?rm3YkmTSh*j&5x*``Y>XyvDu{{ zBR!M-N&`k^HkwRZmjbJ+GJqF9kIH{J!W(w}a06&Yt?A5Vkrm7tVV=)HB7FzjQ!(0n z$Y$j8+Qo7SRKGBH=D$tf7xcD+W%N-^C^iz+_%YCHXH>=1$Xyy*>WAIPSjh9#0sq|I zSO56YmjVq;5&cr(*66qT4`GI3;zGfm&aE@;fzHcUp8D-{UBUW}j@f68@Y;8*q*Pih zlX`Y+%$gQect}MVC5-1xDZe>elVO}t#5wj&OZR><&sf?-ppHfR?&RVzTD+Z@;fja7 z(~FMa3_J)N!D6$T+v#Woqh}?b^Jbpcre>@?+a+-@h>tizU;2 zLhENZ=U(2RW_kr_9pOZ$M%?amPdh_PQ|J|t!*v{IQ1EJg&W2neE)?9)1xo`D7#Irz zPR}5%HoNlkkdPnjtOU|`avszl4mA%({(Ay3j6#daILZFcj3)(?@w-Sa)ijMQd&T- zW;jlD$Lonk6%>K%ULsyeIix-eii^|RPXRRM!~eBd=2c}(`loI2KPoSel= zNdw^iao2ILu<^g^uP1LLk>1vqupPu*e~mYfYpNc*(6=L`-!{-c?ckF$eH)G=!Oho@ zk~I2ST0_t!<@fgqZe&xxu6}CZMnc@*pQZnHm3Te#kR%Js#aVP)^iQo|N}&H0XTiT~ zKfyBU5eScR``PcVFqW$8^CRNhyX^4G@a&PB28sAjoB?;94M0;ke_Q|lej{I@U$1O8 zy+(EaV*#4{O;}LijTrI*)I;QXPQ#kf`jW0!v>iKSHv2;<9tyLD-CaV=yTjd%TymcXz%I8ZIz zFTBAa1O_2$UKc%QJ-*mG~MrbFjm!c97**4J<&^5>=1zE zJ02MD$B};3ufuo-f@K(yc)t3j08RInBn|RO#Z%yzZ7vgHw;D0$0Kqqih~7OuGXJWAf+g?5NPmmiNYsrS z^*k5TuzlxLm94Sf9jw2efCdJ^wt^^hYdw@0log^`fK70^z<^p8yHq-Sj;8_$pS$+df8dW>> z?7RvzG7Mf$bat>J$$$^Qe`S>n}hBIcWMJ3LH#pZ)l8&OUSd9Nhp z6BN+`a^v5Nk)i!V1Y+x8#S6He0Or^zr|YG?zyv}Ti9)8BaD~;FQn2Cd6lZasDWkDz znMuabnA-sXacee0I1roM_x{Ndd;MSp`@cb+(OLDpjZd|@y=4V|i1Q==`}+Bp(bn}3 z79MwSUU9-E7T2q&uJn)#-tB;9*UiKF%D|oVb>4 zt!Mu%{n@Zglw_C9)d ztp!5?}n9@t>M^<(n+mC`s$TYrMs52QNSxr`3fazYE+1 zb)k!*e7qQj>PF1CLwP@67Lq6Tz^ixZ>cWEP-tc32oZx8C9_jV_N<4l*(O;EJA|{Fe zx=0NxEE*ETKN3B&P*9t9P5|wOHR2upK2oW`)7aHu3sJ`aA?g%B{ApF*Xc*eD5732H z?OJsp^@vFVCWj`r0Sd`{MI-VcXy4Y|<`vrX$VgzqQMpkX7Lsq1Tj>7U7Y6I!i*`0j z1Y)J{asqC%!A!WQIQY}S+aVf=g^8mB*K<}sC_>0$sj3wH9$rd0FZl)M|LJDg$a}RX z&rSfg9xqyMLQtn(^!q3$s2+HmJZOvu!hzT$-+Dm+7s>~$RYdIN6n^jFZRF4MmOXJDZ^FNkV|i*8j;<&{ zdY#vM(DSFTe!%y3^p5`a2JH(NaEuQV8udF;3((bKW_b&R6>$T%?{9au2IS_cG-eAz zMtjlsJM91I_~{Dk?iHn-Lmt>ac}WB)v2iCp{BR0%Vm`dRH1OY52Szio(Zy1N3{aoA z;qQMdrgvZrlpR9p+h-McfwxH5hOANpzdCSD-wCU$Vg&oD;gsl=0=ls-bK4&+KyJ~Z z?ZSs^o`SyD_~Q2)6+cW+0ItI{ieT9P`vC3Rb(rngyvp(4LtFFp^2yCNij6>H4l*gq zd_J%X@_w`Yy78&|a#>?|cvl1;Uam%X{J$$C_qeH~8xrtpi7=-iuH3b_9nN+y{lxvW zqh)w_Jw*Ul@;ins0r8?gHk(Pl%f$vdaJmp~OpQ9?&++3f0Re?a*ey{jp#ng_MAQ;e zp%C6$A(E}@a*wbBHgBy&is6238A*{L1Hy=VMY2~25rAib9J>{>gkVMd8&c2&!yQ6E z86wgOFcZ5TCO&;me~2m4ozC+l$HAu@2i zmopdm{ba=tUle+KLWKQM;fMEXgSb;F2Uk5iu`r{QtI_E3Esbko*MirbEugS_!o2pX zN5$uJnlSCA7EaUP!(?jn;1EvqHDfx4Tl2~a5l(bKVDkbL4y2v?eVu)nLjr!ghr@87 zQ_OeLVN0p{3@gysx=Gsp34*t?U%qmLU8qc}hO_~uxEr@Uc=ofd&Hj@V8Fl@O3u)z2OJ84`fn@U4 qzhQe=S1$iOzov9$4((-C04%t2|EgQOa%w1mztbm;PUL7)uKzz(W|)Qm literal 0 HcmV?d00001 diff --git a/Projects/Governance/Icons/Programs/referral-program.png b/Projects/Governance/Icons/Programs/referral-program.png new file mode 100644 index 0000000000000000000000000000000000000000..b9d3765cf74aced6a7d7c8043ea170e154e4146a GIT binary patch literal 20204 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 literal 0 HcmV?d00001 diff --git a/Projects/Governance/Icons/Programs/staking-program.png b/Projects/Governance/Icons/Programs/staking-program.png new file mode 100644 index 0000000000000000000000000000000000000000..9ab9dadd6c8385816790221dd3075873d8c26c04 GIT binary patch literal 12357 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%0D$2z} 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

wnLl^%3x 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 sContribution Claims->Asset Contributions Folder->" + "compatibleTypes": "->Claims Program->Asset Contributions Folder->" }, "propertyNameAtParent": "assetContributionsFolder", "childrenNodesProperties": [ diff --git a/Projects/Governance/Schemas/App-Schema/contribution-claims.json b/Projects/Governance/Schemas/App-Schema/claims-program.json similarity index 94% rename from Projects/Governance/Schemas/App-Schema/contribution-claims.json rename to Projects/Governance/Schemas/App-Schema/claims-program.json index 50d309982..cfd71d2e9 100644 --- a/Projects/Governance/Schemas/App-Schema/contribution-claims.json +++ b/Projects/Governance/Schemas/App-Schema/claims-program.json @@ -1,5 +1,5 @@ { - "type": "Contribution Claims", + "type": "Claims Program", "menuItems": [ { "action": "Configure", @@ -47,11 +47,11 @@ "config": "{}" }, "attachingRules": { - "compatibleTypes": "->User Profile->" + "compatibleTypes": "->Token Switch->" }, "addLeftIcons": true, "level": 1, - "propertyNameAtParent": "contributionClaims", + "propertyNameAtParent": "claimsProgram", "childrenNodesProperties": [ { "name": "assetContributionsFolder", diff --git a/Projects/Governance/Schemas/App-Schema/feature-contributions-folder.json b/Projects/Governance/Schemas/App-Schema/feature-contributions-folder.json index eefd3ca61..c68c317a5 100644 --- a/Projects/Governance/Schemas/App-Schema/feature-contributions-folder.json +++ b/Projects/Governance/Schemas/App-Schema/feature-contributions-folder.json @@ -42,7 +42,7 @@ "addLeftIcons": true, "level": 2, "attachingRules": { - "compatibleTypes": "->Contribution Claims->Feature Contributions Folder->" + "compatibleTypes": "->Claims Program->Feature Contributions Folder->" }, "propertyNameAtParent": "featureContributionsFolder", "childrenNodesProperties": [ diff --git a/Projects/Governance/Schemas/App-Schema/mentorship-program.json b/Projects/Governance/Schemas/App-Schema/mentorship-program.json new file mode 100644 index 000000000..6c3f9263a --- /dev/null +++ b/Projects/Governance/Schemas/App-Schema/mentorship-program.json @@ -0,0 +1,51 @@ +{ + "type": "Mentorship Program", + "menuItems": [ + { + "action": "Configure", + "actionFunction": "uiObject.configEditor.activate", + "label": "Configure", + "iconPathOn": "configuration", + "iconPathOff": "configuration" + }, + { + "action": "Add UI Object", + "actionProject": "Foundations", + "disableIfPropertyIsDefined": true, + "propertyToCheckFor": "userMentor", + "actionFunction": "payload.executeAction", + "label": "Add User Mentor", + "relatedUiObject": "User Mentor" + }, + { + "action": "Delete UI Object", + "actionProject": "Foundations", + "askConfirmation": true, + "confirmationLabel": "Confirm to Delete", + "label": "Delete", + "iconPathOn": "delete-entity", + "iconPathOff": "delete-entity", + "actionFunction": "payload.executeAction" + } + ], + "editors": { + "config": true + }, + "initialValues": { + "config": "{}" + }, + "attachingRules": { + "compatibleTypes": "->Token Switch->" + }, + "addLeftIcons": true, + "level": 1, + "propertyNameAtParent": "mentorshipProgram", + "childrenNodesProperties": [ + { + "name": "userMentors", + "type": "array", + "childType": "User Mentor", + "autoAdd": false + } + ] +} \ No newline at end of file diff --git a/Projects/Governance/Schemas/App-Schema/position-contributions-folder.json b/Projects/Governance/Schemas/App-Schema/position-contributions-folder.json index 5cd5b5d86..36390af05 100644 --- a/Projects/Governance/Schemas/App-Schema/position-contributions-folder.json +++ b/Projects/Governance/Schemas/App-Schema/position-contributions-folder.json @@ -42,7 +42,7 @@ "addLeftIcons": true, "level": 2, "attachingRules": { - "compatibleTypes": "->Contribution Claims->Position Contributions Folder->" + "compatibleTypes": "->Claims Program->Position Contributions Folder->" }, "propertyNameAtParent": "positionContributionsFolder", "childrenNodesProperties": [ diff --git a/Projects/Governance/Schemas/App-Schema/referring-program.json b/Projects/Governance/Schemas/App-Schema/referring-program.json new file mode 100644 index 000000000..df7a8f384 --- /dev/null +++ b/Projects/Governance/Schemas/App-Schema/referring-program.json @@ -0,0 +1,51 @@ +{ + "type": "Referral Program", + "menuItems": [ + { + "action": "Configure", + "actionFunction": "uiObject.configEditor.activate", + "label": "Configure", + "iconPathOn": "configuration", + "iconPathOff": "configuration" + }, + { + "action": "Add UI Object", + "actionProject": "Foundations", + "disableIfPropertyIsDefined": true, + "propertyToCheckFor": "userReferrer", + "actionFunction": "payload.executeAction", + "label": "Add User Referrer", + "relatedUiObject": "User Referrer" + }, + { + "action": "Delete UI Object", + "actionProject": "Foundations", + "askConfirmation": true, + "confirmationLabel": "Confirm to Delete", + "label": "Delete", + "iconPathOn": "delete-entity", + "iconPathOff": "delete-entity", + "actionFunction": "payload.executeAction" + } + ], + "editors": { + "config": true + }, + "initialValues": { + "config": "{}" + }, + "attachingRules": { + "compatibleTypes": "->Token Switch->" + }, + "addLeftIcons": true, + "level": 1, + "propertyNameAtParent": "referralProgram", + "childrenNodesProperties": [ + { + "name": "userReferrer", + "type": "node", + "childType": "User Referrer", + "autoAdd": true + } + ] +} \ No newline at end of file diff --git a/Projects/Governance/Schemas/App-Schema/staking-program.json b/Projects/Governance/Schemas/App-Schema/staking-program.json new file mode 100644 index 000000000..8c9d03a2c --- /dev/null +++ b/Projects/Governance/Schemas/App-Schema/staking-program.json @@ -0,0 +1,34 @@ +{ + "type": "Staking Program", + "menuItems": [ + { + "action": "Configure", + "actionFunction": "uiObject.configEditor.activate", + "label": "Configure", + "iconPathOn": "configuration", + "iconPathOff": "configuration" + }, + { + "action": "Delete UI Object", + "actionProject": "Foundations", + "askConfirmation": true, + "confirmationLabel": "Confirm to Delete", + "label": "Delete", + "iconPathOn": "delete-entity", + "iconPathOff": "delete-entity", + "actionFunction": "payload.executeAction" + } + ], + "editors": { + "config": true + }, + "initialValues": { + "config": "{}" + }, + "attachingRules": { + "compatibleTypes": "->Token Switch->" + }, + "addLeftIcons": true, + "level": 1, + "propertyNameAtParent": "stakingProgram" +} \ No newline at end of file diff --git a/Projects/Governance/Schemas/App-Schema/support-program.json b/Projects/Governance/Schemas/App-Schema/support-program.json new file mode 100644 index 000000000..05c44007c --- /dev/null +++ b/Projects/Governance/Schemas/App-Schema/support-program.json @@ -0,0 +1,51 @@ +{ + "type": "Support Program", + "menuItems": [ + { + "action": "Configure", + "actionFunction": "uiObject.configEditor.activate", + "label": "Configure", + "iconPathOn": "configuration", + "iconPathOff": "configuration" + }, + { + "action": "Add UI Object", + "actionProject": "Foundations", + "disableIfPropertyIsDefined": true, + "propertyToCheckFor": "userSupport", + "actionFunction": "payload.executeAction", + "label": "Add User Support", + "relatedUiObject": "User Support" + }, + { + "action": "Delete UI Object", + "actionProject": "Foundations", + "askConfirmation": true, + "confirmationLabel": "Confirm to Delete", + "label": "Delete", + "iconPathOn": "delete-entity", + "iconPathOff": "delete-entity", + "actionFunction": "payload.executeAction" + } + ], + "editors": { + "config": true + }, + "initialValues": { + "config": "{}" + }, + "attachingRules": { + "compatibleTypes": "->Token Switch->" + }, + "addLeftIcons": true, + "level": 1, + "propertyNameAtParent": "supportProgram", + "childrenNodesProperties": [ + { + "name": "userSupports", + "type": "array", + "childType": "User Support", + "autoAdd": false + } + ] +} \ No newline at end of file diff --git a/Projects/Governance/Schemas/App-Schema/tokensSwitch.json b/Projects/Governance/Schemas/App-Schema/tokensSwitch.json new file mode 100644 index 000000000..caad9fc1d --- /dev/null +++ b/Projects/Governance/Schemas/App-Schema/tokensSwitch.json @@ -0,0 +1,126 @@ +{ + "type": "Token Switch", + "menuItems": [ + { + "action": "Configure", + "actionFunction": "uiObject.configEditor.activate", + "label": "Configure", + "iconPathOn": "configuration", + "iconPathOff": "configuration" + }, + { + "action": "Add UI Object", + "actionProject": "Foundations", + "actionFunction": "payload.executeAction", + "disableIfPropertyIsDefined": true, + "propertyToCheckFor": "referralProgram", + "label": "Add Referral Program", + "relatedUiObject": "Referral Program" + }, + { + "action": "Add UI Object", + "actionProject": "Foundations", + "actionFunction": "payload.executeAction", + "disableIfPropertyIsDefined": true, + "propertyToCheckFor": "mentorshipProgram", + "label": "Add Mentorship Program", + "relatedUiObject": "Mentorship Program" + }, + { + "action": "Add UI Object", + "actionProject": "Foundations", + "actionFunction": "payload.executeAction", + "disableIfPropertyIsDefined": true, + "propertyToCheckFor": "supportProgram", + "label": "Add Support Program", + "relatedUiObject": "Support Program" + }, + { + "action": "Add UI Object", + "actionProject": "Voting Program", + "actionFunction": "payload.executeAction", + "disableIfPropertyIsDefined": true, + "propertyToCheckFor": "votingProgram", + "label": "Add Voting Program", + "relatedUiObject": "Voting Program" + }, + { + "action": "Add UI Object", + "actionProject": "Foundations", + "actionFunction": "payload.executeAction", + "disableIfPropertyIsDefined": true, + "propertyToCheckFor": "claimsProgram", + "label": "Add Claims Program", + "relatedUiObject": "Claims Program" + }, + { + "action": "Add UI Object", + "actionProject": "Foundations", + "actionFunction": "payload.executeAction", + "disableIfPropertyIsDefined": true, + "propertyToCheckFor": "stakingProgram", + "label": "Add Staking Program", + "relatedUiObject": "Staking Program" + }, + { + "action": "Delete UI Object", + "actionProject": "Foundations", + "askConfirmation": true, + "confirmationLabel": "Confirm to Delete", + "label": "Delete", + "iconPathOn": "delete-entity", + "iconPathOff": "delete-entity", + "actionFunction": "payload.executeAction" + } + ], + "editors": { + "config": true + }, + "initialValues": { + "config": "{}" + }, + "addLeftIcons": true, + "level": 2, + "attachingRules": { + "compatibleTypes": "->User Profile->" + }, + "propertyNameAtParent": "tokenSwitch", + "childrenNodesProperties": [ + { + "name": "referralProgram", + "type": "node", + "childType": "Referral Program", + "autoAdd": true + }, + { + "name": "mentorshipProgram", + "type": "node", + "childType": "Mentorship Program", + "autoAdd": true + }, + { + "name": "supportProgram", + "type": "node", + "childType": "Support Program", + "autoAdd": true + }, + { + "name": "votingProgram", + "type": "node", + "childType": "Voting Program", + "autoAdd": true + }, + { + "name": "claimsProgram", + "type": "node", + "childType": "Claims Program", + "autoAdd": true + }, + { + "name": "stakingProgram", + "type": "node", + "childType": "Staking Program", + "autoAdd": true + } + ] +} \ No newline at end of file diff --git a/Projects/Governance/Schemas/App-Schema/user-mentor.json b/Projects/Governance/Schemas/App-Schema/user-mentor.json new file mode 100644 index 000000000..60f4577a1 --- /dev/null +++ b/Projects/Governance/Schemas/App-Schema/user-mentor.json @@ -0,0 +1,40 @@ +{ + "type": "User Mentor", + "menuItems": [ + { + "action": "Configure", + "actionFunction": "uiObject.configEditor.activate", + "label": "Configure", + "iconPathOn": "configuration", + "iconPathOff": "configuration" + }, + { + "action": "Delete UI Object", + "actionProject": "Foundations", + "askConfirmation": true, + "confirmationLabel": "Confirm to Delete", + "label": "Delete", + "iconPathOn": "delete-entity", + "iconPathOff": "delete-entity", + "actionFunction": "payload.executeAction" + } + ], + "title": [ + "Use Reference Parent" + ], + "editors": { + "config": true + }, + "initialValues": { + "config": "{}" + }, + "addLeftIcons": true, + "level": 2, + "attachingRules": { + "compatibleTypes": "->mentorship Program->" + }, + "referencingRules": { + "compatibleTypes": "->User Profile->" + }, + "propertyNameAtParent": "userMentors" +} \ No newline at end of file diff --git a/Projects/Governance/Schemas/App-Schema/user-profile.json b/Projects/Governance/Schemas/App-Schema/user-profile.json index 53f1dafea..938527f3b 100644 --- a/Projects/Governance/Schemas/App-Schema/user-profile.json +++ b/Projects/Governance/Schemas/App-Schema/user-profile.json @@ -12,28 +12,10 @@ "action": "Add UI Object", "actionProject": "Foundations", "disableIfPropertyIsDefined": true, - "propertyToCheckFor": "contributionClaims", + "propertyToCheckFor": "tokenSwitch", "actionFunction": "payload.executeAction", - "label": "Add Contribution Claims", - "relatedUiObject": "Contribution Claims" - }, - { - "action": "Add UI Object", - "actionProject": "Foundations", - "disableIfPropertyIsDefined": true, - "propertyToCheckFor": "votesDistribution", - "actionFunction": "payload.executeAction", - "label": "Add Votes Distribution", - "relatedUiObject": "Votes Distribution" - }, - { - "action": "Add UI Object", - "actionProject": "Foundations", - "disableIfPropertyIsDefined": true, - "propertyToCheckFor": "userReferrer", - "actionFunction": "payload.executeAction", - "label": "Add User Referrer", - "relatedUiObject": "User Referrer" + "label": "Add Token Switch", + "relatedUiObject": "Token Switch" }, { "action": "Delete UI Object", @@ -50,7 +32,7 @@ "config": true }, "initialValues": { - "config": "{\n\"codeName\": \"\"\n}" + "config": "{}" }, "isTitleAllwaysVisible": false, "isHierarchyHead": true, @@ -58,22 +40,10 @@ "level": 0, "childrenNodesProperties": [ { - "name": "contributionClaims", + "name": "tokenSwitch", "type": "node", - "childType": "Contribution Claims", - "autoAdd": false - }, - { - "name": "votesDistribution", - "type": "node", - "childType": "Votes Distribution", - "autoAdd": false - }, - { - "name": "userReferrer", - "type": "node", - "childType": "User Referrer", - "autoAdd": false + "childType": "Token Switch", + "autoAdd": true } ] } \ No newline at end of file diff --git a/Projects/Governance/Schemas/App-Schema/user-referrer.json b/Projects/Governance/Schemas/App-Schema/user-referrer.json index 4c04c2b59..4f300213e 100644 --- a/Projects/Governance/Schemas/App-Schema/user-referrer.json +++ b/Projects/Governance/Schemas/App-Schema/user-referrer.json @@ -26,12 +26,12 @@ "config": true }, "initialValues": { - "config": "{\n \"description\": \"\"\n}" + "config": "{}" }, "addLeftIcons": true, "level": 2, "attachingRules": { - "compatibleTypes": "->User Profile->" + "compatibleTypes": "->Referral Program->" }, "referencingRules": { "compatibleTypes": "->User Profile->" diff --git a/Projects/Governance/Schemas/App-Schema/userSupport.json b/Projects/Governance/Schemas/App-Schema/userSupport.json new file mode 100644 index 000000000..caa0d2478 --- /dev/null +++ b/Projects/Governance/Schemas/App-Schema/userSupport.json @@ -0,0 +1,40 @@ +{ + "type": "User Support", + "menuItems": [ + { + "action": "Configure", + "actionFunction": "uiObject.configEditor.activate", + "label": "Configure", + "iconPathOn": "configuration", + "iconPathOff": "configuration" + }, + { + "action": "Delete UI Object", + "actionProject": "Foundations", + "askConfirmation": true, + "confirmationLabel": "Confirm to Delete", + "label": "Delete", + "iconPathOn": "delete-entity", + "iconPathOff": "delete-entity", + "actionFunction": "payload.executeAction" + } + ], + "title": [ + "Use Reference Parent" + ], + "editors": { + "config": true + }, + "initialValues": { + "config": "{}" + }, + "addLeftIcons": true, + "level": 2, + "attachingRules": { + "compatibleTypes": "->support Program->" + }, + "referencingRules": { + "compatibleTypes": "->User Profile->" + }, + "propertyNameAtParent": "userSupports" +} \ No newline at end of file diff --git a/Projects/Governance/Schemas/App-Schema/votes-switch.json b/Projects/Governance/Schemas/App-Schema/votes-switch.json index bd97acfbf..3437ff59a 100644 --- a/Projects/Governance/Schemas/App-Schema/votes-switch.json +++ b/Projects/Governance/Schemas/App-Schema/votes-switch.json @@ -65,7 +65,7 @@ "addLeftIcons": true, "level": 2, "attachingRules": { - "compatibleTypes": "->Votes Distribution->Votes Switch->" + "compatibleTypes": "->Voting Program->Votes Switch->" }, "propertyNameAtParent": "votesSwitch", "childrenNodesProperties": [ diff --git a/Projects/Governance/Schemas/App-Schema/votes-distribution.json b/Projects/Governance/Schemas/App-Schema/voting-program.json similarity index 72% rename from Projects/Governance/Schemas/App-Schema/votes-distribution.json rename to Projects/Governance/Schemas/App-Schema/voting-program.json index 6cb033b94..32790eaed 100644 --- a/Projects/Governance/Schemas/App-Schema/votes-distribution.json +++ b/Projects/Governance/Schemas/App-Schema/voting-program.json @@ -1,5 +1,5 @@ { - "type": "Votes Distribution", + "type": "Voting Program", "menuItems": [ { "action": "Configure", @@ -15,15 +15,6 @@ "label": "Add Votes Switch", "relatedUiObject": "Votes Switch" }, - { - "action": "Add UI Object", - "actionProject": "Foundations", - "disableIfPropertyIsDefined": true, - "propertyToCheckFor": "userReferrer", - "actionFunction": "payload.executeAction", - "label": "Add User Referrer", - "relatedUiObject": "User Referrer" - }, { "action": "Delete UI Object", "actionProject": "Foundations", @@ -42,11 +33,11 @@ "config": "{}" }, "attachingRules": { - "compatibleTypes": "->User Profile->" + "compatibleTypes": "->Token Switch->" }, "addLeftIcons": true, "level": 1, - "propertyNameAtParent": "votesDistribution", + "propertyNameAtParent": "votingProgram", "childrenNodesProperties": [ { "name": "votesSwitch", diff --git a/Projects/Governance/Schemas/Docs-Nodes/C/Contribution/Contribution-Claims/contribution-claims.json b/Projects/Governance/Schemas/Docs-Nodes/C/Contribution/Contribution-Claims/contribution-claims.json index 2ec3b147f..0f38bc9ea 100644 --- a/Projects/Governance/Schemas/Docs-Nodes/C/Contribution/Contribution-Claims/contribution-claims.json +++ b/Projects/Governance/Schemas/Docs-Nodes/C/Contribution/Contribution-Claims/contribution-claims.json @@ -1,5 +1,5 @@ { - "type": "Contribution Claims", + "type": "Claims Program", "definition": { "text": "This node helps define the section of the User Profiel hierarchy that is going to be used to define the claims users make for the contributions they have done. These claims need later to be voted by other users in order to be considered during the token distribution process.", "updated": 1622989461838 diff --git a/Projects/Governance/Schemas/Docs-Nodes/U/User/User-Profile/user-profile.json b/Projects/Governance/Schemas/Docs-Nodes/U/User/User-Profile/user-profile.json index bc21b5fbe..b3a567301 100644 --- a/Projects/Governance/Schemas/Docs-Nodes/U/User/User-Profile/user-profile.json +++ b/Projects/Governance/Schemas/Docs-Nodes/U/User/User-Profile/user-profile.json @@ -1,7 +1,7 @@ { "type": "User Profile", "definition": { - "text": "At these hierarchies, users define their profile, which essentially means declaring which are their contribution claims, and which is the way they would like to distribute their voting power. From each user profile starts a stream of votes that flows through switches that split these streams according to the user preferences and end up at other hierarchies's nodes, who are the recipient of these votes. ", + "text": "At these hierarchies, users define their profile, which essentially means declaring which are their Claims Program, and which is the way they would like to distribute their voting power. From each user profile starts a stream of votes that flows through switches that split these streams according to the user preferences and end up at other hierarchies's nodes, who are the recipient of these votes. ", "updated": 1622988108578 }, "paragraphs": [ diff --git a/Projects/Governance/Schemas/Docs-Nodes/V/Votes/Votes-Distribution/votes-distribution.json b/Projects/Governance/Schemas/Docs-Nodes/V/Votes/Votes-Distribution/votes-distribution.json index fb7eefb6d..672e68c22 100644 --- a/Projects/Governance/Schemas/Docs-Nodes/V/Votes/Votes-Distribution/votes-distribution.json +++ b/Projects/Governance/Schemas/Docs-Nodes/V/Votes/Votes-Distribution/votes-distribution.json @@ -1,5 +1,5 @@ { - "type": "Votes Distribution", + "type": "Voting Program", "definition": { "text": "This node defined the section where votes are going to flow like vote-streams, going through Votes Swithces and several different types of Vote nodes. Via references they are later sent to recipient nodes living at other hierarchies.", "updated": 1622989230849 diff --git a/Projects/Governance/UI/Function-Libraries/Claims.js b/Projects/Governance/UI/Function-Libraries/Claims.js index 4a5fb6fdf..a048f246e 100644 --- a/Projects/Governance/UI/Function-Libraries/Claims.js +++ b/Projects/Governance/UI/Function-Libraries/Claims.js @@ -40,13 +40,13 @@ function newGovernanceFunctionLibraryClaims() { }, count: 0 } - countForNode(userProfilesNode.contributionClaims) + countForNode(userProfilesNode.claimsProgram) } /* Claim Calculation Follows */ for (let i = 0; i < userProfiles.length; i++) { let userProfilesNode = userProfiles[i] - calculateForNode(userProfilesNode.contributionClaims, userProfilesNode) + calculateForNode(userProfilesNode.claimsProgram, userProfilesNode) } } @@ -102,7 +102,7 @@ function newGovernanceFunctionLibraryClaims() { node.type !== 'Asset Contributions Folder' && node.type !== 'Feature Contributions Folder' && node.type !== 'Position Contributions Folder' && - node.type !== 'Contribution Claims' + node.type !== 'Claims Program' ) { if (node.payload.claims === undefined) { node.payload.claims = { @@ -170,7 +170,7 @@ function newGovernanceFunctionLibraryClaims() { node.type !== 'Asset Contributions Folder' && node.type !== 'Feature Contributions Folder' && node.type !== 'Position Contributions Folder' && - node.type !== 'Contribution Claims' + node.type !== 'Claims Program' ) { if ( node.payload.claims !== undefined && diff --git a/Projects/Governance/UI/Function-Libraries/Tokens.js b/Projects/Governance/UI/Function-Libraries/Tokens.js index a41f1d8fc..35ec03401 100644 --- a/Projects/Governance/UI/Function-Libraries/Tokens.js +++ b/Projects/Governance/UI/Function-Libraries/Tokens.js @@ -71,7 +71,7 @@ function newGovernanceFunctionLibraryTokens() { switch (property.type) { case 'node': { - if (node.type === 'Pools' && property.name === "votesDistribution") { + if (node.type === 'Pools' && property.name === "votingProgram") { let childNode = node[property.name] resetTokenFlow(childNode) } @@ -142,7 +142,7 @@ function newGovernanceFunctionLibraryTokens() { switch (property.type) { case 'node': { - if (node.type === 'Pools' && property.name === "votesDistribution") { + if (node.type === 'Pools' && property.name === "votingProgram") { let childNode = node[property.name] distributeTokens(childNode, tokens) } diff --git a/Projects/Governance/UI/Function-Libraries/Votes.js b/Projects/Governance/UI/Function-Libraries/Votes.js index 13da3b0a0..416a6e4e0 100644 --- a/Projects/Governance/UI/Function-Libraries/Votes.js +++ b/Projects/Governance/UI/Function-Libraries/Votes.js @@ -89,11 +89,11 @@ function newGovernanceFunctionLibraryVotes() { for (let i = 0; i < schemaDocument.childrenNodesProperties.length; i++) { let property = schemaDocument.childrenNodesProperties[i] - if (node.type === 'User Profile' && property.name !== "votesDistribution") { continue } + if (node.type === 'User Profile' && property.name !== "votingProgram") { continue } switch (property.type) { case 'node': { - if (node.type === 'User Profile' && property.name === "votesDistribution") { + if (node.type === 'User Profile' && property.name === "votingProgram") { let childNode = node[property.name] resetVotes(childNode) } @@ -176,11 +176,11 @@ function newGovernanceFunctionLibraryVotes() { for (let i = 0; i < schemaDocument.childrenNodesProperties.length; i++) { let property = schemaDocument.childrenNodesProperties[i] - if (node.type === 'User Profile' && property.name !== "votesDistribution") { continue } + if (node.type === 'User Profile' && property.name !== "votingProgram") { continue } switch (property.type) { case 'node': { - if (node.type === 'User Profile' && property.name === "votesDistribution") { + if (node.type === 'User Profile' && property.name === "votingProgram") { let childNode = node[property.name] if (childNode === undefined) { continue } let percentage = UI.projects.foundations.utilities.nodeConfig.loadConfigProperty(childNode.payload, 'percentage') @@ -224,11 +224,11 @@ function newGovernanceFunctionLibraryVotes() { for (let i = 0; i < schemaDocument.childrenNodesProperties.length; i++) { let property = schemaDocument.childrenNodesProperties[i] - if (node.type === 'User Profile' && property.name !== "votesDistribution") { continue } + if (node.type === 'User Profile' && property.name !== "votingProgram") { continue } switch (property.type) { case 'node': { - if (node.type === 'User Profile' && property.name === "votesDistribution") { + if (node.type === 'User Profile' && property.name === "votingProgram") { let childNode = node[property.name] if (childNode === undefined) { continue } let percentage = UI.projects.foundations.utilities.nodeConfig.loadConfigProperty(childNode.payload, 'percentage') From b8409025f38934c7a1bbdfe20ea4baf2537b49ab Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Wed, 16 Jun 2021 13:53:51 +0200 Subject: [PATCH 5/9] Governance Token Power Distribution Implemented --- .../Function-Libraries/DistributionProcess.js | 4 + .../UI/Function-Libraries/TokenPower.js | 248 ++++++++++++++++++ .../Spaces/User-Profile-Space/UserProfile.js | 3 +- Projects/ProjectsSchema.json | 5 + 4 files changed, 258 insertions(+), 2 deletions(-) create mode 100644 Projects/Governance/UI/Function-Libraries/TokenPower.js diff --git a/Projects/Governance/UI/Function-Libraries/DistributionProcess.js b/Projects/Governance/UI/Function-Libraries/DistributionProcess.js index 13e621677..2fc2f894b 100644 --- a/Projects/Governance/UI/Function-Libraries/DistributionProcess.js +++ b/Projects/Governance/UI/Function-Libraries/DistributionProcess.js @@ -13,6 +13,10 @@ function newGovernanceFunctionLibraryDistributionProcess() { let positions = UI.projects.foundations.spaces.designSpace.workspace.getHierarchyHeadsByNodeType('Positions') let userProfiles = UI.projects.foundations.spaces.designSpace.workspace.getHierarchyHeadsByNodeType('User Profile') + UI.projects.governance.functionLibraries.tokenPower.calculate( + userProfiles + ) + UI.projects.governance.functionLibraries.votes.calculate( pools, features, diff --git a/Projects/Governance/UI/Function-Libraries/TokenPower.js b/Projects/Governance/UI/Function-Libraries/TokenPower.js new file mode 100644 index 000000000..ea196c329 --- /dev/null +++ b/Projects/Governance/UI/Function-Libraries/TokenPower.js @@ -0,0 +1,248 @@ +function newGovernanceFunctionLibraryTokenPower() { + let thisObject = { + calculate: calculate + } + + return thisObject + + function calculate( + userProfiles + ) { + /* + We will first reset all the token power, and then distribute it to each Program. + */ + for (let i = 0; i < userProfiles.length; i++) { + let userProfile = userProfiles[i] + resetTokenPower(userProfile) + } + for (let i = 0; i < userProfiles.length; i++) { + let userProfile = userProfiles[i] + distributeForProfile(userProfile) + } + + function resetTokenPower(node) { + if (node === undefined) { return } + if (node.payload === undefined) { return } + node.payload.tokenPower = 0 + /* + When we reach certain node types, we will halt the distribution, because these are targets for + token power. + */ + if ( + node.type === 'Referral Program' || + node.type === 'Mentorship Program' || + node.type === 'Support Program' || + node.type === 'Voting Program' || + node.type === 'Claims Program' || + node.type === 'Staking Program' + ) { return } + /* + We will reset token power of children. + */ + let schemaDocument = getSchemaDocument(node) + if (schemaDocument === undefined) { return } + + if (schemaDocument.childrenNodesProperties !== undefined) { + for (let i = 0; i < schemaDocument.childrenNodesProperties.length; i++) { + let property = schemaDocument.childrenNodesProperties[i] + + switch (property.type) { + case 'node': { + let childNode = node[property.name] + resetTokenPower(childNode) + } + break + case 'array': { + let propertyArray = node[property.name] + if (propertyArray !== undefined) { + for (let m = 0; m < propertyArray.length; m++) { + let childNode = propertyArray[m] + resetTokenPower(childNode) + } + } + break + } + } + } + } + } + + function distributeForProfile(userProfile) { + if (userProfile.payload === undefined) { return } + let tokenPower + if (userProfile.payload.blockchainTokens === undefined) { + return + } else { + tokenPower = userProfile.payload.blockchainTokens + } + /* + Before we start we will do some validations: + */ + if (userProfile.tokenSwitch === undefined) { + userProfile.payload.uiObject.setErrorMessage("You need to have a Token Switch child node.") + return + } + if (userProfile.tokenSwitch.referralProgram === undefined) { + userProfile.tokenSwitch.payload.uiObject.setErrorMessage("You need to have a Referral Program child node.") + return + } + if (userProfile.tokenSwitch.mentorshipProgram === undefined) { + userProfile.tokenSwitch.payload.uiObject.setErrorMessage("You need to have a Mentorship Program child node.") + return + } + if (userProfile.tokenSwitch.supportProgram === undefined) { + userProfile.tokenSwitch.payload.uiObject.setErrorMessage("You need to have a Spupport Program child node.") + return + } + + distributeTokenPower(userProfile, tokenPower) + } + + function distributeTokenPower(node, tokenPower, switchPercentage) { + if (node === undefined) { return } + if (node.payload === undefined) { return } + node.payload.tokenPower = node.payload.tokenPower + tokenPower + drawTokenPower(node, node.payload.tokenPower, switchPercentage) + /* + When we reach certain node types, we will halt the distribution, + because these are targets for token power. + */ + if ( + node.type === 'Referral Program' || + node.type === 'Mentorship Program' || + node.type === 'Support Program' || + node.type === 'Voting Program' || + node.type === 'Claims Program' || + node.type === 'Staking Program' + ) { return } + /* + We will redistribute token power among children. + */ + let schemaDocument = getSchemaDocument(node) + if (schemaDocument === undefined) { return } + + if (schemaDocument.childrenNodesProperties !== undefined) { + /* + Before distributing the token power, we will calculate how the power + is going to be switched between all nodes. The first pass is about + scanning all sibling nodes to see which ones have a percentage defined + at their config, and check that all percentages don't add more than 100. + */ + let totalPercentage = 0 + let totalNodesWithoutPercentage = 0 + for (let i = 0; i < schemaDocument.childrenNodesProperties.length; i++) { + let property = schemaDocument.childrenNodesProperties[i] + + switch (property.type) { + case 'node': { + let childNode = node[property.name] + if (childNode === undefined) { continue } + let percentage = getPercentage(childNode) + + if (percentage !== undefined && isNaN(percentage) !== true) { + totalPercentage = totalPercentage + percentage + } else { + totalNodesWithoutPercentage++ + } + } + break + case 'array': { + let propertyArray = node[property.name] + if (propertyArray !== undefined) { + for (let m = 0; m < propertyArray.length; m++) { + let childNode = propertyArray[m] + if (childNode === undefined) { continue } + let percentage = getPercentage(childNode) + if (percentage !== undefined && isNaN(percentage) !== true) { + totalPercentage = totalPercentage + percentage + } else { + totalNodesWithoutPercentage++ + } + } + } + break + } + } + } + if (totalPercentage > 100) { + node.payload.uiObject.setErrorMessage('Token Power Switching Error. Total Percentage of children nodes is grater that 100.') + return + } + let defaultPercentage = 0 + if (totalNodesWithoutPercentage > 0) { + defaultPercentage = (100 - totalPercentage) / totalNodesWithoutPercentage + } + /* + Here we do the actual distribution. + */ + for (let i = 0; i < schemaDocument.childrenNodesProperties.length; i++) { + let property = schemaDocument.childrenNodesProperties[i] + + switch (property.type) { + case 'node': { + let childNode = node[property.name] + if (childNode === undefined) { continue } + let percentage = getPercentage(childNode) + if (percentage === undefined || isNaN(percentage) === true) { + percentage = defaultPercentage + } + distributeTokenPower(childNode, tokenPower * percentage / 100, percentage) + } + break + case 'array': { + let propertyArray = node[property.name] + if (propertyArray !== undefined) { + for (let m = 0; m < propertyArray.length; m++) { + let childNode = propertyArray[m] + if (childNode === undefined) { continue } + let percentage = getPercentage(childNode) + if (percentage === undefined || isNaN(percentage) === true) { + percentage = defaultPercentage + } + distributeTokenPower(childNode, tokenPower * percentage / 100, percentage) + } + } + break + } + } + } + } + } + + function getPercentage(node) { + /* + There are some system wide rules regarfing mandatory percentages, + we will apply them now. + */ + switch (node.type) { + case 'Referral Program': { + return 20 + } + case 'Mentorship Program': { + return 10 + } + case 'Support Program': { + return 10 + } + default: return UI.projects.foundations.utilities.nodeConfig.loadConfigProperty(node.payload, 'percentage') + } + } + + function drawTokenPower(node, tokenPower, percentage) { + tokenPower = new Intl.NumberFormat().format(tokenPower) + ' ' + 'Token Power' + if (node.payload !== undefined) { + if (node.type === 'User Profile') { + return + } + node.payload.uiObject.valueAngleOffset = 180 + node.payload.uiObject.valueAtAngle = true + + node.payload.uiObject.setValue(tokenPower) + + if (percentage !== undefined) { + node.payload.uiObject.setPercentage(percentage.toFixed(2)) + } + } + } + } +} \ No newline at end of file diff --git a/Projects/Governance/UI/Spaces/User-Profile-Space/UserProfile.js b/Projects/Governance/UI/Spaces/User-Profile-Space/UserProfile.js index f9dd1c21d..1a5425677 100644 --- a/Projects/Governance/UI/Spaces/User-Profile-Space/UserProfile.js +++ b/Projects/Governance/UI/Spaces/User-Profile-Space/UserProfile.js @@ -53,7 +53,6 @@ function newGovernanceUserProfileSpace() { if (userProfile.payload === undefined) { continue } if (userProfile.payload.blockchainTokens === undefined) { - //userProfile.payload.blockchainTokens = UI.projects.foundations.utilities.nodeConfig.loadConfigProperty(userProfile.payload, 'tokens') getBlockchainAccount(userProfile) } } @@ -114,7 +113,7 @@ function newGovernanceUserProfileSpace() { userProfile.payload.blockchainTokens = Number(data.result) / 1000000000000000000 waitingForResponses-- }).catch(function (err) { - const message = err.message + ' - ' + 'Can not access BSC SCAN servers. Using tokens Config Property instead of blockchain data.' + const message = err.message + ' - ' + 'Can not access BSC SCAN servers.' console.log(message) userProfile.payload.uiObject.setErrorMessage(message, 1000) waitingForResponses-- diff --git a/Projects/ProjectsSchema.json b/Projects/ProjectsSchema.json index 246b26fca..76c98a4f6 100644 --- a/Projects/ProjectsSchema.json +++ b/Projects/ProjectsSchema.json @@ -963,6 +963,11 @@ "propertyName": "assets", "functionName": "newGovernanceFunctionLibraryAssets" }, + { + "name": "TokenPower", + "propertyName": "tokenPower", + "functionName": "newGovernanceFunctionLibraryTokenPower" + }, { "name": "Votes", "propertyName": "votes", From ac38f35c68a61e05caa7a3fae49880d55719c53d Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Wed, 16 Jun 2021 18:41:21 +0200 Subject: [PATCH 6/9] Voting Program Fixed --- .../User-Profiles/Luis-Fernando-Molina.json | 1267 ++++++++++++++++- .../Governance/UI/Function-Libraries/Votes.js | 30 +- 2 files changed, 1284 insertions(+), 13 deletions(-) diff --git a/Projects/Governance/Plugins/User-Profiles/Luis-Fernando-Molina.json b/Projects/Governance/Plugins/User-Profiles/Luis-Fernando-Molina.json index db41bff80..e15103c2c 100644 --- a/Projects/Governance/Plugins/User-Profiles/Luis-Fernando-Molina.json +++ b/Projects/Governance/Plugins/User-Profiles/Luis-Fernando-Molina.json @@ -99,7 +99,1272 @@ "name": "New Voting Program", "config": "{}", "project": "Governance", - "votesSwitch": [], + "votesSwitch": [ + { + "type": "Votes Switch", + "name": "New Votes Switch", + "config": "{}", + "project": "Governance", + "votesSwitch": [], + "claimVotesSwitch": [], + "weightVotesSwitch": [ + { + "type": "Weight Votes Switch", + "name": "New Weight Votes Switch", + "config": "{}", + "project": "Governance", + "weightVotesSwitch": [ + { + "type": "Weight Votes Switch", + "name": "Superalgos Pools", + "config": "{}", + "project": "Governance", + "weightVotesSwitch": [ + { + "type": "Weight Votes Switch", + "name": "Software Pool Class", + "config": "{}", + "project": "Governance", + "weightVotesSwitch": [], + "poolWeightVotes": [ + { + "type": "Pool Weight Vote", + "name": "Foundations Project Pool", + "config": "{}", + "project": "Governance", + "id": "f24631c9-92f7-40ec-af18-f32e5e200537", + "savedPayload": { + "position": { + "x": 30555.56228253721, + "y": 24685.538763626188 + }, + "targetPosition": { + "x": 30268.890440801366, + "y": 24773.96531594946 + }, + "floatingObject": { + "isPinned": false, + "isFrozen": false, + "isCollapsed": false, + "angleToParent": 2, + "distanceToParent": 3, + "arrangementStyle": 0 + }, + "uiObject": {}, + "referenceParent": { + "type": "Pool", + "name": "Foundations Project", + "id": "2207c69c-ee9d-4453-8bf4-582d79b4b635" + } + } + }, + { + "type": "Pool Weight Vote", + "name": "TensorFlow Project Pool", + "config": "{}", + "project": "Governance", + "id": "21ac46d3-6170-422d-82ca-0738be0401c4", + "savedPayload": { + "position": { + "x": 30561.368814455913, + "y": 24840.721596136354 + }, + "targetPosition": { + "x": 30268.890440801366, + "y": 24773.96531594946 + }, + "floatingObject": { + "isPinned": false, + "isFrozen": false, + "isCollapsed": false, + "angleToParent": 2, + "distanceToParent": 3, + "arrangementStyle": 0 + }, + "uiObject": {}, + "referenceParent": { + "type": "Pool", + "name": "TensorFlow Project", + "id": "ea854cf8-47cd-43f0-b58a-13e61ae3106d" + } + } + }, + { + "type": "Pool Weight Vote", + "name": "Governance Project Pool", + "config": "{}", + "project": "Governance", + "id": "ac8070f0-fe42-4595-b844-e97170a0a5d6", + "savedPayload": { + "position": { + "x": 30488.806002350313, + "y": 24978.017137280734 + }, + "targetPosition": { + "x": 30268.890440801366, + "y": 24773.96531594946 + }, + "floatingObject": { + "isPinned": false, + "isFrozen": false, + "isCollapsed": false, + "angleToParent": 2, + "distanceToParent": 3, + "arrangementStyle": 0 + }, + "uiObject": {}, + "referenceParent": { + "type": "Pool", + "name": "Governance Project", + "id": "3c80032c-51a8-4fd8-ab65-cf219c03ce95" + } + } + }, + { + "type": "Pool Weight Vote", + "name": "Education Project Pool", + "config": "{}", + "project": "Governance", + "id": "fcfd5e40-7df6-47bd-b246-fea2309636a7", + "savedPayload": { + "position": { + "x": 30357.316993124638, + "y": 25060.6371576853 + }, + "targetPosition": { + "x": 30268.890440801366, + "y": 24773.96531594946 + }, + "floatingObject": { + "isPinned": false, + "isFrozen": false, + "isCollapsed": false, + "angleToParent": 2, + "distanceToParent": 3, + "arrangementStyle": 0 + }, + "uiObject": {}, + "referenceParent": { + "type": "Pool", + "name": "Education Project", + "id": "0a79ec65-6f67-4c18-823f-48a6d0494a81" + } + } + }, + { + "type": "Pool Weight Vote", + "name": "Ethereum Project Pool", + "config": "{}", + "project": "Governance", + "id": "db4d2213-3fd5-478e-b6f3-b754090e0721", + "savedPayload": { + "position": { + "x": 30202.13416061447, + "y": 25066.443689604006 + }, + "targetPosition": { + "x": 30268.890440801366, + "y": 24773.96531594946 + }, + "floatingObject": { + "isPinned": false, + "isFrozen": false, + "isCollapsed": false, + "angleToParent": 2, + "distanceToParent": 3, + "arrangementStyle": 0 + }, + "uiObject": {}, + "referenceParent": { + "type": "Pool", + "name": "Ethereum Project", + "id": "f51d23aa-742c-40d4-b000-2b90c3ae197c" + } + } + } + ], + "assetWeightVotes": [], + "featureWeightVotes": [], + "positionWeightVotes": [], + "id": "a970cae4-b62a-4127-ad64-067d44f721b4", + "savedPayload": { + "position": { + "x": 30268.890440801366, + "y": 24773.96531594946 + }, + "targetPosition": { + "x": 30048.97487925242, + "y": 24569.913494618184 + }, + "floatingObject": { + "isPinned": false, + "isFrozen": false, + "isCollapsed": false, + "angleToParent": 2, + "distanceToParent": 3, + "arrangementStyle": 0 + }, + "uiObject": { + "isRunning": false + } + } + }, + { + "type": "Weight Votes Switch", + "name": "Marketing Pool Class", + "config": "{}", + "project": "Governance", + "weightVotesSwitch": [ + { + "type": "Weight Votes Switch", + "name": "Collective Rewards Pool Class", + "config": "{}", + "project": "Governance", + "weightVotesSwitch": [], + "poolWeightVotes": [ + { + "type": "Pool Weight Vote", + "name": "First Exchange Listing The Token Pool", + "config": "{}", + "project": "Governance", + "id": "492e0acc-1d34-476b-8519-a25b26dc5d24", + "savedPayload": { + "position": { + "x": 30649.795366779184, + "y": 25127.393437872197 + }, + "targetPosition": { + "x": 30357.316993124638, + "y": 25060.6371576853 + }, + "floatingObject": { + "isPinned": false, + "isFrozen": false, + "isCollapsed": false, + "angleToParent": 2, + "distanceToParent": 3, + "arrangementStyle": 0 + }, + "uiObject": {}, + "referenceParent": { + "type": "Pool", + "name": "First Exchange Listing The Token", + "id": "6a456247-13b7-41f2-80b3-957c1af55009" + } + } + }, + { + "type": "Pool Weight Vote", + "name": "10K Stars on Github Pool", + "config": "{}", + "project": "Governance", + "id": "0a569224-49d0-4518-ac0b-3a9237410d76", + "savedPayload": { + "position": { + "x": 30445.74354544791, + "y": 25347.308999421144 + }, + "targetPosition": { + "x": 30357.316993124638, + "y": 25060.6371576853 + }, + "floatingObject": { + "isPinned": false, + "isFrozen": false, + "isCollapsed": false, + "angleToParent": 2, + "distanceToParent": 3, + "arrangementStyle": 0 + }, + "uiObject": {}, + "referenceParent": { + "type": "Pool", + "name": "10K Stars on Github", + "id": "5bbe5a09-fe32-4802-8e14-d06615a24510" + } + } + } + ], + "assetWeightVotes": [], + "featureWeightVotes": [], + "positionWeightVotes": [], + "id": "7ef32920-85af-4d4a-b4be-dd03415f905e", + "savedPayload": { + "position": { + "x": 30357.316993124638, + "y": 25060.6371576853 + }, + "targetPosition": { + "x": 30137.40143157569, + "y": 24856.585336354026 + }, + "floatingObject": { + "isPinned": false, + "isFrozen": false, + "isCollapsed": false, + "angleToParent": 2, + "distanceToParent": 3, + "arrangementStyle": 0 + }, + "uiObject": { + "isRunning": false + } + } + }, + { + "type": "Weight Votes Switch", + "name": "Assets Pool Class", + "config": "{}", + "project": "Governance", + "weightVotesSwitch": [], + "poolWeightVotes": [ + { + "type": "Pool Weight Vote", + "name": "Marketing Assets Pool", + "config": "{}", + "project": "Governance", + "id": "8ee0f13f-79ac-49e6-a417-414ef568eae7", + "savedPayload": { + "position": { + "x": 30003.8888712019, + "y": 25441.54208366312 + }, + "targetPosition": { + "x": 30070.645151388795, + "y": 25149.063710008573 + }, + "floatingObject": { + "isPinned": false, + "isFrozen": false, + "isCollapsed": false, + "angleToParent": 2, + "distanceToParent": 3, + "arrangementStyle": 0 + }, + "uiObject": {}, + "referenceParent": { + "type": "Pool", + "name": "Marketing Assets", + "id": "6b4bee15-622d-4df6-9662-4d7b8d44f198" + } + } + } + ], + "assetWeightVotes": [], + "featureWeightVotes": [], + "positionWeightVotes": [], + "id": "7ffccefb-7efa-43d8-942a-25f02307de29", + "savedPayload": { + "position": { + "x": 30070.645151388795, + "y": 25149.063710008573 + }, + "targetPosition": { + "x": 30137.40143157569, + "y": 24856.585336354026 + }, + "floatingObject": { + "isPinned": false, + "isFrozen": false, + "isCollapsed": false, + "angleToParent": 2, + "distanceToParent": 3, + "arrangementStyle": 0 + }, + "uiObject": { + "isRunning": false + } + } + } + ], + "poolWeightVotes": [], + "assetWeightVotes": [], + "featureWeightVotes": [], + "positionWeightVotes": [], + "id": "036afdd7-5205-41e6-aac2-5ef009ba46d8", + "savedPayload": { + "position": { + "x": 30137.40143157569, + "y": 24856.585336354026 + }, + "targetPosition": { + "x": 30048.97487925242, + "y": 24569.913494618184 + }, + "floatingObject": { + "isPinned": false, + "isFrozen": false, + "isCollapsed": false, + "angleToParent": 2, + "distanceToParent": 3, + "arrangementStyle": 0 + }, + "uiObject": { + "isRunning": false + } + } + }, + { + "type": "Weight Votes Switch", + "name": "Community Pool Class", + "config": "{}", + "project": "Governance", + "weightVotesSwitch": [ + { + "type": "Weight Votes Switch", + "name": "Users Pool Class", + "config": "{}", + "project": "Governance", + "weightVotesSwitch": [], + "poolWeightVotes": [ + { + "type": "Pool Weight Vote", + "name": "Usage Pool", + "config": "{}", + "project": "Governance", + "id": "536db08b-dc25-4548-b233-724d099dc447", + "savedPayload": { + "position": { + "x": 30407.062840071507, + "y": 25256.589716523136 + }, + "targetPosition": { + "x": 30141.828222020125, + "y": 25116.409128041218 + }, + "floatingObject": { + "isPinned": false, + "isFrozen": false, + "isCollapsed": false, + "angleToParent": 2, + "distanceToParent": 3, + "arrangementStyle": 0 + }, + "uiObject": {}, + "referenceParent": { + "type": "Pool", + "name": "Usage", + "id": "60712b3c-ee76-40ba-8de2-e03aa61f6dde" + } + } + }, + { + "type": "Pool Weight Vote", + "name": "User Referrals Pool", + "config": "{}", + "project": "Governance", + "id": "915e0231-3b99-4893-bb9a-dbcf638228d0", + "savedPayload": { + "position": { + "x": 30153.045580303024, + "y": 25416.19933947774 + }, + "targetPosition": { + "x": 30141.828222020125, + "y": 25116.409128041218 + }, + "floatingObject": { + "isPinned": false, + "isFrozen": false, + "isCollapsed": false, + "angleToParent": 2, + "distanceToParent": 3, + "arrangementStyle": 0 + }, + "uiObject": {}, + "referenceParent": { + "type": "Pool", + "name": "User Referrals", + "id": "639a6504-a0d0-4d7e-ad99-80ba5115ac72" + } + } + } + ], + "assetWeightVotes": [], + "featureWeightVotes": [], + "positionWeightVotes": [], + "id": "e058f130-c894-40b7-9e66-dfef44f20991", + "savedPayload": { + "position": { + "x": 30141.828222020125, + "y": 25116.409128041218 + }, + "targetPosition": { + "x": 29982.218599065523, + "y": 24862.39186827273 + }, + "floatingObject": { + "isPinned": false, + "isFrozen": false, + "isCollapsed": false, + "angleToParent": 2, + "distanceToParent": 3, + "arrangementStyle": 0 + }, + "uiObject": { + "isRunning": false + } + } + }, + { + "type": "Weight Votes Switch", + "name": "Contributors Pool Class", + "config": "{}", + "project": "Governance", + "weightVotesSwitch": [], + "poolWeightVotes": [ + { + "type": "Pool Weight Vote", + "name": "Badges Pool", + "config": "{}", + "project": "Governance", + "id": "1c26b6c1-477a-44f6-baa2-b8ab65622aed", + "savedPayload": { + "position": { + "x": 29848.706038691733, + "y": 25447.348615581825 + }, + "targetPosition": { + "x": 29915.462318878628, + "y": 25154.870241927278 + }, + "floatingObject": { + "isPinned": false, + "isFrozen": false, + "isCollapsed": false, + "angleToParent": 2, + "distanceToParent": 3, + "arrangementStyle": 0 + }, + "uiObject": {}, + "referenceParent": { + "type": "Pool", + "name": "Badges", + "id": "6b11cf29-2957-417d-a268-3569178eca9e" + } + } + } + ], + "assetWeightVotes": [], + "featureWeightVotes": [], + "positionWeightVotes": [], + "id": "8bf4d5ef-c106-47d2-abd8-9789453279db", + "savedPayload": { + "position": { + "x": 29915.462318878628, + "y": 25154.870241927278 + }, + "targetPosition": { + "x": 29982.218599065523, + "y": 24862.39186827273 + }, + "floatingObject": { + "isPinned": false, + "isFrozen": false, + "isCollapsed": false, + "angleToParent": 2, + "distanceToParent": 3, + "arrangementStyle": 0 + }, + "uiObject": { + "isRunning": false + } + } + }, + { + "type": "Weight Votes Switch", + "name": "Token Holders Pool Class", + "config": "{}", + "project": "Governance", + "weightVotesSwitch": [], + "poolWeightVotes": [ + { + "type": "Pool Weight Vote", + "name": "Stacking Pool", + "config": "{}", + "project": "Governance", + "id": "fd7f8254-69b2-4d16-ac6b-b3d40b39273b", + "savedPayload": { + "position": { + "x": 29474.18407952855, + "y": 25181.611114181935 + }, + "targetPosition": { + "x": 29728.201339297037, + "y": 25022.001491227333 + }, + "floatingObject": { + "isPinned": false, + "isFrozen": false, + "isCollapsed": false, + "angleToParent": 2, + "distanceToParent": 3, + "arrangementStyle": 0 + }, + "uiObject": {}, + "referenceParent": { + "type": "Pool", + "name": "Stacking", + "id": "ea79efd3-c3d9-4c80-a1d0-1cab106e0242" + } + } + } + ], + "assetWeightVotes": [], + "featureWeightVotes": [], + "positionWeightVotes": [], + "id": "14c021f7-fe45-459e-80f2-d7d358b25f4a", + "savedPayload": { + "position": { + "x": 29728.201339297037, + "y": 25022.001491227333 + }, + "targetPosition": { + "x": 29982.218599065523, + "y": 24862.39186827273 + }, + "floatingObject": { + "isPinned": false, + "isFrozen": false, + "isCollapsed": false, + "angleToParent": 2, + "distanceToParent": 3, + "arrangementStyle": 0 + }, + "uiObject": { + "isRunning": false + } + } + } + ], + "poolWeightVotes": [], + "assetWeightVotes": [], + "featureWeightVotes": [], + "positionWeightVotes": [], + "id": "2cc608dd-0424-4a44-be7a-b2993ce2976d", + "savedPayload": { + "position": { + "x": 29982.218599065523, + "y": 24862.39186827273 + }, + "targetPosition": { + "x": 30048.97487925242, + "y": 24569.913494618184 + }, + "floatingObject": { + "isPinned": false, + "isFrozen": false, + "isCollapsed": false, + "angleToParent": 2, + "distanceToParent": 3, + "arrangementStyle": 0 + }, + "uiObject": { + "isRunning": false + } + } + }, + { + "type": "Weight Votes Switch", + "name": "Education Pool Class", + "config": "{}", + "project": "Governance", + "weightVotesSwitch": [ + { + "type": "Weight Votes Switch", + "name": "Production Pool Class", + "config": "{}", + "project": "Governance", + "weightVotesSwitch": [ + { + "type": "Weight Votes Switch", + "name": "Creating Pool Class", + "config": "{}", + "project": "Governance", + "weightVotesSwitch": [], + "poolWeightVotes": [ + { + "type": "Pool Weight Vote", + "name": "Blog-Tutorials Pool", + "config": "{}", + "project": "Governance", + "id": "ccb1229b-a633-4234-82c9-ea1404bb570b", + "savedPayload": { + "position": { + "x": 30150.49154519727, + "y": 25465.94216879386 + }, + "targetPosition": { + "x": 29866.59333005752, + "y": 25368.97927155752 + }, + "floatingObject": { + "isPinned": false, + "isFrozen": false, + "isCollapsed": false, + "angleToParent": 2, + "distanceToParent": 3, + "arrangementStyle": 0 + }, + "uiObject": {}, + "referenceParent": { + "type": "Pool", + "name": "Blog-Tutorials", + "id": "0548fbd2-7904-481a-a33d-16ef93707276" + } + } + }, + { + "type": "Pool Weight Vote", + "name": "In-App-Docs Pool", + "config": "{}", + "project": "Governance", + "id": "f7596a5b-52cb-4477-bc47-b2ef35d01dc8", + "savedPayload": { + "position": { + "x": 30039.27844976322, + "y": 25614.29508725685 + }, + "targetPosition": { + "x": 29866.59333005752, + "y": 25368.97927155752 + }, + "floatingObject": { + "isPinned": false, + "isFrozen": false, + "isCollapsed": false, + "angleToParent": 2, + "distanceToParent": 3, + "arrangementStyle": 0 + }, + "uiObject": {}, + "referenceParent": { + "type": "Pool", + "name": "In-App-Docs", + "id": "14175310-1a9c-4f4b-89e2-aabe4507932a" + } + } + }, + { + "type": "Pool Weight Vote", + "name": "In-App-Tutorials Pool", + "config": "{}", + "project": "Governance", + "id": "1b0f7ebf-facc-484a-ae38-8ae379d8ddec", + "savedPayload": { + "position": { + "x": 29862.10550795294, + "y": 25668.945702100602 + }, + "targetPosition": { + "x": 29866.59333005752, + "y": 25368.97927155752 + }, + "floatingObject": { + "isPinned": false, + "isFrozen": false, + "isCollapsed": false, + "angleToParent": 2, + "distanceToParent": 3, + "arrangementStyle": 0 + }, + "uiObject": {}, + "referenceParent": { + "type": "Pool", + "name": "In-App-Tutorials", + "id": "64b19ffc-0240-46cd-804b-b57d25195f64" + } + } + }, + { + "type": "Pool Weight Vote", + "name": "Video-Tutorials Pool", + "config": "{}", + "project": "Governance", + "id": "0d3dc298-3699-4ccf-a0d6-21d9b6d7f85d", + "savedPayload": { + "position": { + "x": 29686.646761651147, + "y": 25609.019335960882 + }, + "targetPosition": { + "x": 29866.59333005752, + "y": 25368.97927155752 + }, + "floatingObject": { + "isPinned": false, + "isFrozen": false, + "isCollapsed": false, + "angleToParent": 2, + "distanceToParent": 3, + "arrangementStyle": 0 + }, + "uiObject": {}, + "referenceParent": { + "type": "Pool", + "name": "Video-Tutorials", + "id": "4d9474e1-e58f-4563-a1c2-e89533bc451e" + } + } + } + ], + "assetWeightVotes": [], + "featureWeightVotes": [], + "positionWeightVotes": [], + "id": "4f922838-940d-4ab2-a185-f737f3572f8a", + "savedPayload": { + "position": { + "x": 29866.59333005752, + "y": 25368.97927155752 + }, + "targetPosition": { + "x": 29778.166777734248, + "y": 25082.307429821678 + }, + "floatingObject": { + "isPinned": false, + "isFrozen": false, + "isCollapsed": false, + "angleToParent": 2, + "distanceToParent": 3, + "arrangementStyle": 0 + }, + "uiObject": { + "isRunning": false + } + } + }, + { + "type": "Weight Votes Switch", + "name": "Translating Pool Class", + "config": "{}", + "project": "Governance", + "weightVotesSwitch": [], + "poolWeightVotes": [ + { + "type": "Pool Weight Vote", + "name": "In-App-Docs Pool", + "config": "{}", + "project": "Governance", + "id": "d6530670-46f6-4fa2-8839-25c77465437c", + "savedPayload": { + "position": { + "x": 29585.33231468587, + "y": 25602.013202807146 + }, + "targetPosition": { + "x": 29574.114956402973, + "y": 25302.222991370625 + }, + "floatingObject": { + "isPinned": false, + "isFrozen": false, + "isCollapsed": false, + "angleToParent": 2, + "distanceToParent": 3, + "arrangementStyle": 0 + }, + "uiObject": {}, + "referenceParent": { + "type": "Pool", + "name": "In-App-Docs", + "id": "5737235d-c74f-4247-b870-b52428b5576f" + } + } + }, + { + "type": "Pool Weight Vote", + "name": "In-App-Tutorials Pool", + "config": "{}", + "project": "Governance", + "id": "3ce2eb05-c54a-40c1-816d-36e1088dfed2", + "savedPayload": { + "position": { + "x": 29370.063135071698, + "y": 25522.138552919572 + }, + "targetPosition": { + "x": 29574.114956402973, + "y": 25302.222991370625 + }, + "floatingObject": { + "isPinned": false, + "isFrozen": false, + "isCollapsed": false, + "angleToParent": 2, + "distanceToParent": 3, + "arrangementStyle": 0 + }, + "uiObject": {}, + "referenceParent": { + "type": "Pool", + "name": "In-App-Tutorials", + "id": "abe07b52-de21-44da-a989-f52067f508df" + } + } + }, + { + "type": "Pool Weight Vote", + "name": "Video-Tutorials Pool", + "config": "{}", + "project": "Governance", + "id": "2da649ef-07fe-4e07-a1de-59c0c2e37ea8", + "savedPayload": { + "position": { + "x": 29274.324744966452, + "y": 25313.440349653523 + }, + "targetPosition": { + "x": 29574.114956402973, + "y": 25302.222991370625 + }, + "floatingObject": { + "isPinned": false, + "isFrozen": false, + "isCollapsed": false, + "angleToParent": 2, + "distanceToParent": 3, + "arrangementStyle": 0 + }, + "uiObject": {}, + "referenceParent": { + "type": "Pool", + "name": "Video-Tutorials", + "id": "fb52e785-fa45-4522-8478-b0d039525b4a" + } + } + } + ], + "assetWeightVotes": [], + "featureWeightVotes": [], + "positionWeightVotes": [], + "id": "2b64a4bf-8347-4b72-a3e4-1ad22ea3d78a", + "savedPayload": { + "position": { + "x": 29574.114956402973, + "y": 25302.222991370625 + }, + "targetPosition": { + "x": 29778.166777734248, + "y": 25082.307429821678 + }, + "floatingObject": { + "isPinned": false, + "isFrozen": false, + "isCollapsed": false, + "angleToParent": 2, + "distanceToParent": 3, + "arrangementStyle": 0 + }, + "uiObject": { + "isRunning": false + } + } + } + ], + "poolWeightVotes": [], + "assetWeightVotes": [], + "featureWeightVotes": [], + "positionWeightVotes": [], + "id": "0d66181b-39c6-4e0b-a195-45d85fca3da4", + "savedPayload": { + "position": { + "x": 29778.166777734248, + "y": 25082.307429821678 + }, + "targetPosition": { + "x": 29844.923057921143, + "y": 24789.82905616713 + }, + "floatingObject": { + "isPinned": false, + "isFrozen": false, + "isCollapsed": false, + "angleToParent": 2, + "distanceToParent": 3, + "arrangementStyle": 0 + }, + "uiObject": { + "isRunning": false + } + } + }, + { + "type": "Weight Votes Switch", + "name": "Consumption Pool Class", + "config": "{}", + "project": "Governance", + "weightVotesSwitch": [], + "poolWeightVotes": [ + { + "type": "Pool Weight Vote", + "name": "Completing Tutorials Pool", + "config": "{}", + "project": "Governance", + "id": "7db3a456-0428-4236-bac9-6bb40495f45a", + "savedPayload": { + "position": { + "x": 29354.199394854026, + "y": 25098.17117003935 + }, + "targetPosition": { + "x": 29558.2512161853, + "y": 24878.255608490403 + }, + "floatingObject": { + "isPinned": false, + "isFrozen": false, + "isCollapsed": false, + "angleToParent": 2, + "distanceToParent": 3, + "arrangementStyle": 0 + }, + "uiObject": {}, + "referenceParent": { + "type": "Pool", + "name": "Completing Tutorials", + "id": "0bfaeebd-a900-4e6e-b62c-3387e4e7baec" + } + } + }, + { + "type": "Pool Weight Vote", + "name": "Reading the Docs Pool", + "config": "{}", + "project": "Governance", + "id": "621292e3-1917-413e-8327-3777e77c1fd5", + "savedPayload": { + "position": { + "x": 29265.772842530754, + "y": 24811.499328303507 + }, + "targetPosition": { + "x": 29558.2512161853, + "y": 24878.255608490403 + }, + "floatingObject": { + "isPinned": false, + "isFrozen": false, + "isCollapsed": false, + "angleToParent": 2, + "distanceToParent": 3, + "arrangementStyle": 0 + }, + "uiObject": {}, + "referenceParent": { + "type": "Pool", + "name": "Reading the Docs", + "id": "c3bee026-075f-48db-92df-fc599cce744d" + } + } + } + ], + "assetWeightVotes": [], + "featureWeightVotes": [], + "positionWeightVotes": [], + "id": "8ea22ba7-0745-4459-a7eb-6446bb64dae2", + "savedPayload": { + "position": { + "x": 29558.2512161853, + "y": 24878.255608490403 + }, + "targetPosition": { + "x": 29844.923057921143, + "y": 24789.82905616713 + }, + "floatingObject": { + "isPinned": false, + "isFrozen": false, + "isCollapsed": false, + "angleToParent": 2, + "distanceToParent": 3, + "arrangementStyle": 0 + }, + "uiObject": { + "isRunning": false + } + } + } + ], + "poolWeightVotes": [], + "assetWeightVotes": [], + "featureWeightVotes": [], + "positionWeightVotes": [], + "id": "cbe7d779-09c1-4ea3-ab72-03c65d69fd3e", + "savedPayload": { + "position": { + "x": 29844.923057921143, + "y": 24789.82905616713 + }, + "targetPosition": { + "x": 30048.97487925242, + "y": 24569.913494618184 + }, + "floatingObject": { + "isPinned": false, + "isFrozen": false, + "isCollapsed": false, + "angleToParent": 2, + "distanceToParent": 3, + "arrangementStyle": 0 + }, + "uiObject": { + "isRunning": false + } + } + }, + { + "type": "Weight Votes Switch", + "name": "Management Pool Class", + "config": "{}", + "project": "Governance", + "weightVotesSwitch": [], + "poolWeightVotes": [ + { + "type": "Pool Weight Vote", + "name": "Management Pool", + "config": "{}", + "project": "Governance", + "id": "2e7259e0-122f-4482-87a0-e73182ff29e8", + "savedPayload": { + "position": { + "x": 29475.631195780734, + "y": 24746.766599264727 + }, + "targetPosition": { + "x": 29762.303037516576, + "y": 24658.340046941456 + }, + "floatingObject": { + "isPinned": false, + "isFrozen": false, + "isCollapsed": false, + "angleToParent": 2, + "distanceToParent": 3, + "arrangementStyle": 0 + }, + "uiObject": {}, + "referenceParent": { + "type": "Pool", + "name": "Management", + "id": "5d878af1-e32c-4458-8fb7-98df55f1e54a" + } + } + } + ], + "assetWeightVotes": [], + "featureWeightVotes": [], + "positionWeightVotes": [], + "id": "f7fa794e-2188-40c2-b342-9b1995bbb9dc", + "savedPayload": { + "position": { + "x": 29762.303037516576, + "y": 24658.340046941456 + }, + "targetPosition": { + "x": 30048.97487925242, + "y": 24569.913494618184 + }, + "floatingObject": { + "isPinned": false, + "isFrozen": false, + "isCollapsed": false, + "angleToParent": 2, + "distanceToParent": 3, + "arrangementStyle": 0 + }, + "uiObject": { + "isRunning": false + } + } + } + ], + "poolWeightVotes": [], + "assetWeightVotes": [], + "featureWeightVotes": [], + "positionWeightVotes": [], + "id": "e059f5c4-9132-4d76-9f3e-1060658fa704", + "savedPayload": { + "position": { + "x": 30048.97487925242, + "y": 24569.913494618184 + }, + "targetPosition": { + "x": 30115.731159439314, + "y": 24277.435120963637 + }, + "floatingObject": { + "isPinned": false, + "isFrozen": false, + "isCollapsed": true, + "angleToParent": 2, + "distanceToParent": 3, + "arrangementStyle": 0 + }, + "uiObject": { + "isRunning": false + }, + "referenceParent": { + "type": "Pools", + "name": "Superalgos", + "id": "6f0aed87-db13-4818-bfe6-68abc463ebec" + } + } + } + ], + "poolWeightVotes": [], + "assetWeightVotes": [], + "featureWeightVotes": [], + "positionWeightVotes": [], + "id": "1d398124-3f36-40a1-8b3b-6c77ad489b92", + "savedPayload": { + "position": { + "x": 30115.731159439314, + "y": 24277.435120963637 + }, + "targetPosition": { + "x": 30182.48743962621, + "y": 23984.95674730909 + }, + "floatingObject": { + "isPinned": false, + "isFrozen": false, + "isCollapsed": false, + "angleToParent": 2, + "distanceToParent": 3, + "arrangementStyle": 0 + }, + "uiObject": { + "isRunning": false + } + } + } + ], + "userProfileVotesSwitch": [], + "id": "2b8d3ce7-515c-44ad-8d80-3c2be6d7736f", + "savedPayload": { + "position": { + "x": 30182.48743962621, + "y": 23984.95674730909 + }, + "targetPosition": { + "x": 30249.243719813105, + "y": 23692.478373654543 + }, + "floatingObject": { + "isPinned": false, + "isFrozen": false, + "isCollapsed": false, + "angleToParent": 2, + "distanceToParent": 3, + "arrangementStyle": 0 + }, + "uiObject": { + "isRunning": false + } + } + } + ], "id": "d5ed432e-78bf-432e-be3b-8649932f7a65", "savedPayload": { "position": { diff --git a/Projects/Governance/UI/Function-Libraries/Votes.js b/Projects/Governance/UI/Function-Libraries/Votes.js index 416a6e4e0..c00ea96df 100644 --- a/Projects/Governance/UI/Function-Libraries/Votes.js +++ b/Projects/Governance/UI/Function-Libraries/Votes.js @@ -41,11 +41,23 @@ function newGovernanceFunctionLibraryVotes() { */ for (let i = 0; i < userProfiles.length; i++) { let userProfile = userProfiles[i] - resetVotes(userProfile) + + if (userProfile.tokenSwitch === undefined) { continue } + if (userProfile.tokenSwitch.votingProgram === undefined) { continue } + if (userProfile.tokenSwitch.votingProgram.payload === undefined) { continue } + + resetVotes(userProfile.tokenSwitch.votingProgram) } for (let i = 0; i < userProfiles.length; i++) { let userProfile = userProfiles[i] - distributeForProfile(userProfile) + + if (userProfile.tokenSwitch === undefined) { continue } + if (userProfile.tokenSwitch.votingProgram === undefined) { continue } + if (userProfile.tokenSwitch.votingProgram.payload === undefined) { continue } + + userProfile.tokenSwitch.votingProgram.payload.votes = userProfile.tokenSwitch.votingProgram.payload.tokenPower + + distributeForVotingProgram(userProfile.tokenSwitch.votingProgram) } function resetVotes(node) { @@ -114,16 +126,10 @@ function newGovernanceFunctionLibraryVotes() { } } - function distributeForProfile(userProfile) { - if (userProfile.payload === undefined) { return } - let votes - if (userProfile.payload.blockchainTokens === undefined) { - return - } else { - votes = userProfile.payload.blockchainTokens - } - - distributeVotes(userProfile, votes) + function distributeForVotingProgram(votingProgram) { + if (votingProgram.payload === undefined) { return } + let votes = votingProgram.payload.votes + distributeVotes(votingProgram, votes) } function distributeVotes(node, votes, switchPercentage) { From 5bac00777e3c4a93bee8cf8e061ed8fd873aee03 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Wed, 16 Jun 2021 20:10:57 +0200 Subject: [PATCH 7/9] Referral Program half way reimplemented --- .../UI/Spaces/Floating-Space/UiObject.js | 30 +++-- .../Governance/Plugins/Pools/Superalgos.json | 2 +- .../Plugins/User-Profiles/Julian-Molina.json | 12 +- .../User-Profiles/Luis-Fernando-Molina.json | 91 ++++++++++----- .../UI/Function-Libraries/TokenPower.js | 2 + .../UI/Function-Libraries/UserReferrals.js | 108 +++++++++++------- .../Governance/UI/Function-Libraries/Votes.js | 15 ++- 7 files changed, 175 insertions(+), 85 deletions(-) diff --git a/Projects/Foundations/UI/Spaces/Floating-Space/UiObject.js b/Projects/Foundations/UI/Spaces/Floating-Space/UiObject.js index 4c5bf3321..9edb76d67 100644 --- a/Projects/Foundations/UI/Spaces/Floating-Space/UiObject.js +++ b/Projects/Foundations/UI/Spaces/Floating-Space/UiObject.js @@ -30,6 +30,10 @@ function newUiObject() { hasInfo: undefined, valueAtAngle: true, valueAngleOffset: 0, + percentageAtAngle: true, + percentageAngleOffset: 0, + statusAtAngle: true, + statusAngleOffset: 0, run: run, stop: stop, heartBeat: heartBeat, @@ -1887,13 +1891,13 @@ function newUiObject() { label = label.substring(0, MAX_LABEL_LENGTH) + '...' } - if (thisObject.valueAtAngle === true && thisObject.payload.angle !== undefined) { + if (thisObject.percentageAtAngle === true && thisObject.payload.angle !== undefined) { labelPoint = { x: position.x - getTextWidth(label) / 2, y: position.y } - labelPoint.x = labelPoint.x + radius * 7 / 3 * Math.cos(toRadians(thisObject.payload.angle + thisObject.valueAngleOffset)) - labelPoint.y = labelPoint.y + radius * 7 / 3 * Math.sin(toRadians(thisObject.payload.angle + thisObject.valueAngleOffset)) + lineSeparator * 1 + labelPoint.x = labelPoint.x + radius * 7 / 3 * Math.cos(toRadians(thisObject.payload.angle + thisObject.percentageAngleOffset)) + labelPoint.y = labelPoint.y + radius * 7 / 3 * Math.sin(toRadians(thisObject.payload.angle + thisObject.percentageAngleOffset)) + lineSeparator * 1 } else { if (thisObject.isOnFocus === true) { labelPoint = { @@ -1948,15 +1952,25 @@ function newUiObject() { label = label.substring(0, MAX_LABEL_LENGTH) + '...' } - if (thisObject.isOnFocus === true) { + if (thisObject.statusAtAngle === true && thisObject.payload.angle !== undefined) { labelPoint = { x: position.x - getTextWidth(label) / 2, - y: position.y + radius * 2 / 3 + lineSeparator * 4 + 30 + y: position.y } + labelPoint.x = labelPoint.x + radius * 7 / 3 * Math.cos(toRadians(thisObject.payload.angle + thisObject.statusAngleOffset)) + labelPoint.y = labelPoint.y + radius * 7 / 3 * Math.sin(toRadians(thisObject.payload.angle + thisObject.statusAngleOffset)) + lineSeparator * 2 } else { - labelPoint = { - x: position.x - getTextWidth(label) / 2, - y: position.y + thisObject.payload.floatingObject.currentImageSize / 2 + lineSeparator * 4 + + if (thisObject.isOnFocus === true) { + labelPoint = { + x: position.x - getTextWidth(label) / 2, + y: position.y + radius * 2 / 3 + lineSeparator * 4 + 30 + } + } else { + labelPoint = { + x: position.x - getTextWidth(label) / 2, + y: position.y + thisObject.payload.floatingObject.currentImageSize / 2 + lineSeparator * 4 + } } } diff --git a/Projects/Governance/Plugins/Pools/Superalgos.json b/Projects/Governance/Plugins/Pools/Superalgos.json index 45da273e9..c8001cec2 100644 --- a/Projects/Governance/Plugins/Pools/Superalgos.json +++ b/Projects/Governance/Plugins/Pools/Superalgos.json @@ -424,7 +424,7 @@ { "type": "Pool", "name": "User Referrals", - "config": "{\n \"codeName\": \"User-Referrals\"\n}", + "config": "{\n \"codeName\": \"Referral-Program\"\n}", "project": "Governance", "poolClasses": [], "pools": [], diff --git a/Projects/Governance/Plugins/User-Profiles/Julian-Molina.json b/Projects/Governance/Plugins/User-Profiles/Julian-Molina.json index 234fbeb37..0772a9bab 100644 --- a/Projects/Governance/Plugins/User-Profiles/Julian-Molina.json +++ b/Projects/Governance/Plugins/User-Profiles/Julian-Molina.json @@ -15,10 +15,10 @@ "project": "Governance", "userReferrer": { "type": "User Referrer", - "name": "Luis-Fernando-Molina", - "config": "{\n \"description\": \"\"\n}", + "name": "Jeremy", + "config": "{}", "project": "Governance", - "id": "edf7bcda-23f6-49bb-b9b2-9a34edcb4a40", + "id": "0d0b04ff-034b-4b02-8351-67d621d514c0", "savedPayload": { "position": { "x": 25503.74798740812, @@ -32,15 +32,15 @@ "isPinned": false, "isFrozen": false, "isCollapsed": false, - "angleToParent": 1, + "angleToParent": 2, "distanceToParent": 3, "arrangementStyle": 0 }, "uiObject": {}, "referenceParent": { "type": "User Profile", - "name": "Luis-Fernando-Molina", - "id": "148911b3-b2f3-44fb-8cb4-017991789132" + "name": "Jeremy", + "id": "759e9012-c995-47ed-92f1-7d204bf2b58e" } } }, diff --git a/Projects/Governance/Plugins/User-Profiles/Luis-Fernando-Molina.json b/Projects/Governance/Plugins/User-Profiles/Luis-Fernando-Molina.json index e15103c2c..5f259a419 100644 --- a/Projects/Governance/Plugins/User-Profiles/Luis-Fernando-Molina.json +++ b/Projects/Governance/Plugins/User-Profiles/Luis-Fernando-Molina.json @@ -13,11 +13,42 @@ "name": "New Referral Program", "config": "{}", "project": "Governance", + "userReferrer": { + "type": "User Referrer", + "name": "Julian-Molina", + "config": "{}", + "project": "Governance", + "id": "c96ae419-54ad-4d70-94fe-38833288d471", + "savedPayload": { + "position": { + "x": 30785.098889480818, + "y": 23025.90611888476 + }, + "targetPosition": { + "x": 30550.54944474041, + "y": 23212.953059442378 + }, + "floatingObject": { + "isPinned": false, + "isFrozen": false, + "isCollapsed": false, + "angleToParent": 2, + "distanceToParent": 3, + "arrangementStyle": 0 + }, + "uiObject": {}, + "referenceParent": { + "type": "User Profile", + "name": "Julian-Molina", + "id": "1fd95e41-4b22-48d5-be3a-904c37afcb11" + } + } + }, "id": "43a24543-03cf-4511-b670-63566159dbd7", "savedPayload": { "position": { - "x": 30586.290660370727, - "y": 23530.165121735263 + "x": 30550.54944474041, + "y": 23212.953059442378 }, "targetPosition": { "x": 30316, @@ -27,7 +58,7 @@ "isPinned": false, "isFrozen": false, "isCollapsed": false, - "angleToParent": 2, + "angleToParent": 1, "distanceToParent": 3, "arrangementStyle": 0 }, @@ -45,8 +76,8 @@ "id": "8af4af68-62bf-4ad2-bf84-f1124cba0abf", "savedPayload": { "position": { - "x": 30503.04694055762, - "y": 23634.549444740405 + "x": 30608.478373654547, + "y": 23466.75628018689 }, "targetPosition": { "x": 30316, @@ -56,7 +87,7 @@ "isPinned": false, "isFrozen": false, "isCollapsed": false, - "angleToParent": 2, + "angleToParent": 1, "distanceToParent": 3, "arrangementStyle": 0 }, @@ -74,8 +105,8 @@ "id": "91d82012-4362-4fe0-b02b-0eb3b394ace5", "savedPayload": { "position": { - "x": 30382.756280186895, - "y": 23692.478373654543 + "x": 30446.165121735266, + "y": 23670.290660370723 }, "targetPosition": { "x": 30316, @@ -85,7 +116,7 @@ "isPinned": false, "isFrozen": false, "isCollapsed": false, - "angleToParent": 2, + "angleToParent": 1, "distanceToParent": 3, "arrangementStyle": 0 }, @@ -1286,12 +1317,12 @@ "id": "e059f5c4-9132-4d76-9f3e-1060658fa704", "savedPayload": { "position": { - "x": 30048.97487925242, - "y": 24569.913494618184 + "x": 29795.339513058934, + "y": 24481.162641482904 }, "targetPosition": { - "x": 30115.731159439314, - "y": 24277.435120963637 + "x": 29925.5046347942, + "y": 24210.871981112177 }, "floatingObject": { "isPinned": false, @@ -1319,12 +1350,12 @@ "id": "1d398124-3f36-40a1-8b3b-6c77ad489b92", "savedPayload": { "position": { - "x": 30115.731159439314, - "y": 24277.435120963637 + "x": 29925.5046347942, + "y": 24210.871981112177 }, "targetPosition": { - "x": 30182.48743962621, - "y": 23984.95674730909 + "x": 30055.669756529467, + "y": 23940.58132074145 }, "floatingObject": { "isPinned": false, @@ -1344,12 +1375,12 @@ "id": "2b8d3ce7-515c-44ad-8d80-3c2be6d7736f", "savedPayload": { "position": { - "x": 30182.48743962621, - "y": 23984.95674730909 + "x": 30055.669756529467, + "y": 23940.58132074145 }, "targetPosition": { - "x": 30249.243719813105, - "y": 23692.478373654543 + "x": 30185.834878264734, + "y": 23670.290660370723 }, "floatingObject": { "isPinned": false, @@ -1368,8 +1399,8 @@ "id": "d5ed432e-78bf-432e-be3b-8649932f7a65", "savedPayload": { "position": { - "x": 30249.243719813105, - "y": 23692.478373654543 + "x": 30185.834878264734, + "y": 23670.290660370723 }, "targetPosition": { "x": 30316, @@ -1379,7 +1410,7 @@ "isPinned": false, "isFrozen": false, "isCollapsed": false, - "angleToParent": 2, + "angleToParent": 1, "distanceToParent": 3, "arrangementStyle": 0 }, @@ -1399,8 +1430,8 @@ "id": "796dd30f-c90d-4b8d-a63d-89867347407b", "savedPayload": { "position": { - "x": 30128.95305944238, - "y": 23634.549444740405 + "x": 30023.521626345453, + "y": 23466.75628018689 }, "targetPosition": { "x": 30316, @@ -1410,7 +1441,7 @@ "isPinned": false, "isFrozen": false, "isCollapsed": false, - "angleToParent": 2, + "angleToParent": 1, "distanceToParent": 3, "arrangementStyle": 0 }, @@ -1427,8 +1458,8 @@ "id": "b046f4e4-40b1-4e47-8fed-75a6a5c6029d", "savedPayload": { "position": { - "x": 30045.709339629273, - "y": 23530.165121735263 + "x": 30081.45055525959, + "y": 23212.953059442378 }, "targetPosition": { "x": 30316, @@ -1438,7 +1469,7 @@ "isPinned": false, "isFrozen": false, "isCollapsed": false, - "angleToParent": 2, + "angleToParent": 1, "distanceToParent": 3, "arrangementStyle": 0 }, diff --git a/Projects/Governance/UI/Function-Libraries/TokenPower.js b/Projects/Governance/UI/Function-Libraries/TokenPower.js index ea196c329..e2508f7dc 100644 --- a/Projects/Governance/UI/Function-Libraries/TokenPower.js +++ b/Projects/Governance/UI/Function-Libraries/TokenPower.js @@ -240,6 +240,8 @@ function newGovernanceFunctionLibraryTokenPower() { node.payload.uiObject.setValue(tokenPower) if (percentage !== undefined) { + node.payload.uiObject.percentageAngleOffset = 180 + node.payload.uiObject.percentageAtAngle = true node.payload.uiObject.setPercentage(percentage.toFixed(2)) } } diff --git a/Projects/Governance/UI/Function-Libraries/UserReferrals.js b/Projects/Governance/UI/Function-Libraries/UserReferrals.js index 289f56a35..dc207c456 100644 --- a/Projects/Governance/UI/Function-Libraries/UserReferrals.js +++ b/Projects/Governance/UI/Function-Libraries/UserReferrals.js @@ -23,15 +23,30 @@ function newGovernanceFunctionLibraryUserReferrals() { */ for (let i = 0; i < userProfiles.length; i++) { let userProfile = userProfiles[i] - resetUserReferrals(userProfile) + + if (userProfile.tokenSwitch === undefined) { continue } + if (userProfile.tokenSwitch.referralProgram === undefined) { continue } + if (userProfile.tokenSwitch.referralProgram.payload === undefined) { continue } + + resetUserReferrals(userProfile.tokenSwitch.referralProgram) } for (let i = 0; i < userProfiles.length; i++) { let userProfile = userProfiles[i] - distributeForProfile(userProfile) + + if (userProfile.tokenSwitch === undefined) { continue } + if (userProfile.tokenSwitch.referralProgram === undefined) { continue } + if (userProfile.tokenSwitch.referralProgram.payload === undefined) { continue } + + distributeForReferralProgram(userProfile.tokenSwitch.referralProgram) } for (let i = 0; i < userProfiles.length; i++) { let userProfile = userProfiles[i] - calculateAwardedForProfile(userProfile) + + if (userProfile.tokenSwitch === undefined) { continue } + if (userProfile.tokenSwitch.referralProgram === undefined) { continue } + if (userProfile.tokenSwitch.referralProgram.payload === undefined) { continue } + + calculateForReferralProgram(userProfile.tokenSwitch.referralProgram) } function findPool(node) { @@ -46,7 +61,7 @@ function newGovernanceFunctionLibraryUserReferrals() { node.type === 'Pool' ) { let codeName = UI.projects.foundations.utilities.nodeConfig.loadConfigProperty(node.payload, 'codeName') - if (codeName === "User-Referrals") { + if (codeName === "Referral-Program") { tokensReward = node.payload.tokens return } @@ -96,8 +111,19 @@ function newGovernanceFunctionLibraryUserReferrals() { If the node is a User Profile, we will check if it has a User Referrer child defined. */ if ( - node.userReferrer !== undefined && - node.type === 'User Profile' + node.type === 'User Profile' && + node.tokenSwitch !== undefined && + node.tokenSwitch.referralProgram !== undefined + ) { + resetUserReferrals(node.tokenSwitch.referralProgram) + return + } + /* + If the node is a Referral Program, we will check if it has a User Referrer child defined. + */ + if ( + node.type === 'Referral Program' && + node.userReferrer !== undefined ) { resetUserReferrals(node.userReferrer) return @@ -107,26 +133,20 @@ function newGovernanceFunctionLibraryUserReferrals() { transfered to it. */ if ( - node.payload.referenceParent !== undefined && - node.type === 'User Referrer' + node.type === 'User Referrer' && + node.payload.referenceParent !== undefined ) { resetUserReferrals(node.payload.referenceParent) return } } - function distributeForProfile(userProfile) { - if (userProfile === undefined || userProfile.payload === undefined) { return } - let referringPower - if (userProfile.payload.blockchainTokens === undefined) { - return - } else { - referringPower = userProfile.payload.blockchainTokens - } - + function distributeForReferralProgram(referralProgram) { + if (referralProgram === undefined || referralProgram.payload === undefined) { return } + let referringPower = referralProgram.payload.tokenPower let referringCount = 0 - userProfile.payload.referring.ownPower = referringPower - distributeUserReferrals(userProfile, referringPower, referringCount) + referralProgram.payload.referring.ownPower = referringPower + distributeUserReferrals(referralProgram, referringPower, referringCount) } function distributeUserReferrals(node, referringPower, referringCount) { @@ -142,10 +162,10 @@ function newGovernanceFunctionLibraryUserReferrals() { node.payload.referring.referralsPower = node.payload.referring.combinedPower - node.payload.referring.ownPower totalReferralsPower = totalReferralsPower + node.payload.referring.referralsPower if ( - node.userReferrer !== undefined && - node.type === 'User Profile' + node.type === 'Referral Program' && + node.userReferrer !== undefined ) { - distributeUserReferrals(node.userReferrer, referringPower, 1, 0) + distributeUserReferrals(node.userReferrer, referringPower / 10, 1, 0) return } /* @@ -153,45 +173,55 @@ function newGovernanceFunctionLibraryUserReferrals() { transfered to it. */ if ( - node.payload.referenceParent !== undefined && - node.type === 'User Referrer' + node.type === 'User Referrer' && + node.payload.referenceParent !== undefined ) { drawUserReferrals(node) - distributeUserReferrals(node.payload.referenceParent, referringPower / 10, 1) + distributeUserReferrals(node.payload.referenceParent, referringPower, 1) return } } - function calculateAwardedForProfile(userProfile) { - if (userProfile.payload === undefined) { return } + function calculateForReferralProgram(referralProgram) { + if (referralProgram.payload === undefined) { return } - let totalPowerRewardRation = tokensReward / totalReferralsPower - if (totalPowerRewardRation < 1) { totalPowerRewardRation = 1 } + let totalPowerRewardRatio = tokensReward / totalReferralsPower + if (totalPowerRewardRatio < 1) { totalPowerRewardRatio = 1 } - userProfile.payload.referring.awarded.tokens = userProfile.payload.referring.referralsPower * totalPowerRewardRation - drawUserProfiles(userProfile) + referralProgram.payload.referring.awarded.tokens = referralProgram.payload.referring.referralsPower * totalPowerRewardRatio + drawReferralProgram(referralProgram) } function drawUserReferrals(node) { if (node.payload !== undefined) { - const powerText = new Intl.NumberFormat().format(node.payload.referring.combinedPower) + const ownPowerText = new Intl.NumberFormat().format(node.payload.referring.ownPower) + const referralsPowerText = new Intl.NumberFormat().format(node.payload.referring.referralsPower) + const combinedPowerText = new Intl.NumberFormat().format(node.payload.referring.combinedPower) - node.payload.uiObject.valueAngleOffset = 0 - node.payload.uiObject.valueAtAngle = false + node.payload.uiObject.valueAngleOffset = 180 + node.payload.uiObject.valueAtAngle = true - node.payload.uiObject.setStatus(powerText + ' ' + 'Combined Referring Power') - return + node.payload.uiObject.setValue( combinedPowerText + ' ' + 'Referring Power') + + node.payload.uiObject.statusAngleOffset = 0 + node.payload.uiObject.statusAtAngle = false + + node.payload.uiObject.setStatus(ownPowerText + ' own RP + ' + referralsPowerText + ' inherited RP = ' + combinedPowerText + ' ' + ' Total RP') } } - function drawUserProfiles(node) { + function drawReferralProgram(node) { if (node.payload !== undefined) { const powerText = new Intl.NumberFormat().format(node.payload.referring.combinedPower) const awardedTokens = new Intl.NumberFormat().format(node.payload.referring.awarded.tokens) const referralPower = new Intl.NumberFormat().format(node.payload.referring.referralsPower) - node.payload.uiObject.valueAngleOffset = 0 - node.payload.uiObject.valueAtAngle = false + node.payload.uiObject.statusAngleOffset = 0 + node.payload.uiObject.statusAtAngle = false + + node.payload.uiObject.setStatus("Referring Power = Token Power / 10") + + return if ( ( diff --git a/Projects/Governance/UI/Function-Libraries/Votes.js b/Projects/Governance/UI/Function-Libraries/Votes.js index c00ea96df..70afdc0c5 100644 --- a/Projects/Governance/UI/Function-Libraries/Votes.js +++ b/Projects/Governance/UI/Function-Libraries/Votes.js @@ -268,7 +268,16 @@ function newGovernanceFunctionLibraryVotes() { function drawVotes(node, votes, percentage) { votes = new Intl.NumberFormat().format(votes) + ' ' + 'Votes' if (node.payload !== undefined) { - if (node.type === 'User Profile') { + + if (node.type === 'Voting Program') { + node.payload.uiObject.statusAngleOffset = 0 + node.payload.uiObject.statusAtAngle = false + + node.payload.uiObject.setStatus("Votes = Tokens Power") + + if (percentage !== undefined) { + node.payload.uiObject.setPercentage(percentage.toFixed(2)) + } return } if ( @@ -286,9 +295,13 @@ function newGovernanceFunctionLibraryVotes() { ) { node.payload.uiObject.valueAngleOffset = 0 node.payload.uiObject.valueAtAngle = false + node.payload.uiObject.percentageAngleOffset = 0 + node.payload.uiObject.percentageAtAngle = false } else { node.payload.uiObject.valueAngleOffset = 180 node.payload.uiObject.valueAtAngle = true + node.payload.uiObject.percentageAngleOffset = 180 + node.payload.uiObject.percentageAtAngle = true } node.payload.uiObject.setValue(votes) From 805f6d48f30d04afc29e792e25eb1ffeb9c215ab Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Thu, 17 Jun 2021 02:38:59 +0200 Subject: [PATCH 8/9] Referral Program reimplemented, without Token Rewards yet. --- .../UI/Function-Libraries/UserReferrals.js | 165 ++++++++++++------ 1 file changed, 110 insertions(+), 55 deletions(-) diff --git a/Projects/Governance/UI/Function-Libraries/UserReferrals.js b/Projects/Governance/UI/Function-Libraries/UserReferrals.js index dc207c456..c50d80ab4 100644 --- a/Projects/Governance/UI/Function-Libraries/UserReferrals.js +++ b/Projects/Governance/UI/Function-Libraries/UserReferrals.js @@ -9,17 +9,28 @@ function newGovernanceFunctionLibraryUserReferrals() { pools, userProfiles ) { - let tokensReward - let totalReferralsPower = 0 + /* + Here we will store the total amount of tokens that is going to be distributed among all participants + of the Referral Program. This will come from a Pool that is configured wiht a codeName config property + with the value "Referral-Program" + */ + let referralProgramPoolTokenReward + /* + In order to be able to calculate the share of the Referrals Program Pool for each User Profile, + we need to accumulate all the Icomming Referral Power that each User Profile at their Referral Program + node has, because with that Incoming Power is that each Referral Program node gets a share of + the pool. + */ + let accumulatedIncomingReferralPower = 0 /* Scan Pools Until finding the User-Referrlas Pool */ for (let i = 0; i < pools.length; i++) { let poolsNode = pools[i] findPool(poolsNode) } - if (tokensReward === undefined || tokensReward === 0) { return } + if (referralProgramPoolTokenReward === undefined || referralProgramPoolTokenReward === 0) { return } /* - We will first reset all the referral combinedPower, and then distribute it. + We will first reset all the referral outgoingPower, and then distribute it. */ for (let i = 0; i < userProfiles.length; i++) { let userProfile = userProfiles[i] @@ -55,14 +66,14 @@ function newGovernanceFunctionLibraryUserReferrals() { /* When we reach certain node types, we will halt the distribution, because these are targets for - voting combinedPower. + voting outgoingPower. */ if ( node.type === 'Pool' ) { let codeName = UI.projects.foundations.utilities.nodeConfig.loadConfigProperty(node.payload, 'codeName') if (codeName === "Referral-Program") { - tokensReward = node.payload.tokens + referralProgramPoolTokenReward = node.payload.tokens return } } @@ -97,11 +108,11 @@ function newGovernanceFunctionLibraryUserReferrals() { function resetUserReferrals(node) { if (node === undefined) { return } if (node.payload === undefined) { return } - node.payload.referring = { + node.payload.referrals = { count: 0, - combinedPower: 0, + outgoingPower: 0, ownPower: 0, - referralsPower: 0, + incomingPower: 0, awarded: { tokens: 0, percentage: 0 @@ -129,7 +140,7 @@ function newGovernanceFunctionLibraryUserReferrals() { return } /* - If there is a reference parent defined, this means that the referral combinedPower is + If there is a reference parent defined, this means that the referral outgoingPower is transfered to it. */ if ( @@ -143,78 +154,122 @@ function newGovernanceFunctionLibraryUserReferrals() { function distributeForReferralProgram(referralProgram) { if (referralProgram === undefined || referralProgram.payload === undefined) { return } - let referringPower = referralProgram.payload.tokenPower - let referringCount = 0 - referralProgram.payload.referring.ownPower = referringPower - distributeUserReferrals(referralProgram, referringPower, referringCount) + /* + Here we will convert Token Power into Referral Power. + As per system rules referringPower = tokensPower / 10 + */ + let referringPower = referralProgram.payload.tokenPower / 10 + /* + We will also reseet the count of referrals here. + */ + let count = 0 + /* + The Own Power is the power generated by the same User Profile tokens, not inherited from others. + */ + referralProgram.payload.referrals.ownPower = referringPower + + distributeReferralPower(referralProgram, referringPower, count) } - function distributeUserReferrals(node, referringPower, referringCount) { + function distributeReferralPower( + node, + referringPower, + count + ) { + if (node === undefined) { return } if (node.payload === undefined) { return } - node.payload.referring.count = node.payload.referring.count + referringCount - node.payload.referring.combinedPower = node.payload.referring.combinedPower + referringPower - /* - If the node is a User Profile, we will check if it has a User Referrer child defined. - */ - totalReferralsPower = totalReferralsPower - node.payload.referring.referralsPower - node.payload.referring.referralsPower = node.payload.referring.combinedPower - node.payload.referring.ownPower - totalReferralsPower = totalReferralsPower + node.payload.referring.referralsPower - if ( - node.type === 'Referral Program' && - node.userReferrer !== undefined - ) { - distributeUserReferrals(node.userReferrer, referringPower / 10, 1, 0) - return - } - /* - If there is a reference parent defined, this means that the referral combinedPower is - transfered to it. - */ - if ( - node.type === 'User Referrer' && - node.payload.referenceParent !== undefined - ) { - drawUserReferrals(node) - distributeUserReferrals(node.payload.referenceParent, referringPower, 1) - return + switch (node.type) { + case 'Referral Program': { + /* + This is the point where we increase to our local count of referrals whatever it comes + at the count parameters. If we are processing the User Profile of this Referral Program + then we will add zero, otherwise, 1. + */ + node.payload.referrals.count = node.payload.referrals.count + count + /* + The outgoingPower of this node will be accumulating all the referringPower flowing + through it, no matter from where it comes. + */ + node.payload.referrals.outgoingPower = node.payload.referrals.outgoingPower + referringPower + /* + We need to adjust the balance that holds the accumulationt of all incomingPower of all Referral Program + nodes. To do this we will substratct the current incomingPower, bacause it is going to be recalculated + inmediatelly after this, and then we will add it again after the recalcualtion. + */ + accumulatedIncomingReferralPower = accumulatedIncomingReferralPower - node.payload.referrals.incomingPower + /* + At any point in time, the incomingPower will be equal to the total of the outgoingPower minus + the ownPower. This is like this because the outgoingPower is the accumulation of all the + power flow that is leaving this node, which includes the ownPower. That means that if we + substract the ownPower, we will have the accumulation of all the incomingPower, which + means all the power coming from other User Profiles referencing this one. + */ + node.payload.referrals.incomingPower = node.payload.referrals.outgoingPower - node.payload.referrals.ownPower + /* + Now that we have the incomingPower calculated again, we can add it again to the balance of all the incomingPower + of all Referral Program nodes. + */ + accumulatedIncomingReferralPower = accumulatedIncomingReferralPower + node.payload.referrals.incomingPower + + if (node.userReferrer !== undefined) { + distributeReferralPower(node.userReferrer, referringPower, 0) + } + break + } + case 'User Referrer': { + drawUserReferrer(node) + if (node.payload.referenceParent !== undefined) { + distributeReferralPower(node.payload.referenceParent, referringPower / 10, 0) + } + break + } + case 'User Profile': { + if (node.tokenSwitch !== undefined) { + distributeReferralPower(node.tokenSwitch, referringPower, 0) + } + break + } + case 'Token Switch': { + if (node.referralProgram !== undefined) { + distributeReferralPower(node.referralProgram, referringPower, 1) + } + break + } } } function calculateForReferralProgram(referralProgram) { if (referralProgram.payload === undefined) { return } - let totalPowerRewardRatio = tokensReward / totalReferralsPower + let totalPowerRewardRatio = referralProgramPoolTokenReward / accumulatedIncomingReferralPower if (totalPowerRewardRatio < 1) { totalPowerRewardRatio = 1 } - referralProgram.payload.referring.awarded.tokens = referralProgram.payload.referring.referralsPower * totalPowerRewardRatio + referralProgram.payload.referrals.awarded.tokens = referralProgram.payload.referrals.incomingPower * totalPowerRewardRatio drawReferralProgram(referralProgram) } - function drawUserReferrals(node) { + function drawUserReferrer(node) { if (node.payload !== undefined) { - const ownPowerText = new Intl.NumberFormat().format(node.payload.referring.ownPower) - const referralsPowerText = new Intl.NumberFormat().format(node.payload.referring.referralsPower) - const combinedPowerText = new Intl.NumberFormat().format(node.payload.referring.combinedPower) + const ownPowerText = new Intl.NumberFormat().format(node.payload.parentNode.payload.referrals.ownPower) + const incomingPowerText = new Intl.NumberFormat().format(node.payload.parentNode.payload.referrals.incomingPower) + const outgoingPowerText = new Intl.NumberFormat().format(node.payload.parentNode.payload.referrals.outgoingPower) node.payload.uiObject.valueAngleOffset = 180 node.payload.uiObject.valueAtAngle = true - node.payload.uiObject.setValue( combinedPowerText + ' ' + 'Referring Power') + node.payload.uiObject.setValue(outgoingPowerText + ' ' + 'Referring Power') node.payload.uiObject.statusAngleOffset = 0 node.payload.uiObject.statusAtAngle = false - node.payload.uiObject.setStatus(ownPowerText + ' own RP + ' + referralsPowerText + ' inherited RP = ' + combinedPowerText + ' ' + ' Total RP') + node.payload.uiObject.setStatus(ownPowerText + ' Own RP + ' + incomingPowerText + ' Incoming RP = ' + outgoingPowerText + ' ' + ' Outgoing RP') } } function drawReferralProgram(node) { if (node.payload !== undefined) { - const powerText = new Intl.NumberFormat().format(node.payload.referring.combinedPower) - const awardedTokens = new Intl.NumberFormat().format(node.payload.referring.awarded.tokens) - const referralPower = new Intl.NumberFormat().format(node.payload.referring.referralsPower) node.payload.uiObject.statusAngleOffset = 0 node.payload.uiObject.statusAtAngle = false @@ -229,18 +284,18 @@ function newGovernanceFunctionLibraryUserReferrals() { node.userReferrer.payload !== undefined && node.userReferrer.payload.referenceParent !== undefined) || - node.payload.referring.combinedPower >= 10000000 + node.payload.referrals.outgoingPower >= 10000000 ) { let status = powerText + ' ' + 'Combined Referring Power' + ' - ' + - node.payload.referring.count + ' Referrals' + ' - ' + + node.payload.referrals.count + ' Referrals' + ' - ' + referralPower + ' Referrals Power' + ' - ' + awardedTokens + ' ' + 'SA Tokens Awarded' node.payload.uiObject.setStatus(status) return } else { - node.payload.referring.awarded.tokens = 0 + node.payload.referrals.awarded.tokens = 0 node.payload.uiObject.setStatus(awardedTokens + ' SA Tokens not Awarded, because you have not defined your referrer yet.') } } From 226205413a494f872f32245400ab8ab73f6930a6 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Thu, 17 Jun 2021 16:02:25 +0200 Subject: [PATCH 9/9] Governance: Referral Program fully reimplemented. --- Projects/Governance/Icons/tokens-awarded.png | Bin 0 -> 16813 bytes .../Plugins/User-Profiles/Julian-Molina.json | 33 ++++++++- .../User-Profiles/Luis-Fernando-Molina.json | 33 ++++++++- .../Schemas/App-Schema/TokensAwarded.json | 21 ++++++ .../Schemas/App-Schema/claims-program.json | 15 +++++ .../App-Schema/mentorship-program.json | 17 ++++- ...ing-program.json => referral-program.json} | 15 +++++ .../Schemas/App-Schema/staking-program.json | 19 +++++- .../Schemas/App-Schema/support-program.json | 17 ++++- .../Schemas/App-Schema/voting-program.json | 15 +++++ .../UI/Function-Libraries/UserReferrals.js | 63 +++++++++++------- 11 files changed, 213 insertions(+), 35 deletions(-) create mode 100644 Projects/Governance/Icons/tokens-awarded.png create mode 100644 Projects/Governance/Schemas/App-Schema/TokensAwarded.json rename Projects/Governance/Schemas/App-Schema/{referring-program.json => referral-program.json} (74%) diff --git a/Projects/Governance/Icons/tokens-awarded.png b/Projects/Governance/Icons/tokens-awarded.png new file mode 100644 index 0000000000000000000000000000000000000000..650a239d609a9d19c4bc0db4e5747fbde5983bc0 GIT binary patch literal 16813 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 literal 0 HcmV?d00001 diff --git a/Projects/Governance/Plugins/User-Profiles/Julian-Molina.json b/Projects/Governance/Plugins/User-Profiles/Julian-Molina.json index 0772a9bab..32cb19cba 100644 --- a/Projects/Governance/Plugins/User-Profiles/Julian-Molina.json +++ b/Projects/Governance/Plugins/User-Profiles/Julian-Molina.json @@ -21,8 +21,8 @@ "id": "0d0b04ff-034b-4b02-8351-67d621d514c0", "savedPayload": { "position": { - "x": 25503.74798740812, - "y": 23618.43086266558 + "x": 25532.618466191747, + "y": 23465.846712854385 }, "targetPosition": { "x": 25233.45732703739, @@ -44,6 +44,31 @@ } } }, + "tokensAwarded": { + "type": "Tokens Awarded", + "name": "New Tokens Awarded", + "project": "Governance", + "id": "208f866a-459d-4dd8-93ea-1a2b8bfa3dac", + "savedPayload": { + "position": { + "x": 25402.453344456477, + "y": 23736.137373225112 + }, + "targetPosition": { + "x": 25233.45732703739, + "y": 23488.265740930314 + }, + "floatingObject": { + "isPinned": false, + "isFrozen": false, + "isCollapsed": false, + "angleToParent": 2, + "distanceToParent": 3, + "arrangementStyle": 0 + }, + "uiObject": {} + } + }, "id": "a9ddce61-97b0-47e8-ad6c-e9438aca3913", "savedPayload": { "position": { @@ -208,7 +233,9 @@ "distanceToParent": 3, "arrangementStyle": 0 }, - "uiObject": {} + "uiObject": { + "isRunning": false + } } }, "id": "86a8ca4c-76d4-4eb0-9acb-5650095c6667", diff --git a/Projects/Governance/Plugins/User-Profiles/Luis-Fernando-Molina.json b/Projects/Governance/Plugins/User-Profiles/Luis-Fernando-Molina.json index 5f259a419..0d67339a8 100644 --- a/Projects/Governance/Plugins/User-Profiles/Luis-Fernando-Molina.json +++ b/Projects/Governance/Plugins/User-Profiles/Luis-Fernando-Molina.json @@ -21,8 +21,8 @@ "id": "c96ae419-54ad-4d70-94fe-38833288d471", "savedPayload": { "position": { - "x": 30785.098889480818, - "y": 23025.90611888476 + "x": 30660.151752050326, + "y": 22933.690934849117 }, "targetPosition": { "x": 30550.54944474041, @@ -44,6 +44,31 @@ } } }, + "tokensAwarded": { + "type": "Tokens Awarded", + "name": "New Tokens Awarded", + "project": "Governance", + "id": "56ac3eb9-2d72-4a8d-99bc-3221819ce995", + "savedPayload": { + "position": { + "x": 30847.198692607948, + "y": 23168.240379589526 + }, + "targetPosition": { + "x": 30550.54944474041, + "y": 23212.953059442378 + }, + "floatingObject": { + "isPinned": false, + "isFrozen": false, + "isCollapsed": false, + "angleToParent": 2, + "distanceToParent": 3, + "arrangementStyle": 0 + }, + "uiObject": {} + } + }, "id": "43a24543-03cf-4511-b670-63566159dbd7", "savedPayload": { "position": { @@ -1473,7 +1498,9 @@ "distanceToParent": 3, "arrangementStyle": 0 }, - "uiObject": {} + "uiObject": { + "isRunning": false + } } }, "id": "f8182a9c-f830-4ec1-a238-ac3a5efd69e6", diff --git a/Projects/Governance/Schemas/App-Schema/TokensAwarded.json b/Projects/Governance/Schemas/App-Schema/TokensAwarded.json new file mode 100644 index 000000000..cf14e5af3 --- /dev/null +++ b/Projects/Governance/Schemas/App-Schema/TokensAwarded.json @@ -0,0 +1,21 @@ +{ + "type": "Tokens Awarded", + "menuItems": [ + { + "action": "Delete UI Object", + "actionProject": "Foundations", + "askConfirmation": true, + "confirmationLabel": "Confirm to Delete", + "label": "Delete", + "iconPathOn": "delete-entity", + "iconPathOff": "delete-entity", + "actionFunction": "payload.executeAction" + } + ], + "addLeftIcons": true, + "level": 2, + "attachingRules": { + "compatibleTypes": "->Referral Program->Mentorship Program->Support Program->Voting Program->Claims Program->Staking Program->" + }, + "propertyNameAtParent": "tokensAwarded" +} \ No newline at end of file diff --git a/Projects/Governance/Schemas/App-Schema/claims-program.json b/Projects/Governance/Schemas/App-Schema/claims-program.json index cfd71d2e9..8a9e731d6 100644 --- a/Projects/Governance/Schemas/App-Schema/claims-program.json +++ b/Projects/Governance/Schemas/App-Schema/claims-program.json @@ -29,6 +29,15 @@ "label": "Add Position Contributions Folder", "relatedUiObject": "Position Contributions Folder" }, + { + "action": "Add UI Object", + "actionProject": "Foundations", + "disableIfPropertyIsDefined": true, + "propertyToCheckFor": "tokensAwarded", + "actionFunction": "payload.executeAction", + "label": "Add Tokens Awarded", + "relatedUiObject": "Tokens Awarded" + }, { "action": "Delete UI Object", "actionProject": "Foundations", @@ -70,6 +79,12 @@ "type": "array", "childType": "Position Contributions Folder", "autoAdd": false + }, + { + "name": "tokensAwarded", + "type": "node", + "childType": "Tokens Awarded", + "autoAdd": true } ] } \ No newline at end of file diff --git a/Projects/Governance/Schemas/App-Schema/mentorship-program.json b/Projects/Governance/Schemas/App-Schema/mentorship-program.json index 6c3f9263a..9bdf5ed90 100644 --- a/Projects/Governance/Schemas/App-Schema/mentorship-program.json +++ b/Projects/Governance/Schemas/App-Schema/mentorship-program.json @@ -11,12 +11,19 @@ { "action": "Add UI Object", "actionProject": "Foundations", - "disableIfPropertyIsDefined": true, - "propertyToCheckFor": "userMentor", "actionFunction": "payload.executeAction", "label": "Add User Mentor", "relatedUiObject": "User Mentor" }, + { + "action": "Add UI Object", + "actionProject": "Foundations", + "disableIfPropertyIsDefined": true, + "propertyToCheckFor": "tokensAwarded", + "actionFunction": "payload.executeAction", + "label": "Add Tokens Awarded", + "relatedUiObject": "Tokens Awarded" + }, { "action": "Delete UI Object", "actionProject": "Foundations", @@ -46,6 +53,12 @@ "type": "array", "childType": "User Mentor", "autoAdd": false + }, + { + "name": "tokensAwarded", + "type": "node", + "childType": "Tokens Awarded", + "autoAdd": true } ] } \ No newline at end of file diff --git a/Projects/Governance/Schemas/App-Schema/referring-program.json b/Projects/Governance/Schemas/App-Schema/referral-program.json similarity index 74% rename from Projects/Governance/Schemas/App-Schema/referring-program.json rename to Projects/Governance/Schemas/App-Schema/referral-program.json index df7a8f384..b16edcda3 100644 --- a/Projects/Governance/Schemas/App-Schema/referring-program.json +++ b/Projects/Governance/Schemas/App-Schema/referral-program.json @@ -17,6 +17,15 @@ "label": "Add User Referrer", "relatedUiObject": "User Referrer" }, + { + "action": "Add UI Object", + "actionProject": "Foundations", + "disableIfPropertyIsDefined": true, + "propertyToCheckFor": "tokensAwarded", + "actionFunction": "payload.executeAction", + "label": "Add Tokens Awarded", + "relatedUiObject": "Tokens Awarded" + }, { "action": "Delete UI Object", "actionProject": "Foundations", @@ -46,6 +55,12 @@ "type": "node", "childType": "User Referrer", "autoAdd": true + }, + { + "name": "tokensAwarded", + "type": "node", + "childType": "Tokens Awarded", + "autoAdd": true } ] } \ No newline at end of file diff --git a/Projects/Governance/Schemas/App-Schema/staking-program.json b/Projects/Governance/Schemas/App-Schema/staking-program.json index 8c9d03a2c..d8e103712 100644 --- a/Projects/Governance/Schemas/App-Schema/staking-program.json +++ b/Projects/Governance/Schemas/App-Schema/staking-program.json @@ -8,6 +8,15 @@ "iconPathOn": "configuration", "iconPathOff": "configuration" }, + { + "action": "Add UI Object", + "actionProject": "Foundations", + "disableIfPropertyIsDefined": true, + "propertyToCheckFor": "tokensAwarded", + "actionFunction": "payload.executeAction", + "label": "Add Tokens Awarded", + "relatedUiObject": "Tokens Awarded" + }, { "action": "Delete UI Object", "actionProject": "Foundations", @@ -30,5 +39,13 @@ }, "addLeftIcons": true, "level": 1, - "propertyNameAtParent": "stakingProgram" + "propertyNameAtParent": "stakingProgram", + "childrenNodesProperties": [ + { + "name": "tokensAwarded", + "type": "node", + "childType": "Tokens Awarded", + "autoAdd": true + } + ] } \ No newline at end of file diff --git a/Projects/Governance/Schemas/App-Schema/support-program.json b/Projects/Governance/Schemas/App-Schema/support-program.json index 05c44007c..a0bfb71e3 100644 --- a/Projects/Governance/Schemas/App-Schema/support-program.json +++ b/Projects/Governance/Schemas/App-Schema/support-program.json @@ -11,12 +11,19 @@ { "action": "Add UI Object", "actionProject": "Foundations", - "disableIfPropertyIsDefined": true, - "propertyToCheckFor": "userSupport", "actionFunction": "payload.executeAction", "label": "Add User Support", "relatedUiObject": "User Support" }, + { + "action": "Add UI Object", + "actionProject": "Foundations", + "disableIfPropertyIsDefined": true, + "propertyToCheckFor": "tokensAwarded", + "actionFunction": "payload.executeAction", + "label": "Add Tokens Awarded", + "relatedUiObject": "Tokens Awarded" + }, { "action": "Delete UI Object", "actionProject": "Foundations", @@ -46,6 +53,12 @@ "type": "array", "childType": "User Support", "autoAdd": false + }, + { + "name": "tokensAwarded", + "type": "node", + "childType": "Tokens Awarded", + "autoAdd": true } ] } \ No newline at end of file diff --git a/Projects/Governance/Schemas/App-Schema/voting-program.json b/Projects/Governance/Schemas/App-Schema/voting-program.json index 32790eaed..04185a618 100644 --- a/Projects/Governance/Schemas/App-Schema/voting-program.json +++ b/Projects/Governance/Schemas/App-Schema/voting-program.json @@ -15,6 +15,15 @@ "label": "Add Votes Switch", "relatedUiObject": "Votes Switch" }, + { + "action": "Add UI Object", + "actionProject": "Foundations", + "disableIfPropertyIsDefined": true, + "propertyToCheckFor": "tokensAwarded", + "actionFunction": "payload.executeAction", + "label": "Add Tokens Awarded", + "relatedUiObject": "Tokens Awarded" + }, { "action": "Delete UI Object", "actionProject": "Foundations", @@ -44,6 +53,12 @@ "type": "array", "childType": "Votes Switch", "autoAdd": false + }, + { + "name": "tokensAwarded", + "type": "node", + "childType": "Tokens Awarded", + "autoAdd": true } ] } \ No newline at end of file diff --git a/Projects/Governance/UI/Function-Libraries/UserReferrals.js b/Projects/Governance/UI/Function-Libraries/UserReferrals.js index c50d80ab4..4bcf9c34d 100644 --- a/Projects/Governance/UI/Function-Libraries/UserReferrals.js +++ b/Projects/Governance/UI/Function-Libraries/UserReferrals.js @@ -156,9 +156,9 @@ function newGovernanceFunctionLibraryUserReferrals() { if (referralProgram === undefined || referralProgram.payload === undefined) { return } /* Here we will convert Token Power into Referral Power. - As per system rules referringPower = tokensPower / 10 + As per system rules referringPower = tokensPower */ - let referringPower = referralProgram.payload.tokenPower / 10 + let referringPower = referralProgram.payload.tokenPower /* We will also reseet the count of referrals here. */ @@ -241,12 +241,41 @@ function newGovernanceFunctionLibraryUserReferrals() { } function calculateForReferralProgram(referralProgram) { + /* + Here we will calculate which share of the Referral Program Pool this user will get in tokens. + To do that, we use the incomingPower, to se which proportion of the accumulatedIncomingReferralPower + represents. + */ if (referralProgram.payload === undefined) { return } + /* + If the accumulatedIncomingReferralPower is not grater the amount of tokens at the Referral Program Pool, then + this user will get the exact amount of tokens from the pool as incomingPower he has. - let totalPowerRewardRatio = referralProgramPoolTokenReward / accumulatedIncomingReferralPower + If the accumulatedIncomingReferralPower is grater the amount of tokens at the Referral Program Pool, then + the amount ot tokens to be received is a proportional to the share of incomingPower in accumulatedIncomingReferralPower. + */ + let totalPowerRewardRatio = accumulatedIncomingReferralPower / referralProgramPoolTokenReward if (totalPowerRewardRatio < 1) { totalPowerRewardRatio = 1 } + if (referralProgram.tokensAwarded === undefined || referralProgram.tokensAwarded.payload === undefined) { + referralProgram.payload.uiObject.setErrorMessage("Tokens Awarded Node is needed in order for this Program to get Tokens from the Referral Program Pool.") + return + } referralProgram.payload.referrals.awarded.tokens = referralProgram.payload.referrals.incomingPower * totalPowerRewardRatio + /* + As per the system rules, the Referral Program will not give tokens to users that do not ha their own Referrer set up, + unless it has a big amount of tokens (this last condition is for the edge case where a user it at the top of the + referral pyramid.) + */ + if ( + referralProgram.payload.referrals.ownPower < 1000000 && + (referralProgram.userReferrer === undefined || referralProgram.userReferrer.payload.referenceParent === undefined) + ) { + + referralProgram.payload.uiObject.setErrorMessage("In order to be awarded " + referralProgram.payload.referrals.awarded.tokens + " SA Tokens from your referrals, you need first to define yourself who your referrer is.") + referralProgram.payload.referrals.awarded.tokens = 0 + } + drawReferralProgram(referralProgram) } @@ -274,30 +303,16 @@ function newGovernanceFunctionLibraryUserReferrals() { node.payload.uiObject.statusAngleOffset = 0 node.payload.uiObject.statusAtAngle = false - node.payload.uiObject.setStatus("Referring Power = Token Power / 10") + node.payload.uiObject.setStatus("Referring Power = Token Power") + } + if (node.tokensAwarded !== undefined && node.tokensAwarded.payload !== undefined) { - return + const tokensAwardedText = new Intl.NumberFormat().format(node.payload.referrals.awarded.tokens) - if ( - ( - node.userReferrer !== undefined && - node.userReferrer.payload !== undefined && - node.userReferrer.payload.referenceParent !== undefined) - || - node.payload.referrals.outgoingPower >= 10000000 - ) { - let status = - powerText + ' ' + 'Combined Referring Power' + ' - ' + - node.payload.referrals.count + ' Referrals' + ' - ' + - referralPower + ' Referrals Power' + ' - ' + - awardedTokens + ' ' + 'SA Tokens Awarded' + node.tokensAwarded.payload.uiObject.statusAngleOffset = 0 + node.tokensAwarded.payload.uiObject.statusAtAngle = false - node.payload.uiObject.setStatus(status) - return - } else { - node.payload.referrals.awarded.tokens = 0 - node.payload.uiObject.setStatus(awardedTokens + ' SA Tokens not Awarded, because you have not defined your referrer yet.') - } + node.tokensAwarded.payload.uiObject.setValue(tokensAwardedText + ' SA Tokens') } } }