Skip to content

Commit

Permalink
reworked subgraph; added entities for StewardCollective, Reward, Dono…
Browse files Browse the repository at this point in the history
…rCollective, and Donation
  • Loading branch information
krisbitney committed Dec 15, 2023
1 parent 321f623 commit ab3b969
Showing 4 changed files with 192 additions and 82 deletions.
85 changes: 52 additions & 33 deletions packages/subgraph/schema.graphql
Original file line number Diff line number Diff line change
@@ -1,45 +1,62 @@
# TODO
# get total donated from correct field
# handling of generated pools from factory contract
# per collective donor/steward record
# update nft with stewards on claim

type Steward @entity {
"{ user address} "
id: String!
" Number of actions performed "
actions: Int!
totalEarned: BigInt!
" NFT's minted to steward"
nfts: [ProvableNFT!]! @derivedFrom(field: "steward")
" Collectives the steward is apart of "
collectives: [Collective!]! @derivedFrom(field: "stewards")
type Donor @entity {
id: String! # The address of the donor
joined: BigInt!
totalDonated: BigInt!
collectives: [DonorCollective!]!
}

type Donor @entity {
id: String! # This will be the contract address from which the transaction originated
supporter: Bytes! # Address of the supporter
joined: Int!
"""Represents the relationship between a Donor and a Collective"""
type DonorCollective @entity {
id: String! # donorAddress + " " + collectiveAddress
donor: Donor! @derivedFrom(field: "collectives")
collective: Collective! @derivedFrom(field: "donors")
totalDonated: BigInt!
donations: [Donation!]!
}

type Donation @entity {
id: String! # donorAddress + " " + collectiveAddress + " " + timestamp
donor: Donor!
collective: Collective!
timestamp: BigInt
originationContract: Bytes! # The contract address from which the transaction originated
previousContribution: BigInt
contribution: BigInt
previousFlowRate: BigInt
flowRate: BigInt
isFlowUpdate: Boolean
collectives: [Collective!]!
}

type CollectiveDonor @entity {
id: String! #collective_donor
totalDonated: BigInt!
flowRate: BigInt
type Steward @entity {
"""{ user address}"""
id: String!
"""Number of actions performed"""
actions: Int!
totalEarned: BigInt!
"""NFT's minted to steward"""
nfts: [ProvableNFT!]!
"""Collectives the steward is apart of"""
collectives: [StewardCollective!]!
}

type CollectiveSteward @entity {
id: String! #collective_donor
"""Represents the relationship between a Steward and a Collective"""
type StewardCollective @entity {
id: String! # stewardAddress + " " + collectiveAddress
steward: Steward! @derivedFrom(field: "collectives")
collective: Collective! @derivedFrom(field: "stewards")
actions: Int!
totalEarned: BigInt!
nft: [ProvableNFT!]!
rewards: [Reward!]!
}

type Reward @entity {
id: String! # stewardAddress + " " + collectiveAddress + " " + timestamp
steward: Steward!
collective: Collective!
timestamp: BigInt
quantity: BigInt
rewardPerContributor: BigInt
nft: ProvableNFT!
}

type Collective @entity {
@@ -51,8 +68,10 @@ type Collective @entity {
contributions: BigInt!
membersValidator: Bytes
uniquenessValidator: String
donors: [Donor!] @derivedFrom(field: "collectives")
stewards: [Steward!]!
donors: [DonorCollective!]!
stewards: [StewardCollective!]!
donations: [Donation!]! @derivedFrom(field: "collective")
rewards: [Reward!]! @derivedFrom(field: "collective")
rewardToken: String
projectId: String
isVerified: Boolean
@@ -82,7 +101,7 @@ type ProvableNFT @entity {
id: ID!
owner: String!
hash: String!
steward: [Steward!]!
steward: [Steward!]! @derivedFrom(field: "nfts")
collective: Collective!
}

@@ -95,11 +114,11 @@ type EventData @entity {
rewardPerContributor: BigInt!
contributors: [Steward!]!
nft: ProvableNFT!
claim: Claim
claim: Claim @derivedFrom(field: "event")
}

type Claim @entity {
id: String!
totalRewards: BigInt!
events: [EventData!] @derivedFrom(field: "claim")
event: EventData!
}
11 changes: 5 additions & 6 deletions packages/subgraph/src/mappings/ProvableNFT.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
import { ProvableNftMinted } from '../../generated/ProvableNFT/ProvableNFT';
import { ProvableNFT, Steward } from '../../generated/schema';
import { ProvableNFT } from '../../generated/schema';

// Note that ProvableNFT.collective is set by steward reward event
export function handleNftMint(event: ProvableNftMinted): void {
const tokenID = event.params.tokenId.toString();
const to = event.params.to.toHexString();
const nftHash = event.params.nftDataHash.toHexString();

let provableNFT = ProvableNFT.load(tokenID);

if (provableNFT === null) {
provableNFT = new ProvableNFT(tokenID);
provableNFT.id = tokenID;
provableNFT.owner = to; // Fixed this line
provableNFT.hash = nftHash;
provableNFT.save();
}
provableNFT.owner = to;
provableNFT.hash = nftHash;
provableNFT.save();
}
106 changes: 88 additions & 18 deletions packages/subgraph/src/mappings/pool.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { BigInt, Bytes, log } from '@graphprotocol/graph-ts';
import { BigInt, log } from '@graphprotocol/graph-ts';
import {
PoolCreated,
PoolDetailsChanged,
@@ -10,8 +10,17 @@ import {
PoolLimitsChanged,
PoolSettingsChanged,
} from '../../generated/DirectPaymentsPool/DirectPaymentsPool';

import { Claim, Collective, PoolSettings, SafetyLimits, EventData, Steward } from '../../generated/schema';
import {
Claim,
Collective,
PoolSettings,
SafetyLimits,
EventData,
Steward,
StewardCollective,
ProvableNFT,
Reward,
} from '../../generated/schema';

export function handlePoolCreated(event: PoolCreated): void {
const poolAddress = event.params.pool;
@@ -39,6 +48,7 @@ export function handlePoolCreated(event: PoolCreated): void {
directPaymentPool.timestamp = event.block.timestamp.toI32();
directPaymentPool.contributions = BigInt.fromI32(0);
directPaymentPool.stewards = new Array<string>();
directPaymentPool.donors = new Array<string>();
directPaymentPool.save();

// Pool Settings
@@ -141,40 +151,100 @@ export function handleRewardClaim(event: EventRewardClaimed): void {
const eventTimestamp = event.params.eventTimestamp;
const eventQuantity = event.params.eventQuantity;
const eventUri = event.params.eventUri;
const contributers = event.params.contributers;
const rewardPerContributer = event.params.rewardPerContributer;
const contributors = event.params.contributers;
const rewardPerContributor = event.params.rewardPerContributer;

const nftAddress = claimId.toHexString();
const poolAddress = event.address.toHexString();

let pool = Collective.load(event.address.toHexString());
let pool = Collective.load(poolAddress);
if (pool === null) {
log.error('Missing Payment Pool {}', [event.address.toHex()]);
return;
}

let eventData = EventData.load(claimId.toHexString());
let eventData = EventData.load(nftAddress);
if (eventData === null) {
eventData = new EventData(claimId.toHexString());
eventData = new EventData(nftAddress);
eventData.eventType = eventType;
eventData.timestamp = eventTimestamp;
eventData.quantity = eventQuantity;
eventData.uri = eventUri;
eventData.nft = event.params.tokenId.toHexString();
eventData.claim = event.params.tokenId.toHexString();
eventData.quantity = eventQuantity;
eventData.rewardPerContributor = rewardPerContributor;

// handle claim
let claim = Claim.load(claimId.toHexString());
if (claim === null) {
claim = new Claim(claimId.toHexString());
}
claim.event = nftAddress;
claim.totalRewards = rewardPerContributor.times(eventQuantity).times(BigInt.fromI32(contributors.length));

// handle nft -> note that ProvableNFT.hash and ProvableNFT.owner are set by NFT mint event
eventData.nft = nftAddress;
let nft = ProvableNFT.load(nftAddress);
if (nft === null) {
nft = new ProvableNFT(nftAddress);
}
nft.collective = poolAddress;

eventData.contributors = new Array<string>();
for (let i = 0; i < contributers.length; i++) {
eventData.contributors.push(contributers[i].toHexString());
if (pool.stewards.includes(contributers[i].toHexString()) === false) {
pool.stewards.push(contributers[i].toHexString());
for (let i = 0; i < contributors.length; i++) {
const stewardAddress = contributors[i].toHexString();
const stewardCollectiveId = `${stewardAddress} ${poolAddress}`;
const timestamp = event.block.timestamp;
const rewardId = stewardAddress + " " + poolAddress + " " + timestamp.toString();

// adds steward to event data
eventData.contributors.push(stewardAddress);

// update Steward
let steward = Steward.load(contributors[i].toHexString());
if (steward === null) {
steward = new Steward(contributors[i].toHexString());
}
steward.nfts.push(nftAddress);
steward.actions = steward.actions + 1;
const totalReward = rewardPerContributor.times(eventQuantity);
steward.totalEarned = steward.totalEarned.plus(totalReward);

// update StewardCollective
let stewardCollective = StewardCollective.load(stewardCollectiveId);
if (stewardCollective === null) {
stewardCollective = new StewardCollective(stewardCollectiveId);
}
stewardCollective.actions = stewardCollective.actions + 1;
stewardCollective.totalEarned = stewardCollective.totalEarned.plus(totalReward);
// Add StewardCollective to Steward and Collective
if (!steward.collectives.includes(stewardCollectiveId)) {
steward.collectives.push(stewardCollectiveId);
}
if (!pool.stewards.includes(stewardCollectiveId)) {
pool.stewards.push(stewardCollectiveId);
}

// create steward reward
let reward = new Reward(rewardId);
reward.steward = stewardAddress;
reward.collective = poolAddress;
reward.timestamp = timestamp;
reward.quantity = eventQuantity;
reward.rewardPerContributor = rewardPerContributor;
reward.nft = nftAddress;
// add Reward to StewardCollective
stewardCollective.rewards.push(rewardId);

steward.save();
stewardCollective.save();
}

eventData.rewardPerContributor = rewardPerContributer;
claim.save();
nft.save();
pool.save();
eventData.save();
}
}

// event NFTClaimed(uint256 indexed tokenId, uint256 totalRewards);

export function handleClaim(event: NFTClaimed): void {
const claimId = event.params.tokenId;
const totalRewards = event.params.totalRewards;
72 changes: 47 additions & 25 deletions packages/subgraph/src/mappings/superApp.ts
Original file line number Diff line number Diff line change
@@ -1,39 +1,61 @@
import { BigInt, Bytes, log } from '@graphprotocol/graph-ts';
import { BigInt, log } from '@graphprotocol/graph-ts';
import { SupporterUpdated } from '../../generated/DirectPaymentsPool/DirectPaymentsPool';
import { Collective, Donor } from '../../generated/schema';
import { Collective, Donation, Donor, DonorCollective } from '../../generated/schema';

export function handleSupport(event: SupporterUpdated): void {
// TODO: need to call contract functions to get donor/pool total donated including streams, the current method done is incorrect
const donorAddress = event.params.supporter.toHexString();
const poolAddress = event.address.toHexString();
const donorCollectiveId = donorAddress + " " + poolAddress;
const timestamp = event.block.timestamp;
const donationId = donorAddress + " " + poolAddress + " " + timestamp.toString()

let donorId = event.params.supporter.toHexString();
let donor = Donor.load(donorId);
let directPaymentPool = Collective.load(event.address.toHexString());
// update pool
const pool = Collective.load(poolAddress);
// This should never happen
if (pool === null) {
log.error('Missing Payment Pool {}', [event.address.toHex()]);
return;
}
pool.contributions = pool.contributions.plus(event.params.contribution);

// update Donor
let donor = Donor.load(donorAddress);
if (donor == null) {
donor = new Donor(donorId);
donor.supporter = event.params.supporter;
donor.joined = event.block.timestamp.toI32();
donor.totalDonated = event.params.contribution;
donor.collectives = new Array<string>();
donor = new Donor(donorAddress);
donor.joined = timestamp;
donor.totalDonated = BigInt.fromI32(0);
}
// TODO: need to call contract functions to get donor/pool total donated including streams, the current method done is incorrect
donor.totalDonated = donor.totalDonated.plus(event.params.contribution);

if (directPaymentPool === null) {
log.error('Missing Payment Pool {}', [event.address.toHex()]);
return;
// update DonorCollective
let donorCollective = DonorCollective.load(donorCollectiveId);
if (donorCollective == null) {
donorCollective = new DonorCollective(donorCollectiveId);
donorCollective.totalDonated = BigInt.fromI32(0);
}
donorCollective.totalDonated = donorCollective.totalDonated.plus(event.params.contribution);

directPaymentPool.contributions = directPaymentPool.contributions.plus(event.params.contribution);
// create Donation
const donation = new Donation(donationId);
donation.donor = donorAddress;
donation.collective = poolAddress;
donation.timestamp = timestamp;
donation.originationContract = event.address;
donation.previousContribution = event.params.previousContribution;
donation.contribution = event.params.contribution;
donation.previousFlowRate = event.params.previousFlowRate;
donation.flowRate = event.params.flowRate;
donation.isFlowUpdate = event.params.isFlowUpdate;

donor.previousContribution = event.params.previousContribution;
donor.totalDonated = donor.totalDonated.plus(event.params.contribution); // Update totalDonated based on the current total
donor.contribution = event.params.contribution;
donor.previousFlowRate = event.params.previousFlowRate;
donor.flowRate = event.params.flowRate;
donor.isFlowUpdate = event.params.isFlowUpdate;
if (donor.collectives.includes(event.address.toHexString()) == false) {
donor.collectives.push(event.address.toHexString());
}
// add Donation to DonorCollective
donorCollective.donations.push(donationId);

// add DonorCollective to Donor
donor.collectives.push(donorCollectiveId);

directPaymentPool.save(); // Save the updated directPaymentPool entity
donor.save();
donorCollective.save();
donation.save();
pool.save();
}

0 comments on commit ab3b969

Please sign in to comment.