Skip to content

Commit

Permalink
Merge branch 'staging'
Browse files Browse the repository at this point in the history
  • Loading branch information
KONFeature committed Jan 20, 2025
2 parents 4cbe80c + 1989f98 commit 3e89296
Show file tree
Hide file tree
Showing 4 changed files with 174 additions and 3 deletions.
2 changes: 1 addition & 1 deletion packages/ponder/abis/addresses.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"campaignBankFactory": "0x00000000003604CF2d09f4Aa3B878843A765015d",
"campaignFactory": "0x3401B830b4C6805Dc192906679514e849aFeda41",
"campaignFactory": "0xfE0D3FD4ed50CE828b8192fc5D547Ee609Abe1eC",
"facetFactory": "0x5Dcb1bB90Fc25ceFe9815bbd0c710F0496Fe946B",
"mUSDToken": "0x43838DCb58a61325eC5F31FD70aB8cd3540733d1",
"productAdministratorRegistry": "0x0000000000000823EaD12075a50A2a6520966e5c",
Expand Down
34 changes: 34 additions & 0 deletions packages/ponder/abis/campaignAbis.ts
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,23 @@ export const affiliationFixedCampaignAbi = [
internalType: "contract CampaignBank",
type: "address",
},
{
name: "chainingConfig",
internalType: "struct RewardChainingConfig",
type: "tuple",
components: [
{
name: "userPercent",
internalType: "uint256",
type: "uint256",
},
{
name: "deperditionPerLevel",
internalType: "uint256",
type: "uint256",
},
],
},
],
stateMutability: "view",
},
Expand Down Expand Up @@ -429,6 +446,23 @@ export const affiliationRangeCampaignAbi = [
internalType: "contract CampaignBank",
type: "address",
},
{
name: "chainingConfig",
internalType: "struct RewardChainingConfig",
type: "tuple",
components: [
{
name: "userPercent",
internalType: "uint256",
type: "uint256",
},
{
name: "deperditionPerLevel",
internalType: "uint256",
type: "uint256",
},
],
},
],
stateMutability: "view",
},
Expand Down
5 changes: 4 additions & 1 deletion packages/ponder/config/configBuilder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,10 @@ type EnvNetworkConfig = {
* Set of old factory addresses we wan't to continue to index
*/
const oldAddresses = {
campaignFactoy: ["0x0000000000278e0EFbC5968020A798AaB1571E5c"],
campaignFactoy: [
"0x0000000000278e0EFbC5968020A798AaB1571E5c",
"0x3401B830b4C6805Dc192906679514e849aFeda41",
],
} as const;

/**
Expand Down
136 changes: 135 additions & 1 deletion packages/ponder/src/api/stats.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
import { ponder } from "ponder:registry";
import {
affiliationCampaignStatsTable,
bankingContractTable,
campaignTable,
interactionEventTable,
productInteractionContractTable,
productTable,
rewardTable,
} from "ponder:schema";
import { count, countDistinct, eq, gte } from "ponder";
import { count, countDistinct, eq, gte, inArray, max } from "ponder";
import { type Address, type Hex, isAddressEqual } from "viem";

/**
* Get the overall system stats
Expand Down Expand Up @@ -76,3 +81,132 @@ ponder.get("/stats/overall", async (ctx) => {
products: totalProducts[0]?.count,
});
});

/**
* Get all the wallets related stats
*/
ponder.get("/stats/wallets", async (ctx) => {
// Total wallets with interactions
const allWallets = await ctx.db
.select({
wallet: interactionEventTable.user,
interactionsContract: interactionEventTable.interactionId,
interactions: countDistinct(interactionEventTable.id),
lastInteraction: max(interactionEventTable.timestamp),
})
.from(interactionEventTable)
.groupBy(
interactionEventTable.user,
interactionEventTable.interactionId
);

// Get the product related to each interactions contract
const uniqueInteractionContracts = [
...new Set(allWallets.map((wallet) => wallet.interactionsContract)),
] as Hex[];
const uniqueWallets = [
...new Set(allWallets.map((wallet) => wallet.wallet)),
] as Address[];

// Then find the list of products on which each wallet interacted
const products = await ctx.db
.select({
id: productInteractionContractTable.id,
productId: productInteractionContractTable.productId,
name: productTable.name,
})
.from(productInteractionContractTable)
.innerJoin(
productTable,
eq(productInteractionContractTable.productId, productTable.id)
)
.where(
inArray(
productInteractionContractTable.id,
uniqueInteractionContracts
)
);

// Then find the rewards for each wallets
const rewards = await ctx.db
.select({
wallet: rewardTable.user,
totalReceived: rewardTable.totalReceived,
totalClaimed: rewardTable.totalReceived,
})
.from(rewardTable)
.where(inArray(rewardTable.user, uniqueWallets));

// Merge everything together (list = { wallet: products: [], rewards: []})
const output = uniqueWallets.map((wallet) => {
// Build the product map for this wallet
const walletWithProducts = allWallets.filter((wallet) =>
isAddressEqual(wallet.wallet, wallet.wallet)
);
const finalProducts = walletWithProducts.map((wallet) => {
const contract = wallet.interactionsContract;
const product = products.find((product) =>
isAddressEqual(product.id, contract)
);
return {
id: product?.id,
name: product?.name,
interactions: wallet.interactions,
lastTimestamp: wallet.lastInteraction,
};
});

return {
wallet: wallet,
products: finalProducts,
rewards: rewards.filter((reward) =>
isAddressEqual(reward.wallet, wallet)
),
};
});

return ctx.json({
allWallets,
uniqueInteractionContracts,
products,
output,
});
});

/**
* Get some campaign related stats
*/
ponder.get("/stats/campaigns", async (ctx) => {
const afilliationCampaigns = await ctx.db
.select({
id: campaignTable.id,
name: campaignTable.name,
bank: campaignTable.bankingContractId,
totalInteractions: affiliationCampaignStatsTable.totalInteractions,
openInteractions: affiliationCampaignStatsTable.openInteractions,
readInteractions: affiliationCampaignStatsTable.readInteractions,
customerMeetingInteractions:
affiliationCampaignStatsTable.customerMeetingInteractions,
referredInteractions:
affiliationCampaignStatsTable.referredInteractions,
createReferredLinkInteractions:
affiliationCampaignStatsTable.createReferredLinkInteractions,
purchaseStartedInteractions:
affiliationCampaignStatsTable.purchaseStartedInteractions,
purchaseCompletedInteractions:
affiliationCampaignStatsTable.purchaseCompletedInteractions,
totalRewards: affiliationCampaignStatsTable.totalRewards,
rewardCount: affiliationCampaignStatsTable.rewardCount,
})
.from(affiliationCampaignStatsTable)
.innerJoin(
campaignTable,
eq(affiliationCampaignStatsTable.campaignId, campaignTable.id)
)
.innerJoin(
bankingContractTable,
eq(campaignTable.bankingContractId, bankingContractTable.id)
);

return ctx.json(afilliationCampaigns);
});

0 comments on commit 3e89296

Please sign in to comment.