diff --git a/README.md b/README.md index 3d3a6de7..2d0db7b8 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,8 @@ Currently, there are multiple subgraphs, but additional subgraphs can be added t 3. **DexCandles**: Tracks all the PancakeSwap trades (event: `Swap`) with 5m / 15m / 1h / 4h / 1d / 1w candles. +4. **Profile**: Tracks all the PancakeSwap Profile with teams, users, points and campaign. + ## To setup and deploy For any of the subgraph: `blocks` as `[subgraph]` diff --git a/abis/profile.json b/abis/profile.json new file mode 100644 index 00000000..412ca578 --- /dev/null +++ b/abis/profile.json @@ -0,0 +1,1140 @@ +[ + { + "inputs":[ + { + "internalType":"contract IBEP20", + "name":"_cakeToken", + "type":"address" + }, + { + "internalType":"uint256", + "name":"_numberCakeToReactivate", + "type":"uint256" + }, + { + "internalType":"uint256", + "name":"_numberCakeToRegister", + "type":"uint256" + }, + { + "internalType":"uint256", + "name":"_numberCakeToUpdate", + "type":"uint256" + } + ], + "stateMutability":"nonpayable", + "type":"constructor" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":true, + "internalType":"bytes32", + "name":"role", + "type":"bytes32" + }, + { + "indexed":true, + "internalType":"bytes32", + "name":"previousAdminRole", + "type":"bytes32" + }, + { + "indexed":true, + "internalType":"bytes32", + "name":"newAdminRole", + "type":"bytes32" + } + ], + "name":"RoleAdminChanged", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":true, + "internalType":"bytes32", + "name":"role", + "type":"bytes32" + }, + { + "indexed":true, + "internalType":"address", + "name":"account", + "type":"address" + }, + { + "indexed":true, + "internalType":"address", + "name":"sender", + "type":"address" + } + ], + "name":"RoleGranted", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":true, + "internalType":"bytes32", + "name":"role", + "type":"bytes32" + }, + { + "indexed":true, + "internalType":"address", + "name":"account", + "type":"address" + }, + { + "indexed":true, + "internalType":"address", + "name":"sender", + "type":"address" + } + ], + "name":"RoleRevoked", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":false, + "internalType":"uint256", + "name":"teamId", + "type":"uint256" + }, + { + "indexed":false, + "internalType":"string", + "name":"teamName", + "type":"string" + } + ], + "name":"TeamAdd", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":true, + "internalType":"uint256", + "name":"teamId", + "type":"uint256" + }, + { + "indexed":false, + "internalType":"uint256", + "name":"numberPoints", + "type":"uint256" + }, + { + "indexed":true, + "internalType":"uint256", + "name":"campaignId", + "type":"uint256" + } + ], + "name":"TeamPointIncrease", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":true, + "internalType":"address", + "name":"userAddress", + "type":"address" + }, + { + "indexed":false, + "internalType":"uint256", + "name":"oldTeamId", + "type":"uint256" + }, + { + "indexed":false, + "internalType":"uint256", + "name":"newTeamId", + "type":"uint256" + } + ], + "name":"UserChangeTeam", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":true, + "internalType":"address", + "name":"userAddress", + "type":"address" + }, + { + "indexed":false, + "internalType":"uint256", + "name":"teamId", + "type":"uint256" + }, + { + "indexed":false, + "internalType":"address", + "name":"nftAddress", + "type":"address" + }, + { + "indexed":false, + "internalType":"uint256", + "name":"tokenId", + "type":"uint256" + } + ], + "name":"UserNew", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":true, + "internalType":"address", + "name":"userAddress", + "type":"address" + }, + { + "indexed":false, + "internalType":"uint256", + "name":"teamId", + "type":"uint256" + } + ], + "name":"UserPause", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":true, + "internalType":"address", + "name":"userAddress", + "type":"address" + }, + { + "indexed":false, + "internalType":"uint256", + "name":"numberPoints", + "type":"uint256" + }, + { + "indexed":true, + "internalType":"uint256", + "name":"campaignId", + "type":"uint256" + } + ], + "name":"UserPointIncrease", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":false, + "internalType":"address[]", + "name":"userAddresses", + "type":"address[]" + }, + { + "indexed":false, + "internalType":"uint256", + "name":"numberPoints", + "type":"uint256" + }, + { + "indexed":true, + "internalType":"uint256", + "name":"campaignId", + "type":"uint256" + } + ], + "name":"UserPointIncreaseMultiple", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":true, + "internalType":"address", + "name":"userAddress", + "type":"address" + }, + { + "indexed":false, + "internalType":"uint256", + "name":"teamId", + "type":"uint256" + }, + { + "indexed":false, + "internalType":"address", + "name":"nftAddress", + "type":"address" + }, + { + "indexed":false, + "internalType":"uint256", + "name":"tokenId", + "type":"uint256" + } + ], + "name":"UserReactivate", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":true, + "internalType":"address", + "name":"userAddress", + "type":"address" + }, + { + "indexed":false, + "internalType":"address", + "name":"nftAddress", + "type":"address" + }, + { + "indexed":false, + "internalType":"uint256", + "name":"tokenId", + "type":"uint256" + } + ], + "name":"UserUpdate", + "type":"event" + }, + { + "inputs":[ + + ], + "name":"DEFAULT_ADMIN_ROLE", + "outputs":[ + { + "internalType":"bytes32", + "name":"", + "type":"bytes32" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"NFT_ROLE", + "outputs":[ + { + "internalType":"bytes32", + "name":"", + "type":"bytes32" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"POINT_ROLE", + "outputs":[ + { + "internalType":"bytes32", + "name":"", + "type":"bytes32" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"SPECIAL_ROLE", + "outputs":[ + { + "internalType":"bytes32", + "name":"", + "type":"bytes32" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"_nftAddress", + "type":"address" + } + ], + "name":"addNftAddress", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"string", + "name":"_teamName", + "type":"string" + }, + { + "internalType":"string", + "name":"_teamDescription", + "type":"string" + } + ], + "name":"addTeam", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"cakeToken", + "outputs":[ + { + "internalType":"contract IBEP20", + "name":"", + "type":"address" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"_userAddress", + "type":"address" + }, + { + "internalType":"uint256", + "name":"_newTeamId", + "type":"uint256" + } + ], + "name":"changeTeam", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"uint256", + "name":"_amount", + "type":"uint256" + } + ], + "name":"claimFee", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"uint256", + "name":"_teamId", + "type":"uint256" + }, + { + "internalType":"address", + "name":"_nftAddress", + "type":"address" + }, + { + "internalType":"uint256", + "name":"_tokenId", + "type":"uint256" + } + ], + "name":"createProfile", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"bytes32", + "name":"role", + "type":"bytes32" + } + ], + "name":"getRoleAdmin", + "outputs":[ + { + "internalType":"bytes32", + "name":"", + "type":"bytes32" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"bytes32", + "name":"role", + "type":"bytes32" + }, + { + "internalType":"uint256", + "name":"index", + "type":"uint256" + } + ], + "name":"getRoleMember", + "outputs":[ + { + "internalType":"address", + "name":"", + "type":"address" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"bytes32", + "name":"role", + "type":"bytes32" + } + ], + "name":"getRoleMemberCount", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"uint256", + "name":"_teamId", + "type":"uint256" + } + ], + "name":"getTeamProfile", + "outputs":[ + { + "internalType":"string", + "name":"", + "type":"string" + }, + { + "internalType":"string", + "name":"", + "type":"string" + }, + { + "internalType":"uint256", + "name":"", + "type":"uint256" + }, + { + "internalType":"uint256", + "name":"", + "type":"uint256" + }, + { + "internalType":"bool", + "name":"", + "type":"bool" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"_userAddress", + "type":"address" + } + ], + "name":"getUserProfile", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + }, + { + "internalType":"uint256", + "name":"", + "type":"uint256" + }, + { + "internalType":"uint256", + "name":"", + "type":"uint256" + }, + { + "internalType":"address", + "name":"", + "type":"address" + }, + { + "internalType":"uint256", + "name":"", + "type":"uint256" + }, + { + "internalType":"bool", + "name":"", + "type":"bool" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"_userAddress", + "type":"address" + } + ], + "name":"getUserStatus", + "outputs":[ + { + "internalType":"bool", + "name":"", + "type":"bool" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"bytes32", + "name":"role", + "type":"bytes32" + }, + { + "internalType":"address", + "name":"account", + "type":"address" + } + ], + "name":"grantRole", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"", + "type":"address" + } + ], + "name":"hasRegistered", + "outputs":[ + { + "internalType":"bool", + "name":"", + "type":"bool" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"bytes32", + "name":"role", + "type":"bytes32" + }, + { + "internalType":"address", + "name":"account", + "type":"address" + } + ], + "name":"hasRole", + "outputs":[ + { + "internalType":"bool", + "name":"", + "type":"bool" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"uint256", + "name":"_teamId", + "type":"uint256" + }, + { + "internalType":"uint256", + "name":"_numberPoints", + "type":"uint256" + }, + { + "internalType":"uint256", + "name":"_campaignId", + "type":"uint256" + } + ], + "name":"increaseTeamPoints", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"_userAddress", + "type":"address" + }, + { + "internalType":"uint256", + "name":"_numberPoints", + "type":"uint256" + }, + { + "internalType":"uint256", + "name":"_campaignId", + "type":"uint256" + } + ], + "name":"increaseUserPoints", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address[]", + "name":"_userAddresses", + "type":"address[]" + }, + { + "internalType":"uint256", + "name":"_numberPoints", + "type":"uint256" + }, + { + "internalType":"uint256", + "name":"_campaignId", + "type":"uint256" + } + ], + "name":"increaseUserPointsMultiple", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"uint256", + "name":"_teamId", + "type":"uint256" + } + ], + "name":"makeTeamJoinable", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"uint256", + "name":"_teamId", + "type":"uint256" + } + ], + "name":"makeTeamNotJoinable", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"numberActiveProfiles", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"numberCakeToReactivate", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"numberCakeToRegister", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"numberCakeToUpdate", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"numberTeams", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"", + "type":"address" + }, + { + "internalType":"address", + "name":"", + "type":"address" + }, + { + "internalType":"uint256", + "name":"", + "type":"uint256" + }, + { + "internalType":"bytes", + "name":"", + "type":"bytes" + } + ], + "name":"onERC721Received", + "outputs":[ + { + "internalType":"bytes4", + "name":"", + "type":"bytes4" + } + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"pauseProfile", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"_nftAddress", + "type":"address" + }, + { + "internalType":"uint256", + "name":"_tokenId", + "type":"uint256" + } + ], + "name":"reactivateProfile", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"uint256", + "name":"_teamId", + "type":"uint256" + }, + { + "internalType":"uint256", + "name":"_numberPoints", + "type":"uint256" + } + ], + "name":"removeTeamPoints", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"_userAddress", + "type":"address" + }, + { + "internalType":"uint256", + "name":"_numberPoints", + "type":"uint256" + } + ], + "name":"removeUserPoints", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address[]", + "name":"_userAddresses", + "type":"address[]" + }, + { + "internalType":"uint256", + "name":"_numberPoints", + "type":"uint256" + } + ], + "name":"removeUserPointsMultiple", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"uint256", + "name":"_teamId", + "type":"uint256" + }, + { + "internalType":"string", + "name":"_teamName", + "type":"string" + }, + { + "internalType":"string", + "name":"_teamDescription", + "type":"string" + } + ], + "name":"renameTeam", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"bytes32", + "name":"role", + "type":"bytes32" + }, + { + "internalType":"address", + "name":"account", + "type":"address" + } + ], + "name":"renounceRole", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"bytes32", + "name":"role", + "type":"bytes32" + }, + { + "internalType":"address", + "name":"account", + "type":"address" + } + ], + "name":"revokeRole", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"uint256", + "name":"_newNumberCakeToReactivate", + "type":"uint256" + }, + { + "internalType":"uint256", + "name":"_newNumberCakeToRegister", + "type":"uint256" + }, + { + "internalType":"uint256", + "name":"_newNumberCakeToUpdate", + "type":"uint256" + } + ], + "name":"updateNumberCake", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"_nftAddress", + "type":"address" + }, + { + "internalType":"uint256", + "name":"_tokenId", + "type":"uint256" + } + ], + "name":"updateProfile", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + } +] diff --git a/package.json b/package.json index bc55fed9..f23496d8 100644 --- a/package.json +++ b/package.json @@ -9,12 +9,15 @@ "codegen:blocks": "graph codegen subgraphs/blocks.yaml", "codegen:dexcandles": "graph codegen subgraphs/dexcandles.yaml", "codegen:exchange": "graph codegen subgraphs/exchange.yaml", + "codegen:profile": "graph codegen subgraphs/profile.yaml", "build:blocks": "graph build subgraphs/blocks.yaml", "build:dexcandles": "graph build subgraphs/dexcandles.yaml", "build:exchange": "graph build subgraphs/exchange.yaml", + "build:profile": "graph build subgraphs/profile.yaml", "deploy:blocks": "graph deploy --node https://api.thegraph.com/deploy/ --ipfs https://api.thegraph.com/ipfs/ pancakeswap/blocks subgraphs/blocks.yaml", "deploy:dexcandles": "graph deploy --node https://api.thegraph.com/deploy/ --ipfs https://api.thegraph.com/ipfs/ pancakeswap/dex-candles subgraphs/dexcandles.yaml", "deploy:exchange": "graph deploy --node https://api.thegraph.com/deploy/ --ipfs https://api.thegraph.com/ipfs/ pancakeswap/exchange subgraphs/exchange.yaml", + "deploy:profile": "graph deploy --node https://api.thegraph.com/deploy/ --ipfs https://api.thegraph.com/ipfs/ pancakeswap/profile subgraphs/profile.yaml", "format": "prettier --write '*/**/*.{js,ts}'", "lint": "eslint '*/**/*.{js,ts}'" }, diff --git a/src/profile/profile.ts b/src/profile/profile.ts new file mode 100644 index 00000000..31c49543 --- /dev/null +++ b/src/profile/profile.ts @@ -0,0 +1,163 @@ +/* eslint-disable prefer-const */ +import { BigInt, Bytes, log } from "@graphprotocol/graph-ts"; +import { concat } from "@graphprotocol/graph-ts/helper-functions"; +import { Points, Team, User } from "../../generated/schema"; +import { + TeamAdd, + TeamPointIncrease, + UserChangeTeam, + UserNew, + UserPause, + UserPointIncrease, + UserReactivate, +} from "../../generated/Profile/Profile"; + +let ZERO_BI = BigInt.fromI32(0); +let ONE_BI = BigInt.fromI32(1); + +/** + * TEAM + */ + +export function handleTeamAdd(event: TeamAdd): void { + // Fail safe condition in case the team has already been created. + let team = Team.load(event.params.teamId.toHex()); + if (team === null) { + team = new Team(event.params.teamId.toHex()); + team.name = event.params.teamName; + team.totalUsers = ZERO_BI; + team.totalPoints = ZERO_BI; + team.isJoinable = true; + team.users = []; + team.points = []; + team.save(); + } +} + +export function handleTeamPointIncrease(event: TeamPointIncrease): void { + let team = Team.load(event.params.teamId.toHex()); + if (team === null) { + log.error("Error in contract, increased point when team was not created.", []); + } + + let pointId = concat( + Bytes.fromI32(event.params.campaignId.toI32()), + Bytes.fromI32(event.params.teamId.toI32()) + ).toHex(); + let point = new Points(pointId); + point.points = event.params.numberPoints; + point.campaignId = event.params.campaignId; + point.save(); + + team.totalPoints = team.totalUsers.plus(event.params.numberPoints); + team.points = team.points.concat([point.id]); + team.save(); +} + +/** + * USER + */ + +export function handleUserNew(event: UserNew): void { + // Fail safe condition in case the user has already been created. + let user = User.load(event.params.teamId.toHex()); + if (user === null) { + user = new User(event.params.userAddress.toHex()); + user.totalPoints = ZERO_BI; + user.isActive = true; + user.points = []; + user.team = event.params.teamId.toHex(); + user.save(); + } + + // Update the team based on the new user joining it. + let team = Team.load(event.params.teamId.toHex()); + if (team === null) { + log.error("Error in contract, joined team when team was not created.", []); + } + team.totalUsers = team.totalUsers.plus(ONE_BI); + team.users = team.users.concat([event.params.userAddress.toHex()]); + team.save(); +} + +export function handleUserPause(event: UserPause): void { + let user = User.load(event.params.userAddress.toHex()); + if (user === null) { + log.error("Error in contract, paused user when user was not created.", []); + } + user.isActive = false; + user.save(); + + // Update the team based on the new user joining it. + let team = Team.load(event.params.teamId.toHex()); + if (team === null) { + log.error("Error in contract, paused user when team was not created.", []); + } + team.totalUsers = team.totalUsers.minus(ONE_BI); + team.save(); +} + +export function handleUserReactivate(event: UserReactivate): void { + let user = User.load(event.params.userAddress.toHex()); + if (user === null) { + log.error("Error in contract, resumed user when user was not created.", []); + } + user.isActive = true; + user.save(); + + // Update the team based on the new user joining it. + let team = Team.load(event.params.teamId.toHex()); + if (team === null) { + log.error("Error in contract, resumed user when team was not created.", []); + } + team.totalUsers = team.totalUsers.plus(ONE_BI); + team.save(); +} + +export function handleUserChangeTeam(event: UserChangeTeam): void { + // Update the (old) team based on the user leaving it. + let oldTeam = Team.load(event.params.oldTeamId.toHex()); + if (oldTeam === null) { + log.error("Error in contract, changed team when (old) team was not created.", []); + } + oldTeam.totalUsers = oldTeam.totalUsers.minus(ONE_BI); + oldTeam.users = oldTeam.users.filter((user) => user !== event.params.userAddress.toHex()); + oldTeam.save(); + + // Update the (new) team based on the user joining it. + let newTeam = Team.load(event.params.newTeamId.toHex()); + if (newTeam === null) { + log.error("Error in contract, changed team when (new) team was not created.", []); + } + newTeam.totalUsers = newTeam.totalUsers.plus(ONE_BI); + newTeam.users = newTeam.users.concat([event.params.userAddress.toHex()]); + newTeam.save(); + + // Update the user based on his (new) team. + let user = User.load(event.params.userAddress.toHex()); + if (user === null) { + log.error("Error in contract, changed team when user was not created.", []); + } + user.team = newTeam.id; + user.save(); +} + +export function handleUserPointIncrease(event: UserPointIncrease): void { + let user = User.load(event.params.userAddress.toHex()); + if (user === null) { + log.error("Error in contract, increased point when user was not created.", []); + } + + let pointId = concat( + Bytes.fromI32(event.params.campaignId.toI32()), + Bytes.fromHexString(event.params.userAddress.toHex()) + ).toHex(); + let point = new Points(pointId); + point.points = event.params.numberPoints; + point.campaignId = event.params.campaignId; + point.save(); + + user.totalPoints = user.totalPoints.plus(event.params.numberPoints); + user.points = user.points.concat([point.id]); + user.save(); +} diff --git a/subgraphs/profile.graphql b/subgraphs/profile.graphql new file mode 100644 index 00000000..3194f931 --- /dev/null +++ b/subgraphs/profile.graphql @@ -0,0 +1,37 @@ +type Team @entity { + id: ID! + + name: String! + # description: String! + + totalUsers: BigInt! + totalPoints: BigInt! + + isJoinable: Boolean! + + # Users + users: [User!]! + + # Points with campaignId + points: [Points!]! +} + +type User @entity { + id: ID! # address + + totalPoints: BigInt! + + isActive: Boolean! + + # Points with campaignId + points: [Points!]! + + team: Team! +} + +type Points @entity { + id: ID! # address/teamId + campaignId + + points: BigInt! + campaignId: BigInt! +} diff --git a/subgraphs/profile.yaml b/subgraphs/profile.yaml new file mode 100644 index 00000000..ac92cb8d --- /dev/null +++ b/subgraphs/profile.yaml @@ -0,0 +1,40 @@ +specVersion: 0.0.2 +description: Pancake Profile +repository: https://github.com/pancakeswap +schema: + file: ./profile.graphql +dataSources: + - kind: ethereum/contract + name: Profile + network: bsc + source: + address: '0xDf4dBf6536201370F95e06A0F8a7a70fE40E388a' + abi: Profile + startBlock: 4570433 + mapping: + kind: ethereum/events + apiVersion: 0.0.4 + language: wasm/assemblyscript + file: ../src/profile/profile.ts + entities: + - Team + - User + - Points + abis: + - name: Profile + file: ../abis/profile.json + eventHandlers: + - event: TeamAdd(uint256,string) + handler: handleTeamAdd + - event: TeamPointIncrease(indexed uint256,uint256,indexed uint256) + handler: handleTeamPointIncrease + - event: UserNew(indexed address,uint256,address,uint256) + handler: handleUserNew + - event: UserPause(indexed address,uint256) + handler: handleUserPause + - event: UserReactivate(indexed address,uint256,address,uint256) + handler: handleUserReactivate + - event: UserChangeTeam(indexed address,uint256,uint256) + handler: handleUserChangeTeam + - event: UserPointIncrease(indexed address,uint256,indexed uint256) + handler: handleUserPointIncrease