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) {
id: Bytes!
owner: Bytes! # address
spender: Bytes! # address
value: BigInt! # uint256
blockNumber: BigInt!
blockTimestamp: BigInt!
transactionHash: Bytes!
type Player @entity {
id: ID! # player address
createdAt: BigInt!
lastRaidedAt: BigInt!
totalMinted: BigInt!
currentBalance: BigInt!
numberOfRaids: Int!
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) {
id: Bytes!
previousOwner: Bytes! # address
newOwner: Bytes! # address
blockNumber: BigInt!
blockTimestamp: BigInt!
transactionHash: Bytes!
type Army @entity {
id: ID! # player address
player: Player!
molochDenierLevel: Int!
apprenticeLevel: Int!
anointedLevel: Int!
championLevel: Int!
profitPerSecond: BigInt!
projectedDailyEarnings: BigInt! # Derived from profitPerSecond
totalUnitsPurchased: Int!
lastUnitPurchaseTime: BigInt
}
type PlayerRegistered @entity(immutable: true) {
id: Bytes!
player: Bytes! # address
initialGeld: BigInt! # uint256
blockNumber: BigInt!
blockTimestamp: BigInt!
transactionHash: Bytes!
}
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!
type GlobalStat @entity {
id: ID! # Can be "1" as we only need one instance
totalPlayers: Int!
totalGeldMinted: BigInt!
totalArmyUnits: Int!
lastUpdateTime: BigInt!
topEarnerProfit: BigInt! # Track highest profit per second
}

View File

@ -1,112 +1,164 @@
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,
RaidPerformed,
Transfer,
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 {
let entity = new Approval(
event.transaction.hash.concatI32(event.logIndex.toI32())
)
entity.owner = event.params.owner
entity.spender = event.params.spender
entity.value = event.params.value
// Constants from RaidGeldUtils
const PRECISION = BigInt.fromI32(10000)
const PRICE_FACTOR = BigInt.fromI32(11500)
entity.blockNumber = event.block.number
entity.blockTimestamp = event.block.timestamp
entity.transactionHash = event.transaction.hash
// Unit profits
const MOLOCH_DENIER_PROFIT = BigInt.fromI32(2533)
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(
event: OwnershipTransferredEvent
): void {
let entity = new OwnershipTransferred(
event.transaction.hash.concatI32(event.logIndex.toI32())
)
entity.previousOwner = event.params.previousOwner
entity.newOwner = event.params.newOwner
entity.blockNumber = event.block.number
entity.blockTimestamp = event.block.timestamp
entity.transactionHash = event.transaction.hash
entity.save()
function getOrCreateGlobalStats(): GlobalStat {
let stats = GlobalStat.load("1")
if (!stats) {
stats = new GlobalStat("1")
stats.totalPlayers = 0
stats.totalGeldMinted = BigInt.fromI32(0)
stats.totalArmyUnits = 0
stats.lastUpdateTime = BigInt.fromI32(0)
stats.topEarnerProfit = BigInt.fromI32(0)
}
return stats
}
export function handlePlayerRegistered(event: PlayerRegisteredEvent): void {
let entity = new PlayerRegistered(
event.transaction.hash.concatI32(event.logIndex.toI32())
function calculateArmyStrength(army: Army): BigInt {
// Using the exact same profit calculation for army strength
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 {
let entity = new RaidPerformed(
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()
function calculateProjectedDailyEarnings(profitPerSecond: BigInt): BigInt {
return profitPerSecond.times(BigInt.fromI32(86400)) // 86400 seconds in a day
}
export function handleTransfer(event: TransferEvent): void {
let entity = new Transfer(
event.transaction.hash.concatI32(event.logIndex.toI32())
)
entity.from = event.params.from
entity.to = event.params.to
entity.value = event.params.value
export function handlePlayerRegistered(event: PlayerRegistered): void {
let player = new Player(event.params.player.toHexString())
player.createdAt = event.block.timestamp
player.lastRaidedAt = event.block.timestamp
player.totalMinted = event.params.initialGeld
player.currentBalance = event.params.initialGeld
player.numberOfRaids = 0
player.armyStrength = BigInt.fromI32(0)
player.rank = 0
player.save()
entity.blockNumber = event.block.number
entity.blockTimestamp = event.block.timestamp
entity.transactionHash = event.transaction.hash
let army = new Army(event.params.player.toHexString())
army.player = player.id
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 {
let entity = new UnitAdded(
event.transaction.hash.concatI32(event.logIndex.toI32())
)
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
export function handleRaidPerformed(event: RaidPerformed): void {
let player = Player.load(event.params.player.toHexString())
if (!player) return
entity.blockNumber = event.block.number
entity.blockTimestamp = event.block.timestamp
entity.transactionHash = event.transaction.hash
// Calculate new GELD minted in this raid
let newGeldMinted = event.params.totalMinted.minus(player.totalMinted)
entity.save()
player.totalMinted = event.params.totalMinted
player.currentBalance = event.params.geldBalance
player.lastRaidedAt = event.block.timestamp
player.numberOfRaids += 1
player.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
file: ./abis/RaidGeld.json
eventHandlers:
- event: Approval(indexed address,indexed address,uint256)
handler: handleApproval
- event: OwnershipTransferred(indexed address,indexed address)
handler: handleOwnershipTransferred
- event: PlayerRegistered(indexed address,uint256)
handler: handlePlayerRegistered
- event: RaidPerformed(indexed address,uint256,uint256)
handler: handleRaidPerformed
- event: Transfer(indexed address,indexed address,uint256)
handler: handleTransfer
- event: UnitAdded(indexed address,uint8,uint16,uint256,uint256,uint16,uint16,uint16,uint16)
handler: handleUnitAdded
file: ./src/raid-geld.ts

3541
yarn.lock Normal file

File diff suppressed because it is too large Load Diff