Reading Onchain Points

To read data for a given Social Club, you only need its collectionId. Once you have that, you can query points for a given address.

How to get the collectionId for a Social Club

From the Social Club page

On a creator's Social Club page, you can get the collectionId from the tag icon on the bottom right of the badge card, under Rewards.

MadFi Club URL | https://madfi.xyz/creators/madfinance

From the subgraph

If you know the club creator's address and Lens profileId you can query our subgraph or check the playground.

API URL | https://api.thegraph.com/subgraphs/name/mad-finance/madfi-subgraph

{
  madCreator(id: "{addressLowerCase}-{lensProfileIdDecimal}") {
    activeMadSBT {
      collectionId
    }
  }
}

Reading the onchain points for a Social Club member

Once you have a collectionId you can use it to query the onchain points for a specific member/ badge holder with just their address.

From the subgraph

API URL | https://api.thegraph.com/subgraphs/name/mad-finance/madfi-subgraph

{
  madSbtTokens(where:{collection_:{collectionId:"{collectionId}"}, owner_:{id:"{addressLowerCase}"}}){
    collection {
      collectionId
    }
    tokenId
    owner {
      id
    }
    rewardPoints
  }
}

From the MadSBT contract

Contract Address (Polygon) | 0x22209D6eAe6cEBA2d059ebfE67b67837BCC1b428

Function interface

function rewardUnitsOf(address account, uint256 collectionId) external view returns (uint128)

With viem

import { createPublicClient, http } from 'viem'
import { polygon } from 'viem/chains'

const publicClient = createPublicClient({ chain: polygon,transport: http() })

const MAD_SBT_ADDRESS = ''; // TODO: MAINNET
const MAD_SBT_ABI = [{
  inputs: [
    { internalType: "address", name: "account", type: "address" },
    { internalType: "uint256", name: "collectionId", type: "uint256" }
  ],
  name: "rewardUnitsOf",
  outputs: [{ internalType: "uint128", name: "", type: "uint128" }],
  stateMutability: "view",
  type: "function"
}]
const collectionId = "1"
const address = "0x..."

const data = await publicClient.readContract({
  address: MAD_SBT_ADDRESS,
  abi: MAD_SBT_ABI,
  functionName: 'rewardUnitsOf',
  args: [address, collectionId]
})

console.log(`rewardPoints: ${(data as BigInt).toString()}`)

Reading total units distributed in a Social Club

If you want to calculate a given holder's points proportional to the total units distributed in the club, you need to also query the total units distributed. This value can only be read onchain.

Function interface

function totalRewardUnits(uint256 collectionId) external view returns (uint128)

Calculating the proportional points with viem (same setup as above)

// ...
const MAD_SBT_ABI = [
  // ...
  {
    inputs: [{ internalType: "uint256", name: "collectionId", type: "uint256" }],
    name: "totalRewardUnits",
    outputs: [{ internalType: "uint128", name: "", type: "uint128" }],
    stateMutability: "view",
    type: "function"
  }
]
// .. 

const points = await publicClient.readContract({
  address: MAD_SBT_ADDRESS,
  abi: MAD_SBT_ABI,
  functionName: 'rewardUnitsOf',
  args: [address, collectionId]
})

const totalPoints = await publicClient.readContract({
  address: MAD_SBT_ADDRESS,
  abi: MAD_SBT_ABI,
  functionName: 'totalRewardUnits',
  args: [collectionId]
})

const pointsProportinoal = points / totalPoints
console.log(`pointsProportinoal: ${(pointsProportinoal).toString()}`)
function collectionData(uint256) external view returns (uint,uint,uint,uint,uint128 totalInterimRewardUnits,address,string memory,bool)

Last updated