Initial Commit

This commit is contained in:
syahirAmali 2024-10-30 13:59:40 +08:00
parent 7256dccea0
commit 3aa429fdd7
4 changed files with 3711 additions and 154 deletions

View File

@ -1,63 +1,33 @@
type Approval @entity(immutable: true) { type Player @entity {
id: Bytes! id: ID! # player address
owner: Bytes! # address createdAt: BigInt!
spender: Bytes! # address lastRaidedAt: BigInt!
value: BigInt! # uint256 totalMinted: BigInt!
blockNumber: BigInt! currentBalance: BigInt!
blockTimestamp: BigInt! numberOfRaids: Int!
transactionHash: Bytes! army: Army! @derivedFrom(field: "player")
armyStrength: BigInt! # Calculated field for total army power
rank: Int # Position in leaderboard, can be updated periodically
} }
type OwnershipTransferred @entity(immutable: true) { type Army @entity {
id: Bytes! id: ID! # player address
previousOwner: Bytes! # address player: Player!
newOwner: Bytes! # address molochDenierLevel: Int!
blockNumber: BigInt! apprenticeLevel: Int!
blockTimestamp: BigInt! anointedLevel: Int!
transactionHash: Bytes! championLevel: Int!
profitPerSecond: BigInt!
projectedDailyEarnings: BigInt! # Derived from profitPerSecond
totalUnitsPurchased: Int!
lastUnitPurchaseTime: BigInt
} }
type PlayerRegistered @entity(immutable: true) { type GlobalStat @entity {
id: Bytes! id: ID! # Can be "1" as we only need one instance
player: Bytes! # address totalPlayers: Int!
initialGeld: BigInt! # uint256 totalGeldMinted: BigInt!
blockNumber: BigInt! totalArmyUnits: Int!
blockTimestamp: BigInt! lastUpdateTime: BigInt!
transactionHash: Bytes! topEarnerProfit: BigInt! # Track highest profit per second
} }
type RaidPerformed @entity(immutable: true) {
id: Bytes!
player: Bytes! # address
totalMinted: BigInt! # uint256
geldBalance: BigInt! # uint256
blockNumber: BigInt!
blockTimestamp: BigInt!
transactionHash: Bytes!
}
type Transfer @entity(immutable: true) {
id: Bytes!
from: Bytes! # address
to: Bytes! # address
value: BigInt! # uint256
blockNumber: BigInt!
blockTimestamp: BigInt!
transactionHash: Bytes!
}
type UnitAdded @entity(immutable: true) {
id: Bytes!
player: Bytes! # address
unitType: Int! # uint8
nUnits: Int! # uint16
cost: BigInt! # uint256
geldBalance: BigInt! # uint256
molochDenierLevel: Int! # uint16
apprenticeLevel: Int! # uint16
anointedLevel: Int! # uint16
championLevel: Int! # uint16
blockNumber: BigInt!
blockTimestamp: BigInt!
transactionHash: Bytes!
}

View File

@ -1,112 +1,164 @@
import { import {
Approval as ApprovalEvent,
OwnershipTransferred as OwnershipTransferredEvent,
PlayerRegistered as PlayerRegisteredEvent,
RaidPerformed as RaidPerformedEvent,
Transfer as TransferEvent,
UnitAdded as UnitAddedEvent
} from "../generated/RaidGeld/RaidGeld"
import {
Approval,
OwnershipTransferred,
PlayerRegistered, PlayerRegistered,
RaidPerformed, RaidPerformed,
Transfer,
UnitAdded UnitAdded
} from "../generated/schema" } from "../generated/RaidGeld/RaidGeld"
import { Player, Army, GlobalStat } from "../generated/schema"
import { BigInt } from "@graphprotocol/graph-ts"
export function handleApproval(event: ApprovalEvent): void { // Constants from RaidGeldUtils
let entity = new Approval( const PRECISION = BigInt.fromI32(10000)
event.transaction.hash.concatI32(event.logIndex.toI32()) const PRICE_FACTOR = BigInt.fromI32(11500)
)
entity.owner = event.params.owner
entity.spender = event.params.spender
entity.value = event.params.value
entity.blockNumber = event.block.number // Unit profits
entity.blockTimestamp = event.block.timestamp const MOLOCH_DENIER_PROFIT = BigInt.fromI32(2533)
entity.transactionHash = event.transaction.hash const APPRENTICE_PROFIT = BigInt.fromI32(27863)
const ANOINTED_PROFIT = BigInt.fromI32(306493)
const CHAMPION_PROFIT = BigInt.fromI32(3371423)
entity.save() // Base costs (not used in profit calculation but useful for reference)
const MOLOCH_DENIER_BASE_COST = BigInt.fromI32(380000)
const APPRENTICE_BASE_COST = BigInt.fromI32(3420000)
const ANOINTED_BASE_COST = BigInt.fromI32(30096000)
const CHAMPION_BASE_COST = BigInt.fromI32(255816000)
function calculateProfitPerSecond(
molochLevel: i32,
apprenticeLevel: i32,
anointedLevel: i32,
championLevel: i32
): BigInt {
// Exactly matching the RaidGeldUtils calculation
let molochDenierProfit = MOLOCH_DENIER_PROFIT.times(BigInt.fromI32(molochLevel))
let apprenticeProfit = APPRENTICE_PROFIT.times(BigInt.fromI32(apprenticeLevel))
let anointedProfit = ANOINTED_PROFIT.times(BigInt.fromI32(anointedLevel))
let championProfit = CHAMPION_PROFIT.times(BigInt.fromI32(championLevel))
return molochDenierProfit
.plus(apprenticeProfit)
.plus(anointedProfit)
.plus(championProfit)
} }
export function handleOwnershipTransferred( function getOrCreateGlobalStats(): GlobalStat {
event: OwnershipTransferredEvent let stats = GlobalStat.load("1")
): void { if (!stats) {
let entity = new OwnershipTransferred( stats = new GlobalStat("1")
event.transaction.hash.concatI32(event.logIndex.toI32()) stats.totalPlayers = 0
) stats.totalGeldMinted = BigInt.fromI32(0)
entity.previousOwner = event.params.previousOwner stats.totalArmyUnits = 0
entity.newOwner = event.params.newOwner stats.lastUpdateTime = BigInt.fromI32(0)
stats.topEarnerProfit = BigInt.fromI32(0)
entity.blockNumber = event.block.number }
entity.blockTimestamp = event.block.timestamp return stats
entity.transactionHash = event.transaction.hash
entity.save()
} }
export function handlePlayerRegistered(event: PlayerRegisteredEvent): void { function calculateArmyStrength(army: Army): BigInt {
let entity = new PlayerRegistered( // Using the exact same profit calculation for army strength
event.transaction.hash.concatI32(event.logIndex.toI32()) return calculateProfitPerSecond(
army.molochDenierLevel,
army.apprenticeLevel,
army.anointedLevel,
army.championLevel
) )
entity.player = event.params.player
entity.initialGeld = event.params.initialGeld
entity.blockNumber = event.block.number
entity.blockTimestamp = event.block.timestamp
entity.transactionHash = event.transaction.hash
entity.save()
} }
export function handleRaidPerformed(event: RaidPerformedEvent): void { function calculateProjectedDailyEarnings(profitPerSecond: BigInt): BigInt {
let entity = new RaidPerformed( return profitPerSecond.times(BigInt.fromI32(86400)) // 86400 seconds in a day
event.transaction.hash.concatI32(event.logIndex.toI32())
)
entity.player = event.params.player
entity.totalMinted = event.params.totalMinted
entity.geldBalance = event.params.geldBalance
entity.blockNumber = event.block.number
entity.blockTimestamp = event.block.timestamp
entity.transactionHash = event.transaction.hash
entity.save()
} }
export function handleTransfer(event: TransferEvent): void { export function handlePlayerRegistered(event: PlayerRegistered): void {
let entity = new Transfer( let player = new Player(event.params.player.toHexString())
event.transaction.hash.concatI32(event.logIndex.toI32()) player.createdAt = event.block.timestamp
) player.lastRaidedAt = event.block.timestamp
entity.from = event.params.from player.totalMinted = event.params.initialGeld
entity.to = event.params.to player.currentBalance = event.params.initialGeld
entity.value = event.params.value player.numberOfRaids = 0
player.armyStrength = BigInt.fromI32(0)
player.rank = 0
player.save()
entity.blockNumber = event.block.number let army = new Army(event.params.player.toHexString())
entity.blockTimestamp = event.block.timestamp army.player = player.id
entity.transactionHash = event.transaction.hash army.molochDenierLevel = 0
army.apprenticeLevel = 0
army.anointedLevel = 0
army.championLevel = 0
army.profitPerSecond = BigInt.fromI32(0)
army.projectedDailyEarnings = BigInt.fromI32(0)
army.totalUnitsPurchased = 0
army.lastUnitPurchaseTime = event.block.timestamp
army.save()
entity.save() let stats = getOrCreateGlobalStats()
stats.totalPlayers += 1
stats.totalGeldMinted = stats.totalGeldMinted.plus(event.params.initialGeld)
stats.lastUpdateTime = event.block.timestamp
stats.save()
} }
export function handleUnitAdded(event: UnitAddedEvent): void { export function handleRaidPerformed(event: RaidPerformed): void {
let entity = new UnitAdded( let player = Player.load(event.params.player.toHexString())
event.transaction.hash.concatI32(event.logIndex.toI32()) if (!player) return
)
entity.player = event.params.player
entity.unitType = event.params.unitType
entity.nUnits = event.params.nUnits
entity.cost = event.params.cost
entity.geldBalance = event.params.geldBalance
entity.molochDenierLevel = event.params.molochDenierLevel
entity.apprenticeLevel = event.params.apprenticeLevel
entity.anointedLevel = event.params.anointedLevel
entity.championLevel = event.params.championLevel
entity.blockNumber = event.block.number // Calculate new GELD minted in this raid
entity.blockTimestamp = event.block.timestamp let newGeldMinted = event.params.totalMinted.minus(player.totalMinted)
entity.transactionHash = event.transaction.hash
player.totalMinted = event.params.totalMinted
player.currentBalance = event.params.geldBalance
player.lastRaidedAt = event.block.timestamp
player.numberOfRaids += 1
player.save()
entity.save() let stats = getOrCreateGlobalStats()
stats.totalGeldMinted = stats.totalGeldMinted.plus(newGeldMinted)
stats.lastUpdateTime = event.block.timestamp
stats.save()
} }
export function handleUnitAdded(event: UnitAdded): void {
let army = Army.load(event.params.player.toHexString())
if (!army) return
// Update army levels based on the event
if (event.params.unitType == 0) {
army.molochDenierLevel = event.params.molochDenierLevel
} else if (event.params.unitType == 1) {
army.apprenticeLevel = event.params.apprenticeLevel
} else if (event.params.unitType == 2) {
army.anointedLevel = event.params.anointedLevel
} else if (event.params.unitType == 3) {
army.championLevel = event.params.championLevel
}
// Calculate new profit per second using exact RaidGeldUtils values
let profitPerSecond = calculateProfitPerSecond(
army.molochDenierLevel,
army.apprenticeLevel,
army.anointedLevel,
army.championLevel
)
army.profitPerSecond = profitPerSecond
army.projectedDailyEarnings = calculateProjectedDailyEarnings(profitPerSecond)
army.totalUnitsPurchased += event.params.nUnits
army.lastUnitPurchaseTime = event.block.timestamp
army.save()
// Update player's army strength and balance
let player = Player.load(event.params.player.toHexString())
if (!player) return
player.currentBalance = event.params.geldBalance
player.armyStrength = calculateArmyStrength(army)
player.save()
// Update global stats
let stats = getOrCreateGlobalStats()
stats.totalArmyUnits += event.params.nUnits
if (profitPerSecond > stats.topEarnerProfit) {
stats.topEarnerProfit = profitPerSecond
}
stats.lastUpdateTime = event.block.timestamp
stats.save()
}

View File

@ -26,16 +26,10 @@ dataSources:
- name: RaidGeld - name: RaidGeld
file: ./abis/RaidGeld.json file: ./abis/RaidGeld.json
eventHandlers: eventHandlers:
- event: Approval(indexed address,indexed address,uint256)
handler: handleApproval
- event: OwnershipTransferred(indexed address,indexed address)
handler: handleOwnershipTransferred
- event: PlayerRegistered(indexed address,uint256) - event: PlayerRegistered(indexed address,uint256)
handler: handlePlayerRegistered handler: handlePlayerRegistered
- event: RaidPerformed(indexed address,uint256,uint256) - event: RaidPerformed(indexed address,uint256,uint256)
handler: handleRaidPerformed handler: handleRaidPerformed
- event: Transfer(indexed address,indexed address,uint256)
handler: handleTransfer
- event: UnitAdded(indexed address,uint8,uint16,uint256,uint256,uint16,uint16,uint16,uint16) - event: UnitAdded(indexed address,uint8,uint16,uint256,uint256,uint16,uint16,uint16,uint16)
handler: handleUnitAdded handler: handleUnitAdded
file: ./src/raid-geld.ts file: ./src/raid-geld.ts

3541
yarn.lock Normal file

File diff suppressed because it is too large Load Diff