@provable-games/metagame-sdk 0.1.2 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/types/extensions.ts","../src/utils/address.ts","../src/utils/formatting.ts","../src/utils/prizes.ts","../src/utils/status.ts","../src/utils/time.ts","../src/utils/entryFee.ts","../src/utils/prizeAggregation.ts","../src/utils/nftInput.ts","../src/utils/extensions.ts","../src/utils/qualification.ts","../src/utils/proofs.ts","../src/utils/tournamentValidator.ts","../src/utils/opusTroves.ts","../src/utils/prizePool.ts"],"names":["QualifyingMode"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Entry requirement and extension types.\n *\n * These types represent the shared entry requirement system used by\n * EGS metagames. The on-chain extension contracts (tournament validator,\n * ERC20 balance, Opus Troves, Snapshot) are deployed once and used by\n * all metagames — the config parsing and qualification logic is the same.\n */\n\n/** The type of entry requirement on a metagame event */\nexport type EntryRequirementVariant =\n | \"token\"\n | \"extension\"\n | \"none\";\n\n/** Known extension types (deployed as shared contracts) */\nexport type ExtensionType =\n | \"tournament\"\n | \"erc20Balance\"\n | \"opusTroves\"\n | \"snapshot\"\n | \"zkPassport\"\n | \"governance\"\n | \"unknown\";\n\n/** Broad category of an extension */\nexport type ExtensionCategory = \"entryRequirement\" | \"entryFee\" | \"prize\";\n\n/** Deployed extension contract addresses per chain */\nexport interface ExtensionAddresses {\n tournamentValidator?: string;\n erc20BalanceValidator?: string;\n opusTrovesValidator?: string;\n snapshotValidator?: string;\n zkPassportValidator?: string;\n governanceValidator?: string;\n}\n\n/** Parsed config for the tournament validator extension */\nexport interface TournamentValidatorConfig {\n /** \"won\" = must have placed in top N, \"participated\" = just entered */\n requirementType: \"won\" | \"participated\";\n /** How tournaments are combined for qualification */\n qualifyingMode: QualifyingMode;\n /** Number of top positions that count (0 = all positions) */\n topPositions: number;\n /** Tournament IDs that qualify */\n tournamentIds: string[];\n}\n\n/** How multiple qualifying tournaments are evaluated */\nexport enum QualifyingMode {\n /** Qualify in at least one tournament */\n AtLeastOne = 0,\n /** Track entry limits separately per tournament */\n CumulativePerTournament = 1,\n /** Must qualify in all tournaments */\n All = 2,\n /** Track entries per qualifying token ID */\n CumulativePerEntry = 3,\n /** Must participate in all, win in any one */\n AllParticipateAnyWin = 4,\n /** Must participate in all, entries multiply by count */\n AllWithCumulative = 5,\n}\n\n/** Human-readable label and description for a qualifying mode */\nexport interface QualifyingModeInfo {\n label: string;\n description: string;\n}\n\n/** Parsed config for the ERC20 balance validator extension */\nexport interface ERC20BalanceValidatorConfig {\n tokenAddress: string;\n /** Minimum token balance required (raw, in smallest units) */\n minThreshold: bigint;\n /** Maximum token balance cap (raw, 0 = unlimited) */\n maxThreshold: bigint;\n /** Token amount per entry (raw, 0 = single entry regardless of balance) */\n valuePerEntry: bigint;\n /** Maximum entries allowed (0 = unlimited) */\n maxEntries: number;\n}\n\n/** Parsed config for the Opus Troves validator extension */\nexport interface OpusTrovesValidatorConfig {\n /** Number of specific assets required (0 = wildcard, any asset) */\n assetCount: number;\n /** Specific collateral asset addresses (empty if wildcard) */\n assetAddresses: string[];\n /** Minimum debt threshold (raw, 18 decimals — CASH is 1:1 USD) */\n threshold: bigint;\n /** Debt value per entry (raw, 0 = single entry) */\n valuePerEntry: bigint;\n /** Maximum entries allowed (0 = unlimited) */\n maxEntries: number;\n}\n\n/** Parsed config for the Snapshot validator extension */\nexport interface SnapshotValidatorConfig {\n snapshotId: string;\n}\n\n/** Result of checking whether a user qualifies to enter */\nexport interface QualificationResult {\n /** Whether the user meets the entry requirements */\n meetsRequirements: boolean;\n /** The best proof to submit (app-specific format) */\n bestProof: QualificationProof | null;\n /** All valid qualification methods with entries remaining */\n qualifications: QualificationEntry[];\n /** Total entries remaining across all qualification methods */\n totalEntriesLeft: number;\n}\n\n/** A single way the user can qualify */\nexport interface QualificationEntry {\n /** Unique ID for this qualification method */\n id: string;\n /** Entries remaining via this method */\n entriesLeft: number;\n /** The proof data for this qualification */\n proof: QualificationProof;\n /** Human-readable label */\n label?: string;\n /** Additional metadata for display */\n metadata?: Record<string, unknown>;\n}\n\n/** Parsed config for the ZK Passport validator extension */\nexport interface ZkPassportValidatorConfig {\n verifierAddress: string;\n serviceScope: bigint;\n subscope: bigint;\n paramCommitment: bigint;\n maxProofAge: number;\n nullifierType: number;\n}\n\n/** Parsed config for the Governance validator extension */\nexport interface GovernanceValidatorConfig {\n governorAddress: string;\n governanceTokenAddress: string;\n balanceThreshold: bigint;\n proposalId: bigint;\n checkVoted: boolean;\n votesThreshold: bigint;\n votesPerEntry: bigint;\n}\n\n/** Generic config placeholder for entry fee extensions */\nexport interface EntryFeeExtensionConfig {\n tokenAddress: string;\n amount: bigint;\n /** Additional config fields (extension-specific) */\n extra?: Record<string, unknown>;\n}\n\n/** Generic config placeholder for prize extensions */\nexport interface PrizeExtensionConfig {\n tokenAddress: string;\n amount: bigint;\n /** Additional config fields (extension-specific) */\n extra?: Record<string, unknown>;\n}\n\n/** Proof data for entering — varies by requirement type */\nexport interface QualificationProof {\n type: EntryRequirementVariant;\n /** For token requirements: the NFT token ID to use */\n tokenId?: string;\n /** Raw proof array to pass to the extension contract */\n extensionProof?: string[];\n}\n","export function indexAddress(address: string): string {\n return address.replace(/^0x0+/, \"0x\");\n}\n\nexport function padAddress(address: string): string {\n if (address && address !== \"\") {\n const length = address.length;\n const neededLength = 66 - length;\n let zeros = \"\";\n for (let i = 0; i < neededLength; i++) {\n zeros += \"0\";\n }\n return address.substring(0, 2) + zeros + address.substring(2);\n }\n return \"\";\n}\n\nexport function displayAddress(address: string): string {\n if (address === undefined) return \"unknown\";\n return address.substring(0, 6) + \"...\" + address.substring(address.length - 4);\n}\n\nexport function bigintToHex(v: bigint | string | number): string {\n if (!v) return \"0x0\";\n return `0x${BigInt(v).toString(16)}`;\n}\n","export function formatNumber(num: number): string {\n if (Math.abs(num) >= 1000000) {\n return parseFloat((num / 1000000).toFixed(2)) + \"m\";\n } else if (Math.abs(num) >= 1000) {\n return parseFloat((num / 1000).toFixed(2)) + \"k\";\n } else if (Math.abs(num) >= 1) {\n return num.toFixed(0);\n } else if (Math.abs(num) >= 0.1) {\n return num.toFixed(1);\n } else if (Math.abs(num) >= 0.01) {\n return num.toFixed(2);\n } else if (Math.abs(num) >= 0.001) {\n return num.toFixed(3);\n } else if (num === 0) {\n return \"0\";\n } else {\n return num.toFixed(4);\n }\n}\n\nexport function formatPrizeAmount(num: number): string {\n if (Math.abs(num) >= 1000000) {\n return parseFloat((num / 1000000).toFixed(2)) + \"m\";\n } else if (Math.abs(num) >= 1000) {\n return parseFloat((num / 1000).toFixed(2)) + \"k\";\n } else if (Math.abs(num) >= 100) {\n return num.toFixed(1);\n } else if (Math.abs(num) >= 10) {\n return num.toFixed(2);\n } else if (Math.abs(num) >= 1) {\n return num.toFixed(2);\n } else if (Math.abs(num) >= 0.1) {\n return num.toFixed(2);\n } else if (Math.abs(num) >= 0.01) {\n return num.toFixed(3);\n } else if (Math.abs(num) >= 0.001) {\n return num.toFixed(4);\n } else if (num === 0) {\n return \"0\";\n } else {\n return num.toFixed(5);\n }\n}\n\nexport function formatUsdValue(value: number): string {\n if (value === 0) return \"0.00\";\n if (value < 0.01 && value > 0) return \"<0.01\";\n return value.toFixed(2);\n}\n\nexport function formatScore(num: number): string {\n if (Math.abs(num) >= 1000000) {\n return parseFloat((num / 1000000).toFixed(2)) + \"m\";\n } else if (Math.abs(num) >= 1000) {\n return parseFloat((num / 1000).toFixed(2)) + \"k\";\n } else if (Math.abs(num) >= 10) {\n return num.toFixed(0);\n } else if (Math.abs(num) > 0) {\n return num.toFixed(0);\n } else {\n return \"0\";\n }\n}\n\nexport function formatTime(seconds: number): string {\n const minutes = Math.floor(seconds / 60);\n const hours = Math.floor(minutes / 60);\n const days = Math.floor(hours / 24);\n\n if (days > 0) {\n return `${days} Day${days > 1 ? \"s\" : \"\"}`;\n } else if (hours > 0) {\n return `${hours} Hour${hours > 1 ? \"s\" : \"\"}`;\n } else if (minutes > 0) {\n return `${minutes} Min${minutes > 1 ? \"s\" : \"\"}`;\n } else {\n return `${seconds.toFixed(0)} Sec${seconds > 1 ? \"s\" : \"\"}`;\n }\n}\n\nexport function getOrdinalSuffix(position: number): string {\n const formatPosition = isNaN(position) ? 0 : position;\n if (formatPosition % 10 === 1 && formatPosition !== 11) return \"st\";\n if (formatPosition % 10 === 2 && formatPosition !== 12) return \"nd\";\n if (position % 10 === 3 && position !== 13) return \"rd\";\n return \"th\";\n}\n\nexport type DistributionType = \"linear\" | \"exponential\" | \"uniform\";\n\nexport function calculatePayouts(\n totalPlaces: number,\n weightingFactor: number,\n): number[] {\n const weights: number[] = [];\n for (let i = 1; i <= totalPlaces; i++) {\n weights.push(1 / Math.pow(i, weightingFactor));\n }\n\n const totalWeight = weights.reduce((sum, weight) => sum + weight, 0);\n\n const payouts: number[] = weights.map((weight) =>\n Math.floor((weight / totalWeight) * 100),\n );\n\n const totalPayout = payouts.reduce((sum, payout) => sum + payout, 0);\n\n let remaining = 100 - totalPayout;\n let index = 0;\n while (remaining > 0) {\n payouts[index] += 1;\n remaining -= 1;\n index = (index + 1) % totalPlaces;\n }\n\n return payouts;\n}\n\nexport function calculateDistribution(\n positions: number,\n weight: number,\n creatorFee?: number,\n gameFee?: number,\n refundShare?: number,\n distributionType: DistributionType = \"exponential\",\n): number[] {\n if (positions <= 0) {\n return [];\n }\n\n const safeCreatorFee = creatorFee ?? 0;\n const safeGameFee = gameFee ?? 0;\n const safeRefundShare = refundShare ?? 0;\n const prizePoolPercentage =\n 100 - safeCreatorFee - safeGameFee - safeRefundShare;\n\n if (prizePoolPercentage <= 0) {\n return Array(positions).fill(0);\n }\n\n let rawDistributions: number[] = [];\n\n if (distributionType === \"uniform\") {\n rawDistributions = Array(positions).fill(1);\n } else if (distributionType === \"linear\") {\n for (let i = 0; i < positions; i++) {\n const positionValue = positions - i;\n const share = 1 + (positionValue - 1) * (weight / 10);\n rawDistributions.push(share);\n }\n } else {\n for (let i = 0; i < positions; i++) {\n const share = Math.pow(1 - i / positions, weight);\n rawDistributions.push(share);\n }\n }\n\n const total = rawDistributions.reduce((a, b) => a + b, 0);\n\n if (total === 0) {\n return Array(positions).fill(0);\n }\n\n const basisPointShares = rawDistributions.map((d) => {\n const ratio = d / total;\n const basisPoints = ratio * 10000;\n return Math.floor(basisPoints);\n });\n\n const totalBasisPoints = basisPointShares.reduce((a, b) => a + b, 0);\n const remainingBasisPoints = 10000 - totalBasisPoints;\n\n if (remainingBasisPoints !== 0 && positions > 0) {\n basisPointShares[0] = basisPointShares[0] + remainingBasisPoints;\n }\n\n return basisPointShares.map((bp) => bp / 100);\n}\n","import type { Prize } from \"../types/prize\";\n\nexport interface GroupedTokenPrize {\n type: \"erc20\" | \"erc721\";\n address: string;\n totalAmount: string;\n}\n\nexport function groupPrizesByToken(\n prizes: Prize[],\n): Record<string, GroupedTokenPrize> {\n return prizes.reduce(\n (acc, prize) => {\n const key = prize.tokenAddress;\n if (!acc[key]) {\n acc[key] = {\n type: prize.tokenType,\n address: prize.tokenAddress,\n totalAmount: \"0\",\n };\n }\n acc[key].totalAmount = String(\n BigInt(acc[key].totalAmount) + BigInt(prize.amount),\n );\n return acc;\n },\n {} as Record<string, GroupedTokenPrize>,\n );\n}\n\nexport function calculatePrizeValue(\n amount: string,\n decimals: number,\n price: number,\n): number {\n return (Number(amount) / 10 ** decimals) * price;\n}\n","import type { StatusTimestamps, StatusResult } from \"../types/status\";\n\nexport function computeStatus(\n timestamps: StatusTimestamps,\n now?: number,\n): StatusResult {\n const currentTimestamp = now ?? Math.floor(Date.now() / 1000);\n\n // Quest-specific: locked state\n if (timestamps.unlocked === false) {\n return {\n label: \"Locked\",\n variant: \"locked\",\n isActive: false,\n countdown: null,\n };\n }\n\n // Quest-specific: completed state\n if (timestamps.completed) {\n return {\n label: \"Completed\",\n variant: \"completed\",\n isActive: false,\n countdown: null,\n };\n }\n\n const { registrationStart, registrationEnd, start, end, submissionEnd } =\n timestamps;\n\n // Registration phase\n if (registrationStart && registrationEnd) {\n if (currentTimestamp < registrationStart) {\n return {\n label: \"Upcoming\",\n variant: \"upcoming\",\n isActive: false,\n countdown: {\n targetTimestamp: registrationStart,\n label: \"Registration\",\n },\n };\n }\n if (\n currentTimestamp >= registrationStart &&\n currentTimestamp < registrationEnd\n ) {\n return {\n label: \"Registration\",\n variant: \"registration\",\n isActive: true,\n countdown: { targetTimestamp: registrationEnd, label: \"Closes\" },\n };\n }\n }\n\n // Before start\n if (currentTimestamp < start) {\n return {\n label: \"Upcoming\",\n variant: \"upcoming\",\n isActive: false,\n countdown: { targetTimestamp: start, label: \"Starts\" },\n };\n }\n\n // Active / Live\n if (currentTimestamp >= start && currentTimestamp < end) {\n return {\n label: \"Live\",\n variant: \"active\",\n isActive: true,\n countdown: { targetTimestamp: end, label: \"Ends\" },\n };\n }\n\n // Submission phase\n if (submissionEnd && currentTimestamp >= end && currentTimestamp < submissionEnd) {\n return {\n label: \"Submission\",\n variant: \"submission\",\n isActive: true,\n countdown: { targetTimestamp: submissionEnd, label: \"Submit\" },\n };\n }\n\n // Ended\n return {\n label: \"Ended\",\n variant: \"ended\",\n isActive: false,\n countdown: null,\n };\n}\n","export function isBefore(date1: Date, date2: Date): boolean {\n return date1.getTime() < date2.getTime();\n}\n","/**\n * Entry fee breakdown calculation.\n *\n * Takes a total fee pool and share percentages (in basis points, where 10000 = 100%)\n * and returns the amount allocated to each bucket.\n *\n * This is the same math that on-chain metagame contracts use to split entry fees\n * between creator, game creator, refund pool, and prize pool.\n */\n\nexport interface EntryFeeBreakdown {\n /** Total fee collected from all entrants */\n totalCollected: bigint;\n /** Amount going to the metagame creator */\n creatorAmount: bigint;\n /** Amount going to the game creator */\n gameCreatorAmount: bigint;\n /** Amount reserved for refunds */\n refundAmount: bigint;\n /** Amount available for prize distribution */\n prizePoolAmount: bigint;\n}\n\nexport interface EntryFeeShares {\n /** Creator share in basis points (0-10000) */\n creatorShare: number;\n /** Game creator share in basis points (0-10000) */\n gameCreatorShare: number;\n /** Refund share in basis points (0-10000) */\n refundShare: number;\n}\n\n/**\n * Calculate how an entry fee pool is split between creator, game, refund, and prizes.\n *\n * @param feePerEntry - Fee amount per entry (in token units, as bigint)\n * @param entryCount - Number of entries\n * @param shares - Share percentages in basis points (10000 = 100%)\n * @returns Breakdown of amounts for each bucket\n */\nexport function calculateEntryFeeBreakdown(\n feePerEntry: bigint,\n entryCount: number,\n shares: EntryFeeShares,\n): EntryFeeBreakdown {\n const totalCollected = feePerEntry * BigInt(entryCount);\n\n if (totalCollected === 0n) {\n return {\n totalCollected: 0n,\n creatorAmount: 0n,\n gameCreatorAmount: 0n,\n refundAmount: 0n,\n prizePoolAmount: 0n,\n };\n }\n\n const creatorAmount =\n shares.creatorShare > 0\n ? (totalCollected * BigInt(shares.creatorShare)) / 10000n\n : 0n;\n\n const gameCreatorAmount =\n shares.gameCreatorShare > 0\n ? (totalCollected * BigInt(shares.gameCreatorShare)) / 10000n\n : 0n;\n\n const refundAmount =\n shares.refundShare > 0\n ? (totalCollected * BigInt(shares.refundShare)) / 10000n\n : 0n;\n\n const prizePoolBps =\n 10000 - shares.creatorShare - shares.gameCreatorShare - shares.refundShare;\n const prizePoolAmount =\n prizePoolBps > 0 ? (totalCollected * BigInt(prizePoolBps)) / 10000n : 0n;\n\n return {\n totalCollected,\n creatorAmount,\n gameCreatorAmount,\n refundAmount,\n prizePoolAmount,\n };\n}\n\n/**\n * Distribute a prize pool across positions using a distribution curve.\n *\n * Takes the prize pool amount and distribution percentages (from calculateDistribution),\n * and returns the actual token amount per position.\n *\n * @param prizePoolAmount - Total pool to distribute (bigint, in smallest token units)\n * @param percentages - Distribution percentages per position (from calculateDistribution)\n * @returns Array of { position, amount } where position is 1-indexed\n */\nexport function distributePool(\n prizePoolAmount: bigint,\n percentages: number[],\n): Array<{ position: number; amount: bigint }> {\n return percentages\n .map((pct, index) => ({\n position: index + 1,\n amount:\n (prizePoolAmount * BigInt(Math.floor(pct * 100))) / 10000n,\n }))\n .filter((entry) => entry.amount > 0n);\n}\n","import type { Prize } from \"../types/prize\";\n\n/**\n * Prize aggregation by position.\n *\n * Groups prizes by position, summing ERC20 amounts and collecting ERC721 IDs.\n * Works with Prize — metagame apps adapt their raw prize data to this\n * shape before calling these functions.\n */\n\nexport interface PositionPrizeGroup {\n position: number;\n erc20: Array<{ tokenAddress: string; totalAmount: bigint }>;\n erc721: Array<{ tokenAddress: string; tokenIds: string[] }>;\n}\n\n/**\n * Group prizes by leaderboard position, aggregating ERC20 amounts and\n * collecting ERC721 token IDs per position.\n */\nexport function aggregatePrizesByPosition(\n prizes: Prize[],\n): PositionPrizeGroup[] {\n const positionMap = new Map<number, {\n erc20Map: Map<string, bigint>;\n erc721Map: Map<string, string[]>;\n }>();\n\n for (const prize of prizes) {\n if (!positionMap.has(prize.position)) {\n positionMap.set(prize.position, {\n erc20Map: new Map(),\n erc721Map: new Map(),\n });\n }\n const group = positionMap.get(prize.position)!;\n\n if (prize.tokenType === \"erc20\") {\n const current = group.erc20Map.get(prize.tokenAddress) ?? 0n;\n group.erc20Map.set(prize.tokenAddress, current + BigInt(prize.amount));\n } else {\n const ids = group.erc721Map.get(prize.tokenAddress) ?? [];\n ids.push(prize.id);\n group.erc721Map.set(prize.tokenAddress, ids);\n }\n }\n\n return Array.from(positionMap.entries())\n .sort(([a], [b]) => a - b)\n .map(([position, { erc20Map, erc721Map }]) => ({\n position,\n erc20: Array.from(erc20Map.entries()).map(([tokenAddress, totalAmount]) => ({\n tokenAddress,\n totalAmount,\n })),\n erc721: Array.from(erc721Map.entries()).map(([tokenAddress, tokenIds]) => ({\n tokenAddress,\n tokenIds,\n })),\n }));\n}\n\n/**\n * Sponsor contribution aggregated from prizes.\n */\nexport interface SponsorContribution {\n sponsorAddress: string;\n tokens: Array<{\n tokenAddress: string;\n totalAmount: bigint;\n prizeCount: number;\n }>;\n /** NFT collections grouped by token address, with individual token IDs */\n nftCollections: Array<{\n tokenAddress: string;\n tokenIds: string[];\n }>;\n nftCount: number;\n totalPrizeCount: number;\n}\n\n/**\n * Group prizes by sponsor address, aggregating ERC20 contributions and\n * grouping NFTs by collection. Filters out prizes with no sponsor\n * (address \"0x0\" or empty).\n *\n * For ERC721 prizes, `prize.amount` is expected to hold the token ID\n * (this is the convention set by the prize adapter).\n *\n * @param prizes - Array of Prize with sponsorAddress populated\n * @returns Sponsor contributions sorted by total prize count (descending)\n */\nexport function aggregatePrizesBySponsor(\n prizes: Prize[],\n): SponsorContribution[] {\n const sponsorMap = new Map<string, {\n erc20Map: Map<string, { amount: bigint; count: number }>;\n nftMap: Map<string, string[]>;\n nftCount: number;\n totalCount: number;\n }>();\n\n for (const prize of prizes) {\n if (!prize.sponsorAddress || prize.sponsorAddress === \"0x0\") continue;\n\n if (!sponsorMap.has(prize.sponsorAddress)) {\n sponsorMap.set(prize.sponsorAddress, {\n erc20Map: new Map(),\n nftMap: new Map(),\n nftCount: 0,\n totalCount: 0,\n });\n }\n const sponsor = sponsorMap.get(prize.sponsorAddress)!;\n sponsor.totalCount++;\n\n if (prize.tokenType === \"erc20\") {\n const current = sponsor.erc20Map.get(prize.tokenAddress) ?? {\n amount: 0n,\n count: 0,\n };\n sponsor.erc20Map.set(prize.tokenAddress, {\n amount: current.amount + BigInt(prize.amount),\n count: current.count + 1,\n });\n } else {\n sponsor.nftCount++;\n const ids = sponsor.nftMap.get(prize.tokenAddress) ?? [];\n ids.push(prize.amount); // For ERC721, amount holds the token ID\n sponsor.nftMap.set(prize.tokenAddress, ids);\n }\n }\n\n return Array.from(sponsorMap.entries())\n .map(([sponsorAddress, { erc20Map, nftMap, nftCount, totalCount }]) => ({\n sponsorAddress,\n tokens: Array.from(erc20Map.entries()).map(\n ([tokenAddress, { amount, count }]) => ({\n tokenAddress,\n totalAmount: amount,\n prizeCount: count,\n }),\n ),\n nftCollections: Array.from(nftMap.entries()).map(\n ([tokenAddress, tokenIds]) => ({\n tokenAddress,\n tokenIds,\n }),\n ),\n nftCount,\n totalPrizeCount: totalCount,\n }))\n .sort((a, b) => b.totalPrizeCount - a.totalPrizeCount);\n}\n\n/**\n * Filter prizes to only those not yet claimed.\n *\n * @param prizes - All prizes the user could potentially claim\n * @param claimedIds - Set of prize IDs already claimed\n * @returns Prizes not yet claimed\n */\nexport function filterClaimablePrizes(\n prizes: Prize[],\n claimedIds: Set<string>,\n): Prize[] {\n return prizes.filter((prize) => !claimedIds.has(prize.id));\n}\n\n/**\n * Filter out ERC20 prizes with zero amount.\n */\nexport function filterZeroPrizes(prizes: Prize[]): Prize[] {\n return prizes.filter((prize) => {\n if (prize.tokenType === \"erc20\") {\n return BigInt(prize.amount) > 0n;\n }\n return true; // Keep all NFTs\n });\n}\n","/**\n * NFT bulk input parsing for prize creation forms.\n *\n * Metagame UIs often need a textarea where users can paste multiple NFT\n * token IDs with positions. This parser handles two common formats:\n *\n * 1. JSON array: [{ \"tokenId\": 1, \"position\": 1 }, ...]\n * 2. Key-value: \"tokenId:position\" per line or comma-separated\n */\n\nexport interface NftPrizeInput {\n tokenId: string;\n position: number;\n}\n\nexport interface NftParseResult {\n entries: NftPrizeInput[];\n errors: string[];\n}\n\n/**\n * Parse bulk NFT input text into structured entries.\n *\n * Supports:\n * - JSON array: `[{\"tokenId\": 1, \"position\": 1}]`\n * - Key-value lines: `123:1` (tokenId:position)\n * - Comma-separated: `123:1, 456:2, 789:3`\n *\n * @param input - Raw text from a textarea\n * @returns Parsed entries and any validation errors\n */\nexport function parseNFTBulkInput(input: string): NftParseResult {\n const trimmed = input.trim();\n if (!trimmed) return { entries: [], errors: [] };\n\n // Try JSON first\n if (trimmed.startsWith(\"[\")) {\n return parseJsonFormat(trimmed);\n }\n\n // Fall back to key-value format\n return parseKeyValueFormat(trimmed);\n}\n\nfunction parseJsonFormat(input: string): NftParseResult {\n const errors: string[] = [];\n try {\n const parsed = JSON.parse(input);\n if (!Array.isArray(parsed)) {\n return { entries: [], errors: [\"Expected a JSON array\"] };\n }\n\n const entries: NftPrizeInput[] = [];\n for (let i = 0; i < parsed.length; i++) {\n const item = parsed[i];\n const tokenId = item.tokenId ?? item.token_id ?? item.id;\n const position = item.position ?? item.pos;\n\n if (tokenId == null || position == null) {\n errors.push(\n `Item ${i + 1}: missing tokenId or position`,\n );\n continue;\n }\n\n const posNum = Number(position);\n if (!Number.isFinite(posNum) || posNum < 1) {\n errors.push(`Item ${i + 1}: position must be >= 1`);\n continue;\n }\n\n entries.push({ tokenId: String(tokenId), position: posNum });\n }\n\n return { entries, errors };\n } catch {\n return { entries: [], errors: [\"Invalid JSON format\"] };\n }\n}\n\nfunction parseKeyValueFormat(input: string): NftParseResult {\n const errors: string[] = [];\n const entries: NftPrizeInput[] = [];\n\n // Split by newlines, then by commas\n const lines = input\n .split(/[\\n,]/)\n .map((s) => s.trim())\n .filter((s) => s.length > 0);\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n const parts = line.split(\":\").map((s) => s.trim());\n\n if (parts.length !== 2) {\n errors.push(`Line ${i + 1}: expected \"tokenId:position\" format`);\n continue;\n }\n\n const [tokenIdStr, posStr] = parts;\n const position = Number(posStr);\n\n if (!tokenIdStr) {\n errors.push(`Line ${i + 1}: missing tokenId`);\n continue;\n }\n if (!Number.isFinite(position) || position < 1) {\n errors.push(`Line ${i + 1}: position must be >= 1`);\n continue;\n }\n\n entries.push({ tokenId: tokenIdStr, position });\n }\n\n return { entries, errors };\n}\n","/**\n * Extension utilities for EGS entry requirements.\n *\n * The EGS ecosystem has shared extension contracts that any metagame can use\n * for gating entry. These utilities handle:\n * - Identifying which extension type an address corresponds to\n * - Parsing the on-chain config arrays into structured objects\n * - Providing deployed addresses per chain\n *\n * The extension contracts are deployed once and shared across metagames.\n * The config format is defined by each extension's Cairo contract — these\n * parsers match that format exactly.\n */\n\nimport type {\n ExtensionType,\n ExtensionAddresses,\n TournamentValidatorConfig,\n ERC20BalanceValidatorConfig,\n OpusTrovesValidatorConfig,\n SnapshotValidatorConfig,\n ZkPassportValidatorConfig,\n GovernanceValidatorConfig,\n QualifyingMode,\n QualifyingModeInfo,\n} from \"../types/extensions\";\n\n// ---------------------------------------------------------------------------\n// Deployed extension addresses\n// ---------------------------------------------------------------------------\n\nconst EXTENSION_ADDRESSES: Record<string, ExtensionAddresses> = {\n SN_SEPOLIA: {\n tournamentValidator:\n \"0x04c9ba290bbebd47f87141801623748884af610230cdaf69232007b4135be3f1\",\n erc20BalanceValidator:\n \"0x05437210fd8231893da2317971983ae1f810d8d500344ad09e5b258b5820a908\",\n opusTrovesValidator:\n \"0x0317f96eeff41d1badffd9bda126d36c1806523d8c91a5b440f9bdf2aa2b9fe7\",\n snapshotValidator:\n \"0x02628045f0688663ecacbaefdbbc46c2e315b2da39271419e8a3443fe4120f61\",\n zkPassportValidator:\n \"0x025b65137c5297e03491830635f4c5d76eb17e5b2db3bf49dbee34bba94ad3e6\",\n governanceValidator:\n \"0x0585e6b1aa8daac7711004a92a8d0d3b5a81eaac8c9a07db24fc34b1a4f2322c\",\n },\n SN_MAIN: {\n tournamentValidator:\n \"0x0771b57c0709fc4407ff8b63d573f302b96fb03638364032fad734e3c310b9e0\",\n erc20BalanceValidator:\n \"0x051fc2681f65ee18e99dab3cc2ca2eca1b4532c735e752f575ace91ed30f17b7\",\n opusTrovesValidator:\n \"0x0604bc0d54727f439786c65d7dc6f7d46de1aba7e129ef9caf65fef111a1644e\",\n snapshotValidator:\n \"0x03e6820e9e1cfb5c22465a86f469c651355f05397e29fc94de8e832d5f3d8ede\",\n zkPassportValidator:\n \"0x01a25f04c8a39da7bb37adcc53d595fde9e60702611d15b1c498df0657001479\",\n governanceValidator: \"\", // placeholder until deployed\n },\n};\n\n// ---------------------------------------------------------------------------\n// Opus supported collateral assets\n// ---------------------------------------------------------------------------\n\nconst OPUS_SUPPORTED_ASSETS: Record<string, string[]> = {\n SN_SEPOLIA: [],\n SN_MAIN: [\n \"0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7\", // ETH\n \"0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d\", // STRK\n \"0x0124aeb495b947201f5fac96fd1138e326ad86195b98df6dec9009158a533b49\", // LORDS\n \"0x075afe6402ad5a5c20dd25e10ec3b3986acaa647b77e4ae24b0cbc9a54a27a87\", // EKUBO\n \"0x03fe2b97c1fd336e750087d68b9b867997fd64a2661ff3ca5a7c771641e8e7ac\", // WBTC\n ],\n};\n\n/**\n * Get deployed extension addresses for a chain.\n */\nexport function getExtensionAddresses(chainId: string): ExtensionAddresses {\n return EXTENSION_ADDRESSES[chainId] ?? {};\n}\n\n/**\n * Get supported Opus collateral asset addresses for a chain.\n */\nexport function getOpusSupportedAssets(chainId: string): string[] {\n return OPUS_SUPPORTED_ASSETS[chainId] ?? [];\n}\n\n/**\n * Get all whitelisted extension addresses for a chain (normalized).\n */\nexport function getWhitelistedExtensionAddresses(\n chainId: string,\n): Set<string> {\n const addresses = EXTENSION_ADDRESSES[chainId] ?? {};\n const set = new Set<string>();\n for (const addr of Object.values(addresses)) {\n if (addr) {\n set.add(normalizeAddr(addr));\n }\n }\n return set;\n}\n\n/**\n * Check if an extension address is whitelisted for a chain.\n */\nexport function isWhitelistedExtension(\n extensionAddress: string,\n chainId: string,\n): boolean {\n const whitelist = getWhitelistedExtensionAddresses(chainId);\n return whitelist.has(normalizeAddr(extensionAddress));\n}\n\n// ---------------------------------------------------------------------------\n// Extension type identification\n// ---------------------------------------------------------------------------\n\n/**\n * Normalize a Starknet address for comparison (lowercase, strip leading zeros).\n */\nfunction normalizeAddr(address: string): string {\n if (!address) return \"\";\n const hex = address.toLowerCase().replace(/^0x0*/, \"\");\n return hex;\n}\n\n/**\n * Identify which extension type a contract address corresponds to.\n *\n * @param extensionAddress - The extension contract address from the entry requirement\n * @param chainId - The chain ID (e.g., \"SN_MAIN\", \"SN_SEPOLIA\")\n * @returns The extension type, or \"unknown\" if not a recognized preset\n */\nexport function identifyExtensionType(\n extensionAddress: string,\n chainId: string,\n): ExtensionType {\n const addresses = getExtensionAddresses(chainId);\n const normalized = normalizeAddr(extensionAddress);\n\n if (\n addresses.tournamentValidator &&\n normalizeAddr(addresses.tournamentValidator) === normalized\n ) {\n return \"tournament\";\n }\n if (\n addresses.erc20BalanceValidator &&\n normalizeAddr(addresses.erc20BalanceValidator) === normalized\n ) {\n return \"erc20Balance\";\n }\n if (\n addresses.opusTrovesValidator &&\n normalizeAddr(addresses.opusTrovesValidator) === normalized\n ) {\n return \"opusTroves\";\n }\n if (\n addresses.snapshotValidator &&\n normalizeAddr(addresses.snapshotValidator) === normalized\n ) {\n return \"snapshot\";\n }\n if (\n addresses.zkPassportValidator &&\n normalizeAddr(addresses.zkPassportValidator) === normalized\n ) {\n return \"zkPassport\";\n }\n if (\n addresses.governanceValidator &&\n normalizeAddr(addresses.governanceValidator) === normalized\n ) {\n return \"governance\";\n }\n\n return \"unknown\";\n}\n\n// ---------------------------------------------------------------------------\n// Config parsers\n// ---------------------------------------------------------------------------\n\n/**\n * Parse a tournament validator extension config array.\n *\n * Config format: [qualifier_type, qualifying_mode, top_positions, ...tournament_ids]\n * - qualifier_type: \"0\" = participated, \"1\" = won\n * - qualifying_mode: 0-5 (see QualifyingMode enum)\n * - top_positions: 0 = all positions, or N = top N\n * - remaining values: tournament IDs\n */\nexport function parseTournamentValidatorConfig(\n config: Array<string | number | bigint>,\n): TournamentValidatorConfig | null {\n if (!config || config.length < 3) return null;\n\n return {\n requirementType: String(config[0]) === \"1\" ? \"won\" : \"participated\",\n qualifyingMode: Number(config[1]) as QualifyingMode,\n topPositions: Number(config[2]),\n tournamentIds: config.slice(3).map((id) => String(BigInt(id))),\n };\n}\n\n/**\n * Parse an ERC20 balance validator extension config array.\n *\n * Config format: [token_address, min_low, min_high, max_low, max_high, vpe_low, vpe_high, max_entries]\n * Values are u256 split into low (128-bit) and high (128-bit) parts.\n */\nexport function parseERC20BalanceValidatorConfig(\n config: Array<string | number | bigint>,\n): ERC20BalanceValidatorConfig | null {\n if (!config || config.length < 8) return null;\n\n const tokenAddress = String(config[0]);\n const minThreshold = (BigInt(config[2]) << 128n) | BigInt(config[1]);\n const maxThreshold = (BigInt(config[4]) << 128n) | BigInt(config[3]);\n const valuePerEntry = (BigInt(config[6]) << 128n) | BigInt(config[5]);\n const maxEntries = Number(config[7]);\n\n return {\n tokenAddress,\n minThreshold,\n maxThreshold,\n valuePerEntry,\n maxEntries,\n };\n}\n\n/**\n * Parse an Opus Troves validator extension config array.\n *\n * Config format: [asset_count, ...asset_addresses, threshold, value_per_entry, max_entries]\n * - asset_count: 0 = wildcard (any collateral), N = specific assets\n * - asset_addresses: N addresses following asset_count\n * - threshold: minimum debt in CASH (18 decimals, 1:1 USD)\n * - value_per_entry: debt per additional entry\n * - max_entries: cap on entries (0 = unlimited)\n */\nexport function parseOpusTrovesValidatorConfig(\n config: Array<string | number | bigint>,\n): OpusTrovesValidatorConfig | null {\n if (!config || config.length < 4) return null;\n\n const assetCount = Number(config[0]);\n const assetAddresses = config.slice(1, assetCount + 1).map(String);\n const threshold = BigInt(config[assetCount + 1] ?? \"0\");\n const valuePerEntry = BigInt(config[assetCount + 2] ?? \"0\");\n const maxEntries = Number(config[assetCount + 3] ?? \"0\");\n\n return {\n assetCount,\n assetAddresses,\n threshold,\n valuePerEntry,\n maxEntries,\n };\n}\n\n/**\n * Parse a Snapshot validator extension config array.\n *\n * Config format: [snapshot_space_id]\n */\nexport function parseSnapshotValidatorConfig(\n config: Array<string | number | bigint>,\n): SnapshotValidatorConfig | null {\n if (!config || config.length === 0) return null;\n\n return {\n snapshotId: String(Number(BigInt(config[0] ?? \"0\"))),\n };\n}\n\n/**\n * Parse a ZK Passport validator extension config array.\n *\n * Config format: [verifier_address, service_scope, subscope, param_commitment, max_proof_age, nullifier_type]\n */\nexport function parseZkPassportValidatorConfig(\n config: Array<string | number | bigint>,\n): ZkPassportValidatorConfig | null {\n if (!config || config.length < 6) return null;\n\n return {\n verifierAddress: String(config[0]),\n serviceScope: BigInt(config[1]),\n subscope: BigInt(config[2]),\n paramCommitment: BigInt(config[3]),\n maxProofAge: Number(config[4]),\n nullifierType: Number(config[5]),\n };\n}\n\n/**\n * Parse a Governance validator extension config array.\n *\n * Config format: [governor_address, governance_token_address, balance_threshold_low, balance_threshold_high,\n * proposal_id_low, proposal_id_high, check_voted, votes_threshold_low, votes_threshold_high,\n * votes_per_entry_low, votes_per_entry_high]\n */\nexport function parseGovernanceValidatorConfig(\n config: Array<string | number | bigint>,\n): GovernanceValidatorConfig | null {\n if (!config || config.length < 11) return null;\n\n return {\n governorAddress: String(config[0]),\n governanceTokenAddress: String(config[1]),\n balanceThreshold: (BigInt(config[3]) << 128n) | BigInt(config[2]),\n proposalId: (BigInt(config[5]) << 128n) | BigInt(config[4]),\n checkVoted: String(config[6]) === \"1\" || BigInt(config[6]) === 1n,\n votesThreshold: (BigInt(config[8]) << 128n) | BigInt(config[7]),\n votesPerEntry: (BigInt(config[10]) << 128n) | BigInt(config[9]),\n };\n}\n\n/**\n * Parse any extension config by first identifying its type.\n *\n * Returns the parsed config along with the identified type. Useful when\n * you have a raw extension config and need to determine both what it is\n * and what its parameters are in one call.\n */\nexport function parseExtensionConfig(\n extensionAddress: string,\n config: Array<string | number | bigint>,\n chainId: string,\n):\n | { type: \"tournament\"; config: TournamentValidatorConfig }\n | { type: \"erc20Balance\"; config: ERC20BalanceValidatorConfig }\n | { type: \"opusTroves\"; config: OpusTrovesValidatorConfig }\n | { type: \"snapshot\"; config: SnapshotValidatorConfig }\n | { type: \"zkPassport\"; config: ZkPassportValidatorConfig }\n | { type: \"governance\"; config: GovernanceValidatorConfig }\n | { type: \"unknown\"; config: null }\n | null {\n const extensionType = identifyExtensionType(extensionAddress, chainId);\n\n switch (extensionType) {\n case \"tournament\": {\n const parsed = parseTournamentValidatorConfig(config);\n return parsed ? { type: \"tournament\", config: parsed } : null;\n }\n case \"erc20Balance\": {\n const parsed = parseERC20BalanceValidatorConfig(config);\n return parsed ? { type: \"erc20Balance\", config: parsed } : null;\n }\n case \"opusTroves\": {\n const parsed = parseOpusTrovesValidatorConfig(config);\n return parsed ? { type: \"opusTroves\", config: parsed } : null;\n }\n case \"snapshot\": {\n const parsed = parseSnapshotValidatorConfig(config);\n return parsed ? { type: \"snapshot\", config: parsed } : null;\n }\n case \"zkPassport\": {\n const parsed = parseZkPassportValidatorConfig(config);\n return parsed ? { type: \"zkPassport\", config: parsed } : null;\n }\n case \"governance\": {\n const parsed = parseGovernanceValidatorConfig(config);\n return parsed ? { type: \"governance\", config: parsed } : null;\n }\n default:\n return { type: \"unknown\", config: null };\n }\n}\n\n// ---------------------------------------------------------------------------\n// Qualifying mode helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Get a human-readable label and description for a qualifying mode.\n */\nexport function getQualifyingModeInfo(mode: number): QualifyingModeInfo {\n switch (mode) {\n case 0:\n return {\n label: \"At Least One\",\n description: \"Qualify in at least one tournament\",\n };\n case 1:\n return {\n label: \"Cumulative per Tournament\",\n description: \"Track entry limits separately for each tournament\",\n };\n case 2:\n return {\n label: \"All\",\n description: \"Must qualify in all tournaments\",\n };\n case 3:\n return {\n label: \"Cumulative per Entry\",\n description: \"Track entries per qualifying token ID\",\n };\n case 4:\n return {\n label: \"All Participate, Any Win\",\n description:\n \"Must participate in all tournaments, but only need to win in any one\",\n };\n case 5:\n return {\n label: \"All With Cumulative\",\n description:\n \"Must participate in all tournaments, entries multiply by tournament count\",\n };\n default:\n return { label: \"Unknown\", description: \"\" };\n }\n}\n\n// ---------------------------------------------------------------------------\n// Formatting helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Format a raw token amount (bigint) to a human-readable string with decimals.\n * Removes trailing zeros from the decimal part.\n */\nexport function formatTokenAmount(\n value: bigint,\n decimals: number,\n): string {\n if (value === 0n) return \"0\";\n\n const divisor = 10n ** BigInt(decimals);\n const integerPart = value / divisor;\n const remainder = value % divisor;\n\n if (remainder === 0n) return integerPart.toString();\n\n const decimalStr = remainder.toString().padStart(decimals, \"0\");\n const trimmed = decimalStr.replace(/0+$/, \"\");\n return trimmed ? `${integerPart}.${trimmed}` : integerPart.toString();\n}\n\n/**\n * Format a CASH value (18 decimals, 1:1 USD) to a USD string.\n */\nexport function formatCashToUSD(value: bigint): string {\n return formatTokenAmount(value, 18);\n}\n","/**\n * Entry qualification evaluation.\n *\n * Pure functions that determine whether a user qualifies to enter a metagame\n * event based on pre-fetched data. Each metagame fetches the data through\n * their own SDK, then passes it here for evaluation.\n *\n * The evaluation logic is the same across metagames because the entry\n * requirement system (token gating, extensions) is shared.\n */\n\nimport type {\n EntryRequirementVariant,\n QualificationResult,\n QualificationEntry,\n} from \"../types/extensions\";\n\n// ---------------------------------------------------------------------------\n// Token-based qualification (NFT ownership)\n// ---------------------------------------------------------------------------\n\nexport interface TokenQualificationInput {\n /** NFT token IDs owned by the player */\n ownedTokenIds: string[];\n /** Number of times each token has been used to enter (tokenId → count) */\n usedEntryCounts: Record<string, number>;\n /** Max entries per token (0 = unlimited) */\n entryLimit: number;\n}\n\n/**\n * Evaluate token-based entry qualification.\n *\n * Checks if the player owns any qualifying NFTs and how many entries\n * remain for each. Selects the token with the most entries remaining\n * as the best proof.\n */\nexport function evaluateTokenQualification(\n input: TokenQualificationInput,\n): QualificationResult {\n if (input.ownedTokenIds.length === 0) {\n return {\n meetsRequirements: false,\n bestProof: null,\n qualifications: [],\n totalEntriesLeft: 0,\n };\n }\n\n const qualifications: QualificationEntry[] = [];\n\n for (const tokenId of input.ownedTokenIds) {\n const usedCount = input.usedEntryCounts[tokenId] ?? 0;\n const remaining =\n input.entryLimit > 0 ? input.entryLimit - usedCount : Infinity;\n\n if (remaining > 0) {\n qualifications.push({\n id: `token-${tokenId}`,\n entriesLeft: remaining,\n proof: { type: \"token\", tokenId },\n label: `Token #${tokenId}`,\n metadata: { tokenId },\n });\n }\n }\n\n const totalEntriesLeft = qualifications.reduce(\n (sum, q) => sum + (q.entriesLeft === Infinity ? 1 : q.entriesLeft),\n 0,\n );\n\n const best =\n qualifications.length > 0\n ? qualifications.reduce((a, b) =>\n b.entriesLeft > a.entriesLeft ? b : a,\n )\n : null;\n\n return {\n meetsRequirements: qualifications.length > 0,\n bestProof: best?.proof ?? null,\n qualifications,\n totalEntriesLeft,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Extension-based qualification\n// ---------------------------------------------------------------------------\n\nexport interface ExtensionQualificationInput {\n /** Results from checking each qualification method against the extension contract */\n checkedQualifications: Array<{\n id: string;\n entriesLeft: number;\n proof: string[];\n label?: string;\n metadata?: Record<string, unknown>;\n }>;\n}\n\n/**\n * Evaluate extension-based entry qualification from pre-checked results.\n *\n * Each metagame calls the extension contract's `entries_left` function\n * for each potential qualification proof, then passes the results here.\n * This function aggregates and selects the best qualification.\n */\nexport function evaluateExtensionQualification(\n input: ExtensionQualificationInput,\n): QualificationResult {\n const qualifications: QualificationEntry[] = input.checkedQualifications\n .filter((q) => q.entriesLeft > 0)\n .map((q) => ({\n id: q.id,\n entriesLeft: q.entriesLeft,\n proof: {\n type: \"extension\" as const,\n extensionProof: q.proof,\n },\n label: q.label,\n metadata: q.metadata,\n }));\n\n const totalEntriesLeft = qualifications.reduce(\n (sum, q) => sum + q.entriesLeft,\n 0,\n );\n\n const best =\n qualifications.length > 0\n ? qualifications.reduce((a, b) =>\n b.entriesLeft > a.entriesLeft ? b : a,\n )\n : null;\n\n return {\n meetsRequirements: qualifications.length > 0,\n bestProof: best?.proof ?? null,\n qualifications,\n totalEntriesLeft,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Combined qualification\n// ---------------------------------------------------------------------------\n\n/**\n * Evaluate entry qualification based on requirement variant.\n *\n * This is the top-level function — pass in the requirement type and\n * the appropriate input, get back a unified QualificationResult.\n */\nexport function evaluateQualification(\n variant: EntryRequirementVariant,\n input:\n | { type: \"token\"; data: TokenQualificationInput }\n | { type: \"extension\"; data: ExtensionQualificationInput }\n | { type: \"none\" },\n): QualificationResult {\n if (variant === \"none\" || input.type === \"none\") {\n return {\n meetsRequirements: true,\n bestProof: null,\n qualifications: [\n {\n id: \"no-requirement\",\n entriesLeft: Infinity,\n proof: { type: \"none\" },\n },\n ],\n totalEntriesLeft: Infinity,\n };\n }\n\n switch (input.type) {\n case \"token\":\n return evaluateTokenQualification(input.data);\n case \"extension\":\n return evaluateExtensionQualification(input.data);\n default:\n return {\n meetsRequirements: false,\n bestProof: null,\n qualifications: [],\n totalEntriesLeft: 0,\n };\n }\n}\n","/**\n * Qualification proof construction for EGS entry requirements.\n *\n * Builds the on-chain proof calldata that metagames pass when entering\n * an event. The proof format matches the Cairo `QualificationProof` enum:\n *\n * enum QualificationProof {\n * NFT: NFTQualification, // { token_id: u256 }\n * Extension: Span<felt252>,\n * }\n *\n * Extension-specific data (tournament IDs, positions, addresses, etc.)\n * is encoded into the `Extension` variant's felt252 array by the\n * extension's own logic.\n */\n\nimport { CairoCustomEnum, CairoOption, CairoOptionVariant } from \"starknet\";\nimport type { QualificationProof } from \"../types/extensions\";\n\n/**\n * Build the on-chain qualification proof from a QualificationProof object.\n *\n * Returns a `CairoOption<CairoCustomEnum>` ready to pass to a metagame\n * contract's entry function. Returns `None` if no proof is needed.\n *\n * @param proof - The qualification proof from evaluateQualification()\n * @returns CairoOption wrapping the proof enum, ready for contract call\n */\nexport function buildQualificationProof(\n proof: QualificationProof | null,\n): CairoOption<CairoCustomEnum> {\n if (!proof) {\n return new CairoOption(CairoOptionVariant.None);\n }\n\n switch (proof.type) {\n case \"token\":\n return buildNFTProof(proof.tokenId ?? \"0\");\n\n case \"extension\":\n return buildExtensionProof(proof.extensionProof ?? []);\n\n case \"none\":\n return new CairoOption(CairoOptionVariant.None);\n\n default:\n return new CairoOption(CairoOptionVariant.None);\n }\n}\n\n/**\n * Build an NFT ownership proof.\n * Used when entry requires holding a specific NFT collection.\n */\nexport function buildNFTProof(\n tokenId: string,\n): CairoOption<CairoCustomEnum> {\n return new CairoOption(\n CairoOptionVariant.Some,\n new CairoCustomEnum({\n NFT: {\n token_id: {\n low: tokenId,\n high: \"0\",\n },\n },\n Extension: undefined,\n }),\n );\n}\n\n/**\n * Build a tournament validator extension proof.\n * Used when entry requires participation/winning in a prior tournament.\n *\n * The proof array is: [tournament_id, token_id, position]\n */\nexport function buildTournamentExtensionProof(\n tournamentId: string,\n tokenId: string,\n position: number,\n): CairoOption<CairoCustomEnum> {\n return buildExtensionProof([\n tournamentId.toString(),\n tokenId.toString(),\n position.toString(),\n ]);\n}\n\n/**\n * Build a generic extension proof.\n * Used for any extension validator (ERC20 balance, Opus Troves, Snapshot, etc.).\n *\n * @param proofData - Array of felt252 values to pass to the extension contract\n */\nexport function buildExtensionProof(\n proofData: string[],\n): CairoOption<CairoCustomEnum> {\n return new CairoOption(\n CairoOptionVariant.Some,\n new CairoCustomEnum({\n NFT: undefined,\n Extension: proofData,\n }),\n );\n}\n","/**\n * Tournament validator qualification resolution.\n *\n * The tournament validator extension requires players to have participated\n * in (or won) specific prior tournaments. This module resolves which of\n * a player's game tokens can serve as proof of qualification.\n *\n * Every metagame that uses the tournament validator extension needs this\n * same logic — cross-referencing the player's registrations and leaderboard\n * positions against the validator's required tournaments.\n */\n\nimport type { TournamentValidatorConfig } from \"../types/extensions\";\n\n/** A registration record — player entered a tournament with a game token */\nexport interface TournamentRegistration {\n tournamentId: string;\n gameTokenId: string;\n}\n\n/** A leaderboard — ordered list of token IDs for a finalized tournament */\nexport interface TournamentLeaderboard {\n tournamentId: string;\n /** Token IDs in rank order (index 0 = 1st place) */\n tokenIds: string[];\n /** Whether this tournament has finalized */\n isFinalized: boolean;\n}\n\n/** A resolved qualification proof for the tournament validator */\nexport interface TournamentQualificationInput {\n tournamentId: string;\n tokenId: string;\n position: number;\n tournamentName?: string;\n}\n\n/**\n * Build a map of tournament ID → game token IDs the player used to enter.\n *\n * @param registrations - All registrations for the required tournaments\n * @param requiredTournamentIds - Tournament IDs from the validator config\n * @returns Map of tournamentId → array of game token IDs the player registered with\n */\nexport function buildParticipationMap(\n registrations: TournamentRegistration[],\n requiredTournamentIds: string[],\n): Record<string, string[]> {\n const requiredSet = new Set(requiredTournamentIds);\n const map: Record<string, string[]> = {};\n\n for (const reg of registrations) {\n if (!requiredSet.has(reg.tournamentId)) continue;\n if (!map[reg.tournamentId]) map[reg.tournamentId] = [];\n map[reg.tournamentId].push(reg.gameTokenId);\n }\n\n return map;\n}\n\n/**\n * Build a map of tournament ID → winning token positions the player holds.\n *\n * Cross-references finalized leaderboards with the player's owned game tokens\n * to find which tokens placed on which leaderboards.\n *\n * @param leaderboards - Leaderboards for the required tournaments\n * @param ownedGameTokenIds - Game token IDs the player currently owns\n * @param topPositions - Only count positions within top N (0 = all positions)\n * @returns Map of tournamentId → array of { tokenId, position }\n */\nexport function buildWinMap(\n leaderboards: TournamentLeaderboard[],\n ownedGameTokenIds: string[],\n topPositions: number = 0,\n): Record<string, Array<{ tokenId: string; position: number }>> {\n const ownedSet = new Set(ownedGameTokenIds);\n const map: Record<string, Array<{ tokenId: string; position: number }>> = {};\n\n for (const lb of leaderboards) {\n if (!lb.isFinalized) continue;\n\n const limit = topPositions > 0 ? topPositions : lb.tokenIds.length;\n\n for (let i = 0; i < Math.min(limit, lb.tokenIds.length); i++) {\n if (ownedSet.has(lb.tokenIds[i])) {\n if (!map[lb.tournamentId]) map[lb.tournamentId] = [];\n map[lb.tournamentId].push({\n tokenId: lb.tokenIds[i],\n position: i + 1,\n });\n }\n }\n }\n\n return map;\n}\n\n/**\n * Resolve tournament validator qualification inputs from player data.\n *\n * Takes the validator config, the player's registrations/leaderboard positions,\n * and returns the list of proofs to check against the extension contract.\n *\n * @param config - Parsed tournament validator config\n * @param participationMap - From buildParticipationMap()\n * @param winMap - From buildWinMap()\n * @param tournamentNames - Optional map of tournamentId → display name\n * @returns Array of qualification inputs to pass to the extension contract\n */\nexport function resolveTournamentQualifications(\n config: TournamentValidatorConfig,\n participationMap: Record<string, string[]>,\n winMap: Record<string, Array<{ tokenId: string; position: number }>>,\n tournamentNames?: Record<string, string>,\n): TournamentQualificationInput[] {\n const inputs: TournamentQualificationInput[] = [];\n\n if (config.requirementType === \"won\") {\n for (const tournamentId of config.tournamentIds) {\n const wonEntries = winMap[tournamentId];\n if (!wonEntries) continue;\n\n for (const entry of wonEntries) {\n inputs.push({\n tournamentId,\n tokenId: entry.tokenId,\n position: entry.position,\n tournamentName: tournamentNames?.[tournamentId],\n });\n }\n }\n } else {\n // participated\n for (const tournamentId of config.tournamentIds) {\n const tokenIds = participationMap[tournamentId];\n if (!tokenIds) continue;\n\n for (const tokenId of tokenIds) {\n inputs.push({\n tournamentId,\n tokenId,\n position: 1, // Participation = position 1\n tournamentName: tournamentNames?.[tournamentId],\n });\n }\n }\n }\n\n return inputs;\n}\n","/**\n * Opus Troves entry calculation.\n *\n * The Opus Troves extension gates entry based on the player's CASH debt\n * in the Opus Protocol. This module contains the pure math for determining\n * how many entries a given debt level allows, and which entries are bannable\n * if a player's debt drops below the threshold.\n *\n * The trove debt fetching (getUserTroveIds, getTroveHealth) is RPC-specific\n * and stays in each app. This module handles the calculation once you have\n * the debt value.\n */\n\nimport type { OpusTrovesValidatorConfig } from \"../types/extensions\";\n\n/**\n * Calculate how many entries a player's total debt allows.\n *\n * Two modes based on config:\n * - Proportional (valuePerEntry > 0): entries = (debt - threshold) / valuePerEntry\n * - Fixed (valuePerEntry == 0): if debt >= threshold → maxEntries\n *\n * @param debt - Player's total CASH debt across all troves (18 decimals)\n * @param config - Parsed Opus Troves validator config\n * @returns Number of entries allowed (0 if below threshold)\n */\nexport function calculateOpusTrovesEntries(\n debt: bigint,\n config: OpusTrovesValidatorConfig,\n): number {\n let allowed = 0;\n\n if (config.valuePerEntry > 0n) {\n // Proportional: entries scale with debt above threshold\n if (debt > config.threshold) {\n allowed = Number((debt - config.threshold) / config.valuePerEntry);\n }\n } else {\n // Fixed: meets threshold → gets maxEntries\n if (debt >= config.threshold && config.maxEntries > 0) {\n allowed = config.maxEntries;\n }\n }\n\n // Cap at maxEntries if specified\n if (config.maxEntries > 0) {\n allowed = Math.min(allowed, config.maxEntries);\n }\n\n return allowed;\n}\n\n/**\n * Determine which entries should be banned based on debt vs allowed entries.\n *\n * When a player's debt drops below what their entries require, the excess\n * entries (sorted by token ID ascending — oldest first) become bannable.\n *\n * @param registeredTokenIds - Token IDs the player registered with\n * @param entriesAllowed - From calculateOpusTrovesEntries()\n * @returns Set of token IDs that should be banned\n */\nexport function findBannableEntries(\n registeredTokenIds: string[],\n entriesAllowed: number,\n): Set<string> {\n const bannable = new Set<string>();\n const bannableCount = Math.max(0, registeredTokenIds.length - entriesAllowed);\n\n if (bannableCount > 0) {\n // Sort by token ID ascending (oldest entries first)\n const sorted = [...registeredTokenIds].sort((a, b) => {\n return Number(BigInt(a)) - Number(BigInt(b));\n });\n for (let i = 0; i < bannableCount; i++) {\n bannable.add(sorted[i]);\n }\n }\n\n return bannable;\n}\n\n/**\n * Batch calculate bannable entries for multiple players.\n *\n * Takes a map of player → { debt, registeredTokenIds } and returns\n * the set of all bannable token IDs across all players.\n *\n * @param players - Map of player address → their debt and registered entries\n * @param config - Parsed Opus Troves validator config\n * @returns Set of all bannable token IDs\n */\nexport function findAllBannableEntries(\n players: Map<string, { debt: bigint; registeredTokenIds: string[] }>,\n config: OpusTrovesValidatorConfig,\n): Set<string> {\n const allBannable = new Set<string>();\n\n for (const [, { debt, registeredTokenIds }] of players) {\n const allowed = calculateOpusTrovesEntries(debt, config);\n const bannable = findBannableEntries(registeredTokenIds, allowed);\n for (const id of bannable) {\n allBannable.add(id);\n }\n }\n\n return allBannable;\n}\n","import type { Prize } from \"../types/prize\";\nimport { calculateEntryFeeBreakdown, distributePool } from \"./entryFee\";\nimport type { EntryFeeShares } from \"./entryFee\";\nimport { calculateDistribution } from \"./formatting\";\nimport { calculatePrizeValue } from \"./prizes\";\n\n/**\n * Entry fee configuration as provided by metagame contracts (e.g. Budokan SDK).\n */\nexport interface EntryFeeConfig {\n tokenAddress: string;\n amount: string;\n tournamentCreatorShare: number;\n gameCreatorShare: number;\n refundShare: number;\n distribution: unknown;\n distributionCount: number;\n}\n\n/**\n * Build Prize[] from entry fee configuration and entry count.\n *\n * Calculates the total entry fee pool, subtracts creator/game/refund shares,\n * then distributes the remaining prize pool across positions using the\n * configured distribution curve.\n *\n * @param entryFee - Entry fee configuration from the tournament\n * @param entryCount - Number of entries in the tournament\n * @returns Array of Prize objects representing entry fee prizes per position\n */\nexport function buildEntryFeePrizes(\n entryFee: EntryFeeConfig,\n entryCount: number,\n): Prize[] {\n if (!entryFee.amount || entryCount === 0 || entryFee.distributionCount <= 0) {\n return [];\n }\n\n const shares: EntryFeeShares = {\n creatorShare: entryFee.tournamentCreatorShare,\n gameCreatorShare: entryFee.gameCreatorShare,\n refundShare: entryFee.refundShare,\n };\n\n const breakdown = calculateEntryFeeBreakdown(\n BigInt(entryFee.amount),\n entryCount,\n shares,\n );\n\n if (breakdown.prizePoolAmount <= 0n) return [];\n\n // Resolve distribution curve\n const dist = entryFee.distribution as any;\n let distributionType: \"linear\" | \"exponential\" | \"uniform\" = \"uniform\";\n let weight = 10;\n\n if (dist?.type === \"linear\" || dist?.Linear !== undefined) {\n distributionType = \"linear\";\n weight = Number(dist.weight ?? dist.Linear ?? 100) / 10;\n } else if (dist?.type === \"exponential\" || dist?.Exponential !== undefined) {\n distributionType = \"exponential\";\n weight = Number(dist.weight ?? dist.Exponential ?? 100) / 10;\n }\n\n const percentages = calculateDistribution(\n entryFee.distributionCount,\n weight,\n 0,\n 0,\n 0,\n distributionType,\n );\n\n const positions = distributePool(breakdown.prizePoolAmount, percentages);\n\n return positions.map((pos) => ({\n id: `entry_fee_${pos.position}`,\n position: pos.position,\n tokenAddress: entryFee.tokenAddress,\n tokenType: \"erc20\" as const,\n amount: pos.amount.toString(),\n sponsorAddress: \"\",\n }));\n}\n\n/**\n * Token price lookup: normalized address → USD price.\n */\nexport type TokenPriceLookup = Record<string, number>;\n\n/**\n * Token decimals lookup: normalized address → decimals.\n */\nexport type TokenDecimalsLookup = Record<string, number>;\n\n/**\n * Calculate total USD value of a set of prizes.\n *\n * @param prizes - Array of Prize objects (sponsored + entry fee)\n * @param prices - Token price lookup (normalized address → USD price)\n * @param decimals - Token decimals lookup (normalized address → decimals, defaults to 18)\n * @param normalizeAddress - Function to normalize addresses for lookup (e.g. indexAddress)\n * @returns Total USD value, or 0 if any required price is missing\n */\nexport function calculateTotalPrizeValueUSD(\n prizes: Prize[],\n prices: TokenPriceLookup,\n decimals: TokenDecimalsLookup,\n normalizeAddress: (addr: string) => string = (addr) => addr,\n): number {\n let total = 0;\n\n for (const prize of prizes) {\n if (prize.tokenType !== \"erc20\") continue;\n const addr = normalizeAddress(prize.tokenAddress);\n const price = prices[addr];\n if (price === undefined) continue;\n const dec = decimals[addr] ?? 18;\n total += calculatePrizeValue(prize.amount, dec, price);\n }\n\n return total;\n}\n\n/**\n * Calculate the number of paid positions (places that receive prizes).\n *\n * Takes the maximum of sponsored prize positions and entry fee distribution count.\n *\n * @param sponsoredPrizes - Array of sponsored Prize objects\n * @param entryFeeDistributionCount - Number of positions from entry fee distribution\n * @returns Number of paid places\n */\nexport function calculatePaidPlaces(\n sponsoredPrizes: Prize[],\n entryFeeDistributionCount: number,\n): number {\n const maxSponsoredPosition = sponsoredPrizes.reduce(\n (max, p) => Math.max(max, p.position),\n 0,\n );\n return Math.max(maxSponsoredPosition, entryFeeDistributionCount);\n}\n"]}
1
+ {"version":3,"sources":["../src/types/extensions.ts","../src/utils/address.ts","../src/utils/formatting.ts","../src/utils/prizes.ts","../src/utils/status.ts","../src/utils/time.ts","../src/utils/entryFee.ts","../src/utils/prizeAggregation.ts","../src/utils/nftInput.ts","../src/utils/extensions.ts","../src/utils/qualification.ts","../src/utils/proofs.ts","../src/utils/tournamentValidator.ts","../src/utils/opusTroves.ts","../src/utils/prizePool.ts","../src/utils/merkleApi.ts","../src/merkle/merkleTree.ts","../src/merkle/client.ts","../src/client.ts"],"names":["QualifyingMode","DEFAULT_MERKLE_API_URLS"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Entry requirement and extension types.\n *\n * These types represent the shared entry requirement system used by\n * EGS metagames. The on-chain extension contracts (tournament validator,\n * ERC20 balance, Opus Troves, Snapshot) are deployed once and used by\n * all metagames — the config parsing and qualification logic is the same.\n */\n\n/** The type of entry requirement on a metagame event */\nexport type EntryRequirementVariant =\n | \"token\"\n | \"extension\"\n | \"none\";\n\n/** Known extension types (deployed as shared contracts) */\nexport type ExtensionType =\n | \"tournament\"\n | \"erc20Balance\"\n | \"opusTroves\"\n | \"snapshot\"\n | \"zkPassport\"\n | \"governance\"\n | \"merkle\"\n | \"unknown\";\n\n/** Broad category of an extension */\nexport type ExtensionCategory = \"entryRequirement\" | \"entryFee\" | \"prize\";\n\n/** Deployed extension contract addresses per chain */\nexport interface ExtensionAddresses {\n tournamentValidator?: string;\n erc20BalanceValidator?: string;\n opusTrovesValidator?: string;\n snapshotValidator?: string;\n zkPassportValidator?: string;\n governanceValidator?: string;\n merkleValidator?: string;\n}\n\n/** Parsed config for the tournament validator extension */\nexport interface TournamentValidatorConfig {\n /** \"won\" = must have placed in top N, \"participated\" = just entered */\n requirementType: \"won\" | \"participated\";\n /** How tournaments are combined for qualification */\n qualifyingMode: QualifyingMode;\n /** Number of top positions that count (0 = all positions) */\n topPositions: number;\n /** Tournament IDs that qualify */\n tournamentIds: string[];\n}\n\n/** How multiple qualifying tournaments are evaluated */\nexport enum QualifyingMode {\n /** Qualify in at least one tournament */\n AtLeastOne = 0,\n /** Track entry limits separately per tournament */\n CumulativePerTournament = 1,\n /** Must qualify in all tournaments */\n All = 2,\n /** Track entries per qualifying token ID */\n CumulativePerEntry = 3,\n /** Must participate in all, win in any one */\n AllParticipateAnyWin = 4,\n /** Must participate in all, entries multiply by count */\n AllWithCumulative = 5,\n}\n\n/** Human-readable label and description for a qualifying mode */\nexport interface QualifyingModeInfo {\n label: string;\n description: string;\n}\n\n/** Parsed config for the ERC20 balance validator extension */\nexport interface ERC20BalanceValidatorConfig {\n tokenAddress: string;\n /** Minimum token balance required (raw, in smallest units) */\n minThreshold: bigint;\n /** Maximum token balance cap (raw, 0 = unlimited) */\n maxThreshold: bigint;\n /** Token amount per entry (raw, 0 = single entry regardless of balance) */\n valuePerEntry: bigint;\n /** Maximum entries allowed (0 = unlimited) */\n maxEntries: number;\n}\n\n/** Parsed config for the Opus Troves validator extension */\nexport interface OpusTrovesValidatorConfig {\n /** Number of specific assets required (0 = wildcard, any asset) */\n assetCount: number;\n /** Specific collateral asset addresses (empty if wildcard) */\n assetAddresses: string[];\n /** Minimum debt threshold (raw, 18 decimals — CASH is 1:1 USD) */\n threshold: bigint;\n /** Debt value per entry (raw, 0 = single entry) */\n valuePerEntry: bigint;\n /** Maximum entries allowed (0 = unlimited) */\n maxEntries: number;\n}\n\n/** Parsed config for the Snapshot validator extension */\nexport interface SnapshotValidatorConfig {\n snapshotId: string;\n}\n\n/** Result of checking whether a user qualifies to enter */\nexport interface QualificationResult {\n /** Whether the user meets the entry requirements */\n meetsRequirements: boolean;\n /** The best proof to submit (app-specific format) */\n bestProof: QualificationProof | null;\n /** All valid qualification methods with entries remaining */\n qualifications: QualificationEntry[];\n /** Total entries remaining across all qualification methods */\n totalEntriesLeft: number;\n}\n\n/** A single way the user can qualify */\nexport interface QualificationEntry {\n /** Unique ID for this qualification method */\n id: string;\n /** Entries remaining via this method */\n entriesLeft: number;\n /** The proof data for this qualification */\n proof: QualificationProof;\n /** Human-readable label */\n label?: string;\n /** Additional metadata for display */\n metadata?: Record<string, unknown>;\n}\n\n/** Parsed config for the ZK Passport validator extension */\nexport interface ZkPassportValidatorConfig {\n verifierAddress: string;\n serviceScope: bigint;\n subscope: bigint;\n paramCommitment: bigint;\n maxProofAge: number;\n nullifierType: number;\n}\n\n/** Parsed config for the Governance validator extension */\nexport interface GovernanceValidatorConfig {\n governorAddress: string;\n governanceTokenAddress: string;\n balanceThreshold: bigint;\n proposalId: bigint;\n checkVoted: boolean;\n votesThreshold: bigint;\n votesPerEntry: bigint;\n}\n\n/** Parsed config for the Merkle validator extension */\nexport interface MerkleValidatorConfig {\n /** On-chain tree ID (from create_tree) */\n treeId: string;\n}\n\n/** Generic config placeholder for entry fee extensions */\nexport interface EntryFeeExtensionConfig {\n tokenAddress: string;\n amount: bigint;\n /** Additional config fields (extension-specific) */\n extra?: Record<string, unknown>;\n}\n\n/** Generic config placeholder for prize extensions */\nexport interface PrizeExtensionConfig {\n tokenAddress: string;\n amount: bigint;\n /** Additional config fields (extension-specific) */\n extra?: Record<string, unknown>;\n}\n\n/** Proof data for entering — varies by requirement type */\nexport interface QualificationProof {\n type: EntryRequirementVariant;\n /** For token requirements: the NFT token ID to use */\n tokenId?: string;\n /** Raw proof array to pass to the extension contract */\n extensionProof?: string[];\n}\n","export function indexAddress(address: string): string {\n return address.replace(/^0x0+/, \"0x\");\n}\n\nexport function padAddress(address: string): string {\n if (address && address !== \"\") {\n const length = address.length;\n const neededLength = 66 - length;\n let zeros = \"\";\n for (let i = 0; i < neededLength; i++) {\n zeros += \"0\";\n }\n return address.substring(0, 2) + zeros + address.substring(2);\n }\n return \"\";\n}\n\nexport function displayAddress(address: string): string {\n if (address === undefined) return \"unknown\";\n return address.substring(0, 6) + \"...\" + address.substring(address.length - 4);\n}\n\nexport function bigintToHex(v: bigint | string | number): string {\n if (!v) return \"0x0\";\n return `0x${BigInt(v).toString(16)}`;\n}\n","export function formatNumber(num: number): string {\n if (Math.abs(num) >= 1000000) {\n return parseFloat((num / 1000000).toFixed(2)) + \"m\";\n } else if (Math.abs(num) >= 1000) {\n return parseFloat((num / 1000).toFixed(2)) + \"k\";\n } else if (Math.abs(num) >= 1) {\n return num.toFixed(0);\n } else if (Math.abs(num) >= 0.1) {\n return num.toFixed(1);\n } else if (Math.abs(num) >= 0.01) {\n return num.toFixed(2);\n } else if (Math.abs(num) >= 0.001) {\n return num.toFixed(3);\n } else if (num === 0) {\n return \"0\";\n } else {\n return num.toFixed(4);\n }\n}\n\nexport function formatPrizeAmount(num: number): string {\n if (Math.abs(num) >= 1000000) {\n return parseFloat((num / 1000000).toFixed(2)) + \"m\";\n } else if (Math.abs(num) >= 1000) {\n return parseFloat((num / 1000).toFixed(2)) + \"k\";\n } else if (Math.abs(num) >= 100) {\n return num.toFixed(1);\n } else if (Math.abs(num) >= 10) {\n return num.toFixed(2);\n } else if (Math.abs(num) >= 1) {\n return num.toFixed(2);\n } else if (Math.abs(num) >= 0.1) {\n return num.toFixed(2);\n } else if (Math.abs(num) >= 0.01) {\n return num.toFixed(3);\n } else if (Math.abs(num) >= 0.001) {\n return num.toFixed(4);\n } else if (num === 0) {\n return \"0\";\n } else {\n return num.toFixed(5);\n }\n}\n\nexport function formatUsdValue(value: number): string {\n if (value === 0) return \"0.00\";\n if (value < 0.01 && value > 0) return \"<0.01\";\n return value.toFixed(2);\n}\n\nexport function formatScore(num: number): string {\n if (Math.abs(num) >= 1000000) {\n return parseFloat((num / 1000000).toFixed(2)) + \"m\";\n } else if (Math.abs(num) >= 1000) {\n return parseFloat((num / 1000).toFixed(2)) + \"k\";\n } else if (Math.abs(num) >= 10) {\n return num.toFixed(0);\n } else if (Math.abs(num) > 0) {\n return num.toFixed(0);\n } else {\n return \"0\";\n }\n}\n\nexport function formatTime(seconds: number): string {\n const minutes = Math.floor(seconds / 60);\n const hours = Math.floor(minutes / 60);\n const days = Math.floor(hours / 24);\n\n if (days > 0) {\n return `${days} Day${days > 1 ? \"s\" : \"\"}`;\n } else if (hours > 0) {\n return `${hours} Hour${hours > 1 ? \"s\" : \"\"}`;\n } else if (minutes > 0) {\n return `${minutes} Min${minutes > 1 ? \"s\" : \"\"}`;\n } else {\n return `${seconds.toFixed(0)} Sec${seconds > 1 ? \"s\" : \"\"}`;\n }\n}\n\nexport function getOrdinalSuffix(position: number): string {\n const formatPosition = isNaN(position) ? 0 : position;\n if (formatPosition % 10 === 1 && formatPosition !== 11) return \"st\";\n if (formatPosition % 10 === 2 && formatPosition !== 12) return \"nd\";\n if (position % 10 === 3 && position !== 13) return \"rd\";\n return \"th\";\n}\n\nexport type DistributionType = \"linear\" | \"exponential\" | \"uniform\";\n\nexport function calculatePayouts(\n totalPlaces: number,\n weightingFactor: number,\n): number[] {\n const weights: number[] = [];\n for (let i = 1; i <= totalPlaces; i++) {\n weights.push(1 / Math.pow(i, weightingFactor));\n }\n\n const totalWeight = weights.reduce((sum, weight) => sum + weight, 0);\n\n const payouts: number[] = weights.map((weight) =>\n Math.floor((weight / totalWeight) * 100),\n );\n\n const totalPayout = payouts.reduce((sum, payout) => sum + payout, 0);\n\n let remaining = 100 - totalPayout;\n let index = 0;\n while (remaining > 0) {\n payouts[index] += 1;\n remaining -= 1;\n index = (index + 1) % totalPlaces;\n }\n\n return payouts;\n}\n\nexport function calculateDistribution(\n positions: number,\n weight: number,\n creatorFee?: number,\n gameFee?: number,\n refundShare?: number,\n distributionType: DistributionType = \"exponential\",\n): number[] {\n if (positions <= 0) {\n return [];\n }\n\n const safeCreatorFee = creatorFee ?? 0;\n const safeGameFee = gameFee ?? 0;\n const safeRefundShare = refundShare ?? 0;\n const prizePoolPercentage =\n 100 - safeCreatorFee - safeGameFee - safeRefundShare;\n\n if (prizePoolPercentage <= 0) {\n return Array(positions).fill(0);\n }\n\n let rawDistributions: number[] = [];\n\n if (distributionType === \"uniform\") {\n rawDistributions = Array(positions).fill(1);\n } else if (distributionType === \"linear\") {\n for (let i = 0; i < positions; i++) {\n const positionValue = positions - i;\n const share = 1 + (positionValue - 1) * (weight / 10);\n rawDistributions.push(share);\n }\n } else {\n for (let i = 0; i < positions; i++) {\n const share = Math.pow(1 - i / positions, weight);\n rawDistributions.push(share);\n }\n }\n\n const total = rawDistributions.reduce((a, b) => a + b, 0);\n\n if (total === 0) {\n return Array(positions).fill(0);\n }\n\n const basisPointShares = rawDistributions.map((d) => {\n const ratio = d / total;\n const basisPoints = ratio * 10000;\n return Math.floor(basisPoints);\n });\n\n const totalBasisPoints = basisPointShares.reduce((a, b) => a + b, 0);\n const remainingBasisPoints = 10000 - totalBasisPoints;\n\n if (remainingBasisPoints !== 0 && positions > 0) {\n basisPointShares[0] = basisPointShares[0] + remainingBasisPoints;\n }\n\n return basisPointShares.map((bp) => bp / 100);\n}\n","import type { Prize } from \"../types/prize\";\n\nexport interface GroupedTokenPrize {\n type: \"erc20\" | \"erc721\";\n address: string;\n totalAmount: string;\n}\n\nexport function groupPrizesByToken(\n prizes: Prize[],\n): Record<string, GroupedTokenPrize> {\n return prizes.reduce(\n (acc, prize) => {\n const key = prize.tokenAddress;\n if (!acc[key]) {\n acc[key] = {\n type: prize.tokenType,\n address: prize.tokenAddress,\n totalAmount: \"0\",\n };\n }\n acc[key].totalAmount = String(\n BigInt(acc[key].totalAmount) + BigInt(prize.amount),\n );\n return acc;\n },\n {} as Record<string, GroupedTokenPrize>,\n );\n}\n\nexport function calculatePrizeValue(\n amount: string,\n decimals: number,\n price: number,\n): number {\n return (Number(amount) / 10 ** decimals) * price;\n}\n","import type { StatusTimestamps, StatusResult } from \"../types/status\";\n\nexport function computeStatus(\n timestamps: StatusTimestamps,\n now?: number,\n): StatusResult {\n const currentTimestamp = now ?? Math.floor(Date.now() / 1000);\n\n // Quest-specific: locked state\n if (timestamps.unlocked === false) {\n return {\n label: \"Locked\",\n variant: \"locked\",\n isActive: false,\n countdown: null,\n };\n }\n\n // Quest-specific: completed state\n if (timestamps.completed) {\n return {\n label: \"Completed\",\n variant: \"completed\",\n isActive: false,\n countdown: null,\n };\n }\n\n const { registrationStart, registrationEnd, start, end, submissionEnd } =\n timestamps;\n\n // Registration phase\n if (registrationStart && registrationEnd) {\n if (currentTimestamp < registrationStart) {\n return {\n label: \"Upcoming\",\n variant: \"upcoming\",\n isActive: false,\n countdown: {\n targetTimestamp: registrationStart,\n label: \"Registration\",\n },\n };\n }\n if (\n currentTimestamp >= registrationStart &&\n currentTimestamp < registrationEnd\n ) {\n return {\n label: \"Registration\",\n variant: \"registration\",\n isActive: true,\n countdown: { targetTimestamp: registrationEnd, label: \"Closes\" },\n };\n }\n }\n\n // Before start\n if (currentTimestamp < start) {\n return {\n label: \"Upcoming\",\n variant: \"upcoming\",\n isActive: false,\n countdown: { targetTimestamp: start, label: \"Starts\" },\n };\n }\n\n // Active / Live\n if (currentTimestamp >= start && currentTimestamp < end) {\n return {\n label: \"Live\",\n variant: \"active\",\n isActive: true,\n countdown: { targetTimestamp: end, label: \"Ends\" },\n };\n }\n\n // Submission phase\n if (submissionEnd && currentTimestamp >= end && currentTimestamp < submissionEnd) {\n return {\n label: \"Submission\",\n variant: \"submission\",\n isActive: true,\n countdown: { targetTimestamp: submissionEnd, label: \"Submit\" },\n };\n }\n\n // Ended\n return {\n label: \"Ended\",\n variant: \"ended\",\n isActive: false,\n countdown: null,\n };\n}\n","export function isBefore(date1: Date, date2: Date): boolean {\n return date1.getTime() < date2.getTime();\n}\n","/**\n * Entry fee breakdown calculation.\n *\n * Takes a total fee pool and share percentages (in basis points, where 10000 = 100%)\n * and returns the amount allocated to each bucket.\n *\n * This is the same math that on-chain metagame contracts use to split entry fees\n * between creator, game creator, refund pool, and prize pool.\n */\n\nexport interface EntryFeeBreakdown {\n /** Total fee collected from all entrants */\n totalCollected: bigint;\n /** Amount going to the metagame creator */\n creatorAmount: bigint;\n /** Amount going to the game creator */\n gameCreatorAmount: bigint;\n /** Amount reserved for refunds */\n refundAmount: bigint;\n /** Amount available for prize distribution */\n prizePoolAmount: bigint;\n}\n\nexport interface EntryFeeShares {\n /** Creator share in basis points (0-10000) */\n creatorShare: number;\n /** Game creator share in basis points (0-10000) */\n gameCreatorShare: number;\n /** Refund share in basis points (0-10000) */\n refundShare: number;\n}\n\n/**\n * Calculate how an entry fee pool is split between creator, game, refund, and prizes.\n *\n * @param feePerEntry - Fee amount per entry (in token units, as bigint)\n * @param entryCount - Number of entries\n * @param shares - Share percentages in basis points (10000 = 100%)\n * @returns Breakdown of amounts for each bucket\n */\nexport function calculateEntryFeeBreakdown(\n feePerEntry: bigint,\n entryCount: number,\n shares: EntryFeeShares,\n): EntryFeeBreakdown {\n const totalCollected = feePerEntry * BigInt(entryCount);\n\n if (totalCollected === 0n) {\n return {\n totalCollected: 0n,\n creatorAmount: 0n,\n gameCreatorAmount: 0n,\n refundAmount: 0n,\n prizePoolAmount: 0n,\n };\n }\n\n const creatorAmount =\n shares.creatorShare > 0\n ? (totalCollected * BigInt(shares.creatorShare)) / 10000n\n : 0n;\n\n const gameCreatorAmount =\n shares.gameCreatorShare > 0\n ? (totalCollected * BigInt(shares.gameCreatorShare)) / 10000n\n : 0n;\n\n const refundAmount =\n shares.refundShare > 0\n ? (totalCollected * BigInt(shares.refundShare)) / 10000n\n : 0n;\n\n const prizePoolBps =\n 10000 - shares.creatorShare - shares.gameCreatorShare - shares.refundShare;\n const prizePoolAmount =\n prizePoolBps > 0 ? (totalCollected * BigInt(prizePoolBps)) / 10000n : 0n;\n\n return {\n totalCollected,\n creatorAmount,\n gameCreatorAmount,\n refundAmount,\n prizePoolAmount,\n };\n}\n\n/**\n * Distribute a prize pool across positions using a distribution curve.\n *\n * Takes the prize pool amount and distribution percentages (from calculateDistribution),\n * and returns the actual token amount per position.\n *\n * @param prizePoolAmount - Total pool to distribute (bigint, in smallest token units)\n * @param percentages - Distribution percentages per position (from calculateDistribution)\n * @returns Array of { position, amount } where position is 1-indexed\n */\nexport function distributePool(\n prizePoolAmount: bigint,\n percentages: number[],\n): Array<{ position: number; amount: bigint }> {\n return percentages\n .map((pct, index) => ({\n position: index + 1,\n amount:\n (prizePoolAmount * BigInt(Math.floor(pct * 100))) / 10000n,\n }))\n .filter((entry) => entry.amount > 0n);\n}\n","import type { Prize } from \"../types/prize\";\n\n/**\n * Prize aggregation by position.\n *\n * Groups prizes by position, summing ERC20 amounts and collecting ERC721 IDs.\n * Works with Prize — metagame apps adapt their raw prize data to this\n * shape before calling these functions.\n */\n\nexport interface PositionPrizeGroup {\n position: number;\n erc20: Array<{ tokenAddress: string; totalAmount: bigint }>;\n erc721: Array<{ tokenAddress: string; tokenIds: string[] }>;\n}\n\n/**\n * Group prizes by leaderboard position, aggregating ERC20 amounts and\n * collecting ERC721 token IDs per position.\n */\nexport function aggregatePrizesByPosition(\n prizes: Prize[],\n): PositionPrizeGroup[] {\n const positionMap = new Map<number, {\n erc20Map: Map<string, bigint>;\n erc721Map: Map<string, string[]>;\n }>();\n\n for (const prize of prizes) {\n if (!positionMap.has(prize.position)) {\n positionMap.set(prize.position, {\n erc20Map: new Map(),\n erc721Map: new Map(),\n });\n }\n const group = positionMap.get(prize.position)!;\n\n if (prize.tokenType === \"erc20\") {\n const current = group.erc20Map.get(prize.tokenAddress) ?? 0n;\n group.erc20Map.set(prize.tokenAddress, current + BigInt(prize.amount));\n } else {\n const ids = group.erc721Map.get(prize.tokenAddress) ?? [];\n ids.push(prize.id);\n group.erc721Map.set(prize.tokenAddress, ids);\n }\n }\n\n return Array.from(positionMap.entries())\n .sort(([a], [b]) => a - b)\n .map(([position, { erc20Map, erc721Map }]) => ({\n position,\n erc20: Array.from(erc20Map.entries()).map(([tokenAddress, totalAmount]) => ({\n tokenAddress,\n totalAmount,\n })),\n erc721: Array.from(erc721Map.entries()).map(([tokenAddress, tokenIds]) => ({\n tokenAddress,\n tokenIds,\n })),\n }));\n}\n\n/**\n * Sponsor contribution aggregated from prizes.\n */\nexport interface SponsorContribution {\n sponsorAddress: string;\n tokens: Array<{\n tokenAddress: string;\n totalAmount: bigint;\n prizeCount: number;\n }>;\n /** NFT collections grouped by token address, with individual token IDs */\n nftCollections: Array<{\n tokenAddress: string;\n tokenIds: string[];\n }>;\n nftCount: number;\n totalPrizeCount: number;\n}\n\n/**\n * Group prizes by sponsor address, aggregating ERC20 contributions and\n * grouping NFTs by collection. Filters out prizes with no sponsor\n * (address \"0x0\" or empty).\n *\n * For ERC721 prizes, `prize.amount` is expected to hold the token ID\n * (this is the convention set by the prize adapter).\n *\n * @param prizes - Array of Prize with sponsorAddress populated\n * @returns Sponsor contributions sorted by total prize count (descending)\n */\nexport function aggregatePrizesBySponsor(\n prizes: Prize[],\n): SponsorContribution[] {\n const sponsorMap = new Map<string, {\n erc20Map: Map<string, { amount: bigint; count: number }>;\n nftMap: Map<string, string[]>;\n nftCount: number;\n totalCount: number;\n }>();\n\n for (const prize of prizes) {\n if (!prize.sponsorAddress || prize.sponsorAddress === \"0x0\") continue;\n\n if (!sponsorMap.has(prize.sponsorAddress)) {\n sponsorMap.set(prize.sponsorAddress, {\n erc20Map: new Map(),\n nftMap: new Map(),\n nftCount: 0,\n totalCount: 0,\n });\n }\n const sponsor = sponsorMap.get(prize.sponsorAddress)!;\n sponsor.totalCount++;\n\n if (prize.tokenType === \"erc20\") {\n const current = sponsor.erc20Map.get(prize.tokenAddress) ?? {\n amount: 0n,\n count: 0,\n };\n sponsor.erc20Map.set(prize.tokenAddress, {\n amount: current.amount + BigInt(prize.amount),\n count: current.count + 1,\n });\n } else {\n sponsor.nftCount++;\n const ids = sponsor.nftMap.get(prize.tokenAddress) ?? [];\n ids.push(prize.amount); // For ERC721, amount holds the token ID\n sponsor.nftMap.set(prize.tokenAddress, ids);\n }\n }\n\n return Array.from(sponsorMap.entries())\n .map(([sponsorAddress, { erc20Map, nftMap, nftCount, totalCount }]) => ({\n sponsorAddress,\n tokens: Array.from(erc20Map.entries()).map(\n ([tokenAddress, { amount, count }]) => ({\n tokenAddress,\n totalAmount: amount,\n prizeCount: count,\n }),\n ),\n nftCollections: Array.from(nftMap.entries()).map(\n ([tokenAddress, tokenIds]) => ({\n tokenAddress,\n tokenIds,\n }),\n ),\n nftCount,\n totalPrizeCount: totalCount,\n }))\n .sort((a, b) => b.totalPrizeCount - a.totalPrizeCount);\n}\n\n/**\n * Filter prizes to only those not yet claimed.\n *\n * @param prizes - All prizes the user could potentially claim\n * @param claimedIds - Set of prize IDs already claimed\n * @returns Prizes not yet claimed\n */\nexport function filterClaimablePrizes(\n prizes: Prize[],\n claimedIds: Set<string>,\n): Prize[] {\n return prizes.filter((prize) => !claimedIds.has(prize.id));\n}\n\n/**\n * Filter out ERC20 prizes with zero amount.\n */\nexport function filterZeroPrizes(prizes: Prize[]): Prize[] {\n return prizes.filter((prize) => {\n if (prize.tokenType === \"erc20\") {\n return BigInt(prize.amount) > 0n;\n }\n return true; // Keep all NFTs\n });\n}\n","/**\n * NFT bulk input parsing for prize creation forms.\n *\n * Metagame UIs often need a textarea where users can paste multiple NFT\n * token IDs with positions. This parser handles two common formats:\n *\n * 1. JSON array: [{ \"tokenId\": 1, \"position\": 1 }, ...]\n * 2. Key-value: \"tokenId:position\" per line or comma-separated\n */\n\nexport interface NftPrizeInput {\n tokenId: string;\n position: number;\n}\n\nexport interface NftParseResult {\n entries: NftPrizeInput[];\n errors: string[];\n}\n\n/**\n * Parse bulk NFT input text into structured entries.\n *\n * Supports:\n * - JSON array: `[{\"tokenId\": 1, \"position\": 1}]`\n * - Key-value lines: `123:1` (tokenId:position)\n * - Comma-separated: `123:1, 456:2, 789:3`\n *\n * @param input - Raw text from a textarea\n * @returns Parsed entries and any validation errors\n */\nexport function parseNFTBulkInput(input: string): NftParseResult {\n const trimmed = input.trim();\n if (!trimmed) return { entries: [], errors: [] };\n\n // Try JSON first\n if (trimmed.startsWith(\"[\")) {\n return parseJsonFormat(trimmed);\n }\n\n // Fall back to key-value format\n return parseKeyValueFormat(trimmed);\n}\n\nfunction parseJsonFormat(input: string): NftParseResult {\n const errors: string[] = [];\n try {\n const parsed = JSON.parse(input);\n if (!Array.isArray(parsed)) {\n return { entries: [], errors: [\"Expected a JSON array\"] };\n }\n\n const entries: NftPrizeInput[] = [];\n for (let i = 0; i < parsed.length; i++) {\n const item = parsed[i];\n const tokenId = item.tokenId ?? item.token_id ?? item.id;\n const position = item.position ?? item.pos;\n\n if (tokenId == null || position == null) {\n errors.push(\n `Item ${i + 1}: missing tokenId or position`,\n );\n continue;\n }\n\n const posNum = Number(position);\n if (!Number.isFinite(posNum) || posNum < 1) {\n errors.push(`Item ${i + 1}: position must be >= 1`);\n continue;\n }\n\n entries.push({ tokenId: String(tokenId), position: posNum });\n }\n\n return { entries, errors };\n } catch {\n return { entries: [], errors: [\"Invalid JSON format\"] };\n }\n}\n\nfunction parseKeyValueFormat(input: string): NftParseResult {\n const errors: string[] = [];\n const entries: NftPrizeInput[] = [];\n\n // Split by newlines, then by commas\n const lines = input\n .split(/[\\n,]/)\n .map((s) => s.trim())\n .filter((s) => s.length > 0);\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n const parts = line.split(\":\").map((s) => s.trim());\n\n if (parts.length !== 2) {\n errors.push(`Line ${i + 1}: expected \"tokenId:position\" format`);\n continue;\n }\n\n const [tokenIdStr, posStr] = parts;\n const position = Number(posStr);\n\n if (!tokenIdStr) {\n errors.push(`Line ${i + 1}: missing tokenId`);\n continue;\n }\n if (!Number.isFinite(position) || position < 1) {\n errors.push(`Line ${i + 1}: position must be >= 1`);\n continue;\n }\n\n entries.push({ tokenId: tokenIdStr, position });\n }\n\n return { entries, errors };\n}\n","/**\n * Extension utilities for EGS entry requirements.\n *\n * The EGS ecosystem has shared extension contracts that any metagame can use\n * for gating entry. These utilities handle:\n * - Identifying which extension type an address corresponds to\n * - Parsing the on-chain config arrays into structured objects\n * - Providing deployed addresses per chain\n *\n * The extension contracts are deployed once and shared across metagames.\n * The config format is defined by each extension's Cairo contract — these\n * parsers match that format exactly.\n */\n\nimport type {\n ExtensionType,\n ExtensionAddresses,\n TournamentValidatorConfig,\n ERC20BalanceValidatorConfig,\n OpusTrovesValidatorConfig,\n SnapshotValidatorConfig,\n ZkPassportValidatorConfig,\n GovernanceValidatorConfig,\n MerkleValidatorConfig,\n QualifyingMode,\n QualifyingModeInfo,\n} from \"../types/extensions\";\n\n// ---------------------------------------------------------------------------\n// Deployed extension addresses\n// ---------------------------------------------------------------------------\n\nconst EXTENSION_ADDRESSES: Record<string, ExtensionAddresses> = {\n SN_SEPOLIA: {\n tournamentValidator:\n \"0x07eade45e4317b1a036e3a8123bb1f95215d37a6f6b0cea25cdd48030a932dfc\",\n erc20BalanceValidator:\n \"0x028112199f873e919963277b41ef1231365986e2fd7722501cd7d293de60b64e\",\n opusTrovesValidator:\n \"0x0317f96eeff41d1badffd9bda126d36c1806523d8c91a5b440f9bdf2aa2b9fe7\",\n snapshotValidator:\n \"0x05520239f16dc58c5dfdccb1f0480977e7fea18d4305e64f5eae88ae786a22fe\",\n zkPassportValidator:\n \"0x025b65137c5297e03491830635f4c5d76eb17e5b2db3bf49dbee34bba94ad3e6\",\n governanceValidator:\n \"0x0585e6b1aa8daac7711004a92a8d0d3b5a81eaac8c9a07db24fc34b1a4f2322c\",\n merkleValidator:\n \"0x07a5b716c65ac5726ecd0b023ff1b4cc9090820707a508b49f5ed42e44a401c4\",\n },\n SN_MAIN: {\n tournamentValidator:\n \"0x0771b57c0709fc4407ff8b63d573f302b96fb03638364032fad734e3c310b9e0\",\n erc20BalanceValidator:\n \"0x051fc2681f65ee18e99dab3cc2ca2eca1b4532c735e752f575ace91ed30f17b7\",\n opusTrovesValidator:\n \"0x0604bc0d54727f439786c65d7dc6f7d46de1aba7e129ef9caf65fef111a1644e\",\n snapshotValidator:\n \"0x03e6820e9e1cfb5c22465a86f469c651355f05397e29fc94de8e832d5f3d8ede\",\n zkPassportValidator:\n \"0x01a25f04c8a39da7bb37adcc53d595fde9e60702611d15b1c498df0657001479\",\n governanceValidator: \"\", // placeholder until deployed\n merkleValidator: \"\", // placeholder until deployed\n },\n};\n\n// ---------------------------------------------------------------------------\n// Opus supported collateral assets\n// ---------------------------------------------------------------------------\n\nconst OPUS_SUPPORTED_ASSETS: Record<string, string[]> = {\n SN_SEPOLIA: [],\n SN_MAIN: [\n \"0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7\", // ETH\n \"0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d\", // STRK\n \"0x0124aeb495b947201f5fac96fd1138e326ad86195b98df6dec9009158a533b49\", // LORDS\n \"0x075afe6402ad5a5c20dd25e10ec3b3986acaa647b77e4ae24b0cbc9a54a27a87\", // EKUBO\n \"0x03fe2b97c1fd336e750087d68b9b867997fd64a2661ff3ca5a7c771641e8e7ac\", // WBTC\n ],\n};\n\n/**\n * Get deployed extension addresses for a chain.\n */\nexport function getExtensionAddresses(chainId: string): ExtensionAddresses {\n return EXTENSION_ADDRESSES[chainId] ?? {};\n}\n\n/**\n * Get supported Opus collateral asset addresses for a chain.\n */\nexport function getOpusSupportedAssets(chainId: string): string[] {\n return OPUS_SUPPORTED_ASSETS[chainId] ?? [];\n}\n\n/**\n * Get all whitelisted extension addresses for a chain (normalized).\n */\nexport function getWhitelistedExtensionAddresses(\n chainId: string,\n): Set<string> {\n const addresses = EXTENSION_ADDRESSES[chainId] ?? {};\n const set = new Set<string>();\n for (const addr of Object.values(addresses)) {\n if (addr) {\n set.add(normalizeAddr(addr));\n }\n }\n return set;\n}\n\n/**\n * Check if an extension address is whitelisted for a chain.\n */\nexport function isWhitelistedExtension(\n extensionAddress: string,\n chainId: string,\n): boolean {\n const whitelist = getWhitelistedExtensionAddresses(chainId);\n return whitelist.has(normalizeAddr(extensionAddress));\n}\n\n// ---------------------------------------------------------------------------\n// Extension type identification\n// ---------------------------------------------------------------------------\n\n/**\n * Normalize a Starknet address for comparison (lowercase, strip leading zeros).\n */\nfunction normalizeAddr(address: string): string {\n if (!address) return \"\";\n const hex = address.toLowerCase().replace(/^0x0*/, \"\");\n return hex;\n}\n\n/**\n * Identify which extension type a contract address corresponds to.\n *\n * @param extensionAddress - The extension contract address from the entry requirement\n * @param chainId - The chain ID (e.g., \"SN_MAIN\", \"SN_SEPOLIA\")\n * @returns The extension type, or \"unknown\" if not a recognized preset\n */\nexport function identifyExtensionType(\n extensionAddress: string,\n chainId: string,\n): ExtensionType {\n const addresses = getExtensionAddresses(chainId);\n const normalized = normalizeAddr(extensionAddress);\n\n if (\n addresses.tournamentValidator &&\n normalizeAddr(addresses.tournamentValidator) === normalized\n ) {\n return \"tournament\";\n }\n if (\n addresses.erc20BalanceValidator &&\n normalizeAddr(addresses.erc20BalanceValidator) === normalized\n ) {\n return \"erc20Balance\";\n }\n if (\n addresses.opusTrovesValidator &&\n normalizeAddr(addresses.opusTrovesValidator) === normalized\n ) {\n return \"opusTroves\";\n }\n if (\n addresses.snapshotValidator &&\n normalizeAddr(addresses.snapshotValidator) === normalized\n ) {\n return \"snapshot\";\n }\n if (\n addresses.zkPassportValidator &&\n normalizeAddr(addresses.zkPassportValidator) === normalized\n ) {\n return \"zkPassport\";\n }\n if (\n addresses.governanceValidator &&\n normalizeAddr(addresses.governanceValidator) === normalized\n ) {\n return \"governance\";\n }\n if (\n addresses.merkleValidator &&\n normalizeAddr(addresses.merkleValidator) === normalized\n ) {\n return \"merkle\";\n }\n\n return \"unknown\";\n}\n\n// ---------------------------------------------------------------------------\n// Config parsers\n// ---------------------------------------------------------------------------\n\n/**\n * Parse a tournament validator extension config array.\n *\n * Config format: [qualifier_type, qualifying_mode, top_positions, ...tournament_ids]\n * - qualifier_type: \"0\" = participated, \"1\" = won\n * - qualifying_mode: 0-5 (see QualifyingMode enum)\n * - top_positions: 0 = all positions, or N = top N\n * - remaining values: tournament IDs\n */\nexport function parseTournamentValidatorConfig(\n config: Array<string | number | bigint>,\n): TournamentValidatorConfig | null {\n if (!config || config.length < 3) return null;\n\n return {\n requirementType: String(config[0]) === \"1\" ? \"won\" : \"participated\",\n qualifyingMode: Number(config[1]) as QualifyingMode,\n topPositions: Number(config[2]),\n tournamentIds: config.slice(3).map((id) => String(BigInt(id))),\n };\n}\n\n/**\n * Parse an ERC20 balance validator extension config array.\n *\n * Config format: [token_address, min_low, min_high, max_low, max_high, vpe_low, vpe_high, max_entries]\n * Values are u256 split into low (128-bit) and high (128-bit) parts.\n */\nexport function parseERC20BalanceValidatorConfig(\n config: Array<string | number | bigint>,\n): ERC20BalanceValidatorConfig | null {\n if (!config || config.length < 8) return null;\n\n const tokenAddress = String(config[0]);\n const minThreshold = (BigInt(config[2]) << 128n) | BigInt(config[1]);\n const maxThreshold = (BigInt(config[4]) << 128n) | BigInt(config[3]);\n const valuePerEntry = (BigInt(config[6]) << 128n) | BigInt(config[5]);\n const maxEntries = Number(config[7]);\n\n return {\n tokenAddress,\n minThreshold,\n maxThreshold,\n valuePerEntry,\n maxEntries,\n };\n}\n\n/**\n * Parse an Opus Troves validator extension config array.\n *\n * Config format: [asset_count, ...asset_addresses, threshold, value_per_entry, max_entries]\n * - asset_count: 0 = wildcard (any collateral), N = specific assets\n * - asset_addresses: N addresses following asset_count\n * - threshold: minimum debt in CASH (18 decimals, 1:1 USD)\n * - value_per_entry: debt per additional entry\n * - max_entries: cap on entries (0 = unlimited)\n */\nexport function parseOpusTrovesValidatorConfig(\n config: Array<string | number | bigint>,\n): OpusTrovesValidatorConfig | null {\n if (!config || config.length < 4) return null;\n\n const assetCount = Number(config[0]);\n const assetAddresses = config.slice(1, assetCount + 1).map(String);\n const threshold = BigInt(config[assetCount + 1] ?? \"0\");\n const valuePerEntry = BigInt(config[assetCount + 2] ?? \"0\");\n const maxEntries = Number(config[assetCount + 3] ?? \"0\");\n\n return {\n assetCount,\n assetAddresses,\n threshold,\n valuePerEntry,\n maxEntries,\n };\n}\n\n/**\n * Parse a Snapshot validator extension config array.\n *\n * Config format: [snapshot_space_id]\n */\nexport function parseSnapshotValidatorConfig(\n config: Array<string | number | bigint>,\n): SnapshotValidatorConfig | null {\n if (!config || config.length === 0) return null;\n\n return {\n snapshotId: String(Number(BigInt(config[0] ?? \"0\"))),\n };\n}\n\n/**\n * Parse a ZK Passport validator extension config array.\n *\n * Config format: [verifier_address, service_scope, subscope, param_commitment, max_proof_age, nullifier_type]\n */\nexport function parseZkPassportValidatorConfig(\n config: Array<string | number | bigint>,\n): ZkPassportValidatorConfig | null {\n if (!config || config.length < 6) return null;\n\n return {\n verifierAddress: String(config[0]),\n serviceScope: BigInt(config[1]),\n subscope: BigInt(config[2]),\n paramCommitment: BigInt(config[3]),\n maxProofAge: Number(config[4]),\n nullifierType: Number(config[5]),\n };\n}\n\n/**\n * Parse a Governance validator extension config array.\n *\n * Config format: [governor_address, governance_token_address, balance_threshold_low, balance_threshold_high,\n * proposal_id_low, proposal_id_high, check_voted, votes_threshold_low, votes_threshold_high,\n * votes_per_entry_low, votes_per_entry_high]\n */\nexport function parseGovernanceValidatorConfig(\n config: Array<string | number | bigint>,\n): GovernanceValidatorConfig | null {\n if (!config || config.length < 11) return null;\n\n return {\n governorAddress: String(config[0]),\n governanceTokenAddress: String(config[1]),\n balanceThreshold: (BigInt(config[3]) << 128n) | BigInt(config[2]),\n proposalId: (BigInt(config[5]) << 128n) | BigInt(config[4]),\n checkVoted: String(config[6]) === \"1\" || BigInt(config[6]) === 1n,\n votesThreshold: (BigInt(config[8]) << 128n) | BigInt(config[7]),\n votesPerEntry: (BigInt(config[10]) << 128n) | BigInt(config[9]),\n };\n}\n\n/**\n * Parse a Merkle validator extension config array.\n *\n * Config format: [tree_id]\n */\nexport function parseMerkleValidatorConfig(\n config: Array<string | number | bigint>,\n): MerkleValidatorConfig | null {\n if (!config || config.length === 0) return null;\n\n return {\n treeId: String(Number(BigInt(config[0] ?? \"0\"))),\n };\n}\n\n/**\n * Parse any extension config by first identifying its type.\n *\n * Returns the parsed config along with the identified type. Useful when\n * you have a raw extension config and need to determine both what it is\n * and what its parameters are in one call.\n */\nexport function parseExtensionConfig(\n extensionAddress: string,\n config: Array<string | number | bigint>,\n chainId: string,\n):\n | { type: \"tournament\"; config: TournamentValidatorConfig }\n | { type: \"erc20Balance\"; config: ERC20BalanceValidatorConfig }\n | { type: \"opusTroves\"; config: OpusTrovesValidatorConfig }\n | { type: \"snapshot\"; config: SnapshotValidatorConfig }\n | { type: \"zkPassport\"; config: ZkPassportValidatorConfig }\n | { type: \"governance\"; config: GovernanceValidatorConfig }\n | { type: \"merkle\"; config: MerkleValidatorConfig }\n | { type: \"unknown\"; config: null }\n | null {\n const extensionType = identifyExtensionType(extensionAddress, chainId);\n\n switch (extensionType) {\n case \"tournament\": {\n const parsed = parseTournamentValidatorConfig(config);\n return parsed ? { type: \"tournament\", config: parsed } : null;\n }\n case \"erc20Balance\": {\n const parsed = parseERC20BalanceValidatorConfig(config);\n return parsed ? { type: \"erc20Balance\", config: parsed } : null;\n }\n case \"opusTroves\": {\n const parsed = parseOpusTrovesValidatorConfig(config);\n return parsed ? { type: \"opusTroves\", config: parsed } : null;\n }\n case \"snapshot\": {\n const parsed = parseSnapshotValidatorConfig(config);\n return parsed ? { type: \"snapshot\", config: parsed } : null;\n }\n case \"zkPassport\": {\n const parsed = parseZkPassportValidatorConfig(config);\n return parsed ? { type: \"zkPassport\", config: parsed } : null;\n }\n case \"governance\": {\n const parsed = parseGovernanceValidatorConfig(config);\n return parsed ? { type: \"governance\", config: parsed } : null;\n }\n case \"merkle\": {\n const parsed = parseMerkleValidatorConfig(config);\n return parsed ? { type: \"merkle\", config: parsed } : null;\n }\n default:\n return { type: \"unknown\", config: null };\n }\n}\n\n// ---------------------------------------------------------------------------\n// Qualifying mode helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Get a human-readable label and description for a qualifying mode.\n */\nexport function getQualifyingModeInfo(mode: number): QualifyingModeInfo {\n switch (mode) {\n case 0:\n return {\n label: \"At Least One\",\n description: \"Qualify in at least one tournament\",\n };\n case 1:\n return {\n label: \"Cumulative per Tournament\",\n description: \"Track entry limits separately for each tournament\",\n };\n case 2:\n return {\n label: \"All\",\n description: \"Must qualify in all tournaments\",\n };\n case 3:\n return {\n label: \"Cumulative per Entry\",\n description: \"Track entries per qualifying token ID\",\n };\n case 4:\n return {\n label: \"All Participate, Any Win\",\n description:\n \"Must participate in all tournaments, but only need to win in any one\",\n };\n case 5:\n return {\n label: \"All With Cumulative\",\n description:\n \"Must participate in all tournaments, entries multiply by tournament count\",\n };\n default:\n return { label: \"Unknown\", description: \"\" };\n }\n}\n\n// ---------------------------------------------------------------------------\n// Formatting helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Format a raw token amount (bigint) to a human-readable string with decimals.\n * Removes trailing zeros from the decimal part.\n */\nexport function formatTokenAmount(\n value: bigint,\n decimals: number,\n): string {\n if (value === 0n) return \"0\";\n\n const divisor = 10n ** BigInt(decimals);\n const integerPart = value / divisor;\n const remainder = value % divisor;\n\n if (remainder === 0n) return integerPart.toString();\n\n const decimalStr = remainder.toString().padStart(decimals, \"0\");\n const trimmed = decimalStr.replace(/0+$/, \"\");\n return trimmed ? `${integerPart}.${trimmed}` : integerPart.toString();\n}\n\n/**\n * Format a CASH value (18 decimals, 1:1 USD) to a USD string.\n */\nexport function formatCashToUSD(value: bigint): string {\n return formatTokenAmount(value, 18);\n}\n","/**\n * Entry qualification evaluation.\n *\n * Pure functions that determine whether a user qualifies to enter a metagame\n * event based on pre-fetched data. Each metagame fetches the data through\n * their own SDK, then passes it here for evaluation.\n *\n * The evaluation logic is the same across metagames because the entry\n * requirement system (token gating, extensions) is shared.\n */\n\nimport type {\n EntryRequirementVariant,\n QualificationResult,\n QualificationEntry,\n} from \"../types/extensions\";\n\n// ---------------------------------------------------------------------------\n// Token-based qualification (NFT ownership)\n// ---------------------------------------------------------------------------\n\nexport interface TokenQualificationInput {\n /** NFT token IDs owned by the player */\n ownedTokenIds: string[];\n /** Number of times each token has been used to enter (tokenId → count) */\n usedEntryCounts: Record<string, number>;\n /** Max entries per token (0 = unlimited) */\n entryLimit: number;\n}\n\n/**\n * Evaluate token-based entry qualification.\n *\n * Checks if the player owns any qualifying NFTs and how many entries\n * remain for each. Selects the token with the most entries remaining\n * as the best proof.\n */\nexport function evaluateTokenQualification(\n input: TokenQualificationInput,\n): QualificationResult {\n if (input.ownedTokenIds.length === 0) {\n return {\n meetsRequirements: false,\n bestProof: null,\n qualifications: [],\n totalEntriesLeft: 0,\n };\n }\n\n const qualifications: QualificationEntry[] = [];\n\n for (const tokenId of input.ownedTokenIds) {\n const usedCount = input.usedEntryCounts[tokenId] ?? 0;\n const remaining =\n input.entryLimit > 0 ? input.entryLimit - usedCount : Infinity;\n\n if (remaining > 0) {\n qualifications.push({\n id: `token-${tokenId}`,\n entriesLeft: remaining,\n proof: { type: \"token\", tokenId },\n label: `Token #${tokenId}`,\n metadata: { tokenId },\n });\n }\n }\n\n const totalEntriesLeft = qualifications.reduce(\n (sum, q) => sum + (q.entriesLeft === Infinity ? 1 : q.entriesLeft),\n 0,\n );\n\n const best =\n qualifications.length > 0\n ? qualifications.reduce((a, b) =>\n b.entriesLeft > a.entriesLeft ? b : a,\n )\n : null;\n\n return {\n meetsRequirements: qualifications.length > 0,\n bestProof: best?.proof ?? null,\n qualifications,\n totalEntriesLeft,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Extension-based qualification\n// ---------------------------------------------------------------------------\n\nexport interface ExtensionQualificationInput {\n /** Results from checking each qualification method against the extension contract */\n checkedQualifications: Array<{\n id: string;\n entriesLeft: number;\n proof: string[];\n label?: string;\n metadata?: Record<string, unknown>;\n }>;\n}\n\n/**\n * Evaluate extension-based entry qualification from pre-checked results.\n *\n * Each metagame calls the extension contract's `entries_left` function\n * for each potential qualification proof, then passes the results here.\n * This function aggregates and selects the best qualification.\n */\nexport function evaluateExtensionQualification(\n input: ExtensionQualificationInput,\n): QualificationResult {\n const qualifications: QualificationEntry[] = input.checkedQualifications\n .filter((q) => q.entriesLeft > 0)\n .map((q) => ({\n id: q.id,\n entriesLeft: q.entriesLeft,\n proof: {\n type: \"extension\" as const,\n extensionProof: q.proof,\n },\n label: q.label,\n metadata: q.metadata,\n }));\n\n const totalEntriesLeft = qualifications.reduce(\n (sum, q) => sum + q.entriesLeft,\n 0,\n );\n\n const best =\n qualifications.length > 0\n ? qualifications.reduce((a, b) =>\n b.entriesLeft > a.entriesLeft ? b : a,\n )\n : null;\n\n return {\n meetsRequirements: qualifications.length > 0,\n bestProof: best?.proof ?? null,\n qualifications,\n totalEntriesLeft,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Combined qualification\n// ---------------------------------------------------------------------------\n\n/**\n * Evaluate entry qualification based on requirement variant.\n *\n * This is the top-level function — pass in the requirement type and\n * the appropriate input, get back a unified QualificationResult.\n */\nexport function evaluateQualification(\n variant: EntryRequirementVariant,\n input:\n | { type: \"token\"; data: TokenQualificationInput }\n | { type: \"extension\"; data: ExtensionQualificationInput }\n | { type: \"none\" },\n): QualificationResult {\n if (variant === \"none\" || input.type === \"none\") {\n return {\n meetsRequirements: true,\n bestProof: null,\n qualifications: [\n {\n id: \"no-requirement\",\n entriesLeft: Infinity,\n proof: { type: \"none\" },\n },\n ],\n totalEntriesLeft: Infinity,\n };\n }\n\n switch (input.type) {\n case \"token\":\n return evaluateTokenQualification(input.data);\n case \"extension\":\n return evaluateExtensionQualification(input.data);\n default:\n return {\n meetsRequirements: false,\n bestProof: null,\n qualifications: [],\n totalEntriesLeft: 0,\n };\n }\n}\n","/**\n * Qualification proof construction for EGS entry requirements.\n *\n * Builds the on-chain proof calldata that metagames pass when entering\n * an event. The proof format matches the Cairo `QualificationProof` enum:\n *\n * enum QualificationProof {\n * NFT: NFTQualification, // { token_id: u256 }\n * Extension: Span<felt252>,\n * }\n *\n * Extension-specific data (tournament IDs, positions, addresses, etc.)\n * is encoded into the `Extension` variant's felt252 array by the\n * extension's own logic.\n */\n\nimport { CairoCustomEnum, CairoOption, CairoOptionVariant } from \"starknet\";\nimport type { QualificationProof } from \"../types/extensions\";\n\n/**\n * Build the on-chain qualification proof from a QualificationProof object.\n *\n * Returns a `CairoOption<CairoCustomEnum>` ready to pass to a metagame\n * contract's entry function. Returns `None` if no proof is needed.\n *\n * @param proof - The qualification proof from evaluateQualification()\n * @returns CairoOption wrapping the proof enum, ready for contract call\n */\nexport function buildQualificationProof(\n proof: QualificationProof | null,\n): CairoOption<CairoCustomEnum> {\n if (!proof) {\n return new CairoOption(CairoOptionVariant.None);\n }\n\n switch (proof.type) {\n case \"token\":\n return buildNFTProof(proof.tokenId ?? \"0\");\n\n case \"extension\":\n return buildExtensionProof(proof.extensionProof ?? []);\n\n case \"none\":\n return new CairoOption(CairoOptionVariant.None);\n\n default:\n return new CairoOption(CairoOptionVariant.None);\n }\n}\n\n/**\n * Build an NFT ownership proof.\n * Used when entry requires holding a specific NFT collection.\n */\nexport function buildNFTProof(\n tokenId: string,\n): CairoOption<CairoCustomEnum> {\n return new CairoOption(\n CairoOptionVariant.Some,\n new CairoCustomEnum({\n NFT: {\n token_id: {\n low: tokenId,\n high: \"0\",\n },\n },\n Extension: undefined,\n }),\n );\n}\n\n/**\n * Build a tournament validator extension proof.\n * Used when entry requires participation/winning in a prior tournament.\n *\n * The proof array is: [tournament_id, token_id, position]\n */\nexport function buildTournamentExtensionProof(\n tournamentId: string,\n tokenId: string,\n position: number,\n): CairoOption<CairoCustomEnum> {\n return buildExtensionProof([\n tournamentId.toString(),\n tokenId.toString(),\n position.toString(),\n ]);\n}\n\n/**\n * Build a generic extension proof.\n * Used for any extension validator (ERC20 balance, Opus Troves, Snapshot, etc.).\n *\n * @param proofData - Array of felt252 values to pass to the extension contract\n */\nexport function buildExtensionProof(\n proofData: string[],\n): CairoOption<CairoCustomEnum> {\n return new CairoOption(\n CairoOptionVariant.Some,\n new CairoCustomEnum({\n NFT: undefined,\n Extension: proofData,\n }),\n );\n}\n","/**\n * Tournament validator qualification resolution.\n *\n * The tournament validator extension requires players to have participated\n * in (or won) specific prior tournaments. This module resolves which of\n * a player's game tokens can serve as proof of qualification.\n *\n * Every metagame that uses the tournament validator extension needs this\n * same logic — cross-referencing the player's registrations and leaderboard\n * positions against the validator's required tournaments.\n */\n\nimport type { TournamentValidatorConfig } from \"../types/extensions\";\n\n/** A registration record — player entered a tournament with a game token */\nexport interface TournamentRegistration {\n tournamentId: string;\n gameTokenId: string;\n}\n\n/** A leaderboard — ordered list of token IDs for a finalized tournament */\nexport interface TournamentLeaderboard {\n tournamentId: string;\n /** Token IDs in rank order (index 0 = 1st place) */\n tokenIds: string[];\n /** Whether this tournament has finalized */\n isFinalized: boolean;\n}\n\n/** A resolved qualification proof for the tournament validator */\nexport interface TournamentQualificationInput {\n tournamentId: string;\n tokenId: string;\n position: number;\n tournamentName?: string;\n}\n\n/**\n * Build a map of tournament ID → game token IDs the player used to enter.\n *\n * @param registrations - All registrations for the required tournaments\n * @param requiredTournamentIds - Tournament IDs from the validator config\n * @returns Map of tournamentId → array of game token IDs the player registered with\n */\nexport function buildParticipationMap(\n registrations: TournamentRegistration[],\n requiredTournamentIds: string[],\n): Record<string, string[]> {\n const requiredSet = new Set(requiredTournamentIds);\n const map: Record<string, string[]> = {};\n\n for (const reg of registrations) {\n if (!requiredSet.has(reg.tournamentId)) continue;\n if (!map[reg.tournamentId]) map[reg.tournamentId] = [];\n map[reg.tournamentId].push(reg.gameTokenId);\n }\n\n return map;\n}\n\n/**\n * Build a map of tournament ID → winning token positions the player holds.\n *\n * Cross-references finalized leaderboards with the player's owned game tokens\n * to find which tokens placed on which leaderboards.\n *\n * @param leaderboards - Leaderboards for the required tournaments\n * @param ownedGameTokenIds - Game token IDs the player currently owns\n * @param topPositions - Only count positions within top N (0 = all positions)\n * @returns Map of tournamentId → array of { tokenId, position }\n */\nexport function buildWinMap(\n leaderboards: TournamentLeaderboard[],\n ownedGameTokenIds: string[],\n topPositions: number = 0,\n): Record<string, Array<{ tokenId: string; position: number }>> {\n const ownedSet = new Set(ownedGameTokenIds);\n const map: Record<string, Array<{ tokenId: string; position: number }>> = {};\n\n for (const lb of leaderboards) {\n if (!lb.isFinalized) continue;\n\n const limit = topPositions > 0 ? topPositions : lb.tokenIds.length;\n\n for (let i = 0; i < Math.min(limit, lb.tokenIds.length); i++) {\n if (ownedSet.has(lb.tokenIds[i])) {\n if (!map[lb.tournamentId]) map[lb.tournamentId] = [];\n map[lb.tournamentId].push({\n tokenId: lb.tokenIds[i],\n position: i + 1,\n });\n }\n }\n }\n\n return map;\n}\n\n/**\n * Resolve tournament validator qualification inputs from player data.\n *\n * Takes the validator config, the player's registrations/leaderboard positions,\n * and returns the list of proofs to check against the extension contract.\n *\n * @param config - Parsed tournament validator config\n * @param participationMap - From buildParticipationMap()\n * @param winMap - From buildWinMap()\n * @param tournamentNames - Optional map of tournamentId → display name\n * @returns Array of qualification inputs to pass to the extension contract\n */\nexport function resolveTournamentQualifications(\n config: TournamentValidatorConfig,\n participationMap: Record<string, string[]>,\n winMap: Record<string, Array<{ tokenId: string; position: number }>>,\n tournamentNames?: Record<string, string>,\n): TournamentQualificationInput[] {\n const inputs: TournamentQualificationInput[] = [];\n\n if (config.requirementType === \"won\") {\n for (const tournamentId of config.tournamentIds) {\n const wonEntries = winMap[tournamentId];\n if (!wonEntries) continue;\n\n for (const entry of wonEntries) {\n inputs.push({\n tournamentId,\n tokenId: entry.tokenId,\n position: entry.position,\n tournamentName: tournamentNames?.[tournamentId],\n });\n }\n }\n } else {\n // participated\n for (const tournamentId of config.tournamentIds) {\n const tokenIds = participationMap[tournamentId];\n if (!tokenIds) continue;\n\n for (const tokenId of tokenIds) {\n inputs.push({\n tournamentId,\n tokenId,\n position: 1, // Participation = position 1\n tournamentName: tournamentNames?.[tournamentId],\n });\n }\n }\n }\n\n return inputs;\n}\n","/**\n * Opus Troves entry calculation.\n *\n * The Opus Troves extension gates entry based on the player's CASH debt\n * in the Opus Protocol. This module contains the pure math for determining\n * how many entries a given debt level allows, and which entries are bannable\n * if a player's debt drops below the threshold.\n *\n * The trove debt fetching (getUserTroveIds, getTroveHealth) is RPC-specific\n * and stays in each app. This module handles the calculation once you have\n * the debt value.\n */\n\nimport type { OpusTrovesValidatorConfig } from \"../types/extensions\";\n\n/**\n * Calculate how many entries a player's total debt allows.\n *\n * Two modes based on config:\n * - Proportional (valuePerEntry > 0): entries = (debt - threshold) / valuePerEntry\n * - Fixed (valuePerEntry == 0): if debt >= threshold → maxEntries\n *\n * @param debt - Player's total CASH debt across all troves (18 decimals)\n * @param config - Parsed Opus Troves validator config\n * @returns Number of entries allowed (0 if below threshold)\n */\nexport function calculateOpusTrovesEntries(\n debt: bigint,\n config: OpusTrovesValidatorConfig,\n): number {\n let allowed = 0;\n\n if (config.valuePerEntry > 0n) {\n // Proportional: entries scale with debt above threshold\n if (debt > config.threshold) {\n allowed = Number((debt - config.threshold) / config.valuePerEntry);\n }\n } else {\n // Fixed: meets threshold → gets maxEntries\n if (debt >= config.threshold && config.maxEntries > 0) {\n allowed = config.maxEntries;\n }\n }\n\n // Cap at maxEntries if specified\n if (config.maxEntries > 0) {\n allowed = Math.min(allowed, config.maxEntries);\n }\n\n return allowed;\n}\n\n/**\n * Determine which entries should be banned based on debt vs allowed entries.\n *\n * When a player's debt drops below what their entries require, the excess\n * entries (sorted by token ID ascending — oldest first) become bannable.\n *\n * @param registeredTokenIds - Token IDs the player registered with\n * @param entriesAllowed - From calculateOpusTrovesEntries()\n * @returns Set of token IDs that should be banned\n */\nexport function findBannableEntries(\n registeredTokenIds: string[],\n entriesAllowed: number,\n): Set<string> {\n const bannable = new Set<string>();\n const bannableCount = Math.max(0, registeredTokenIds.length - entriesAllowed);\n\n if (bannableCount > 0) {\n // Sort by token ID ascending (oldest entries first)\n const sorted = [...registeredTokenIds].sort((a, b) => {\n return Number(BigInt(a)) - Number(BigInt(b));\n });\n for (let i = 0; i < bannableCount; i++) {\n bannable.add(sorted[i]);\n }\n }\n\n return bannable;\n}\n\n/**\n * Batch calculate bannable entries for multiple players.\n *\n * Takes a map of player → { debt, registeredTokenIds } and returns\n * the set of all bannable token IDs across all players.\n *\n * @param players - Map of player address → their debt and registered entries\n * @param config - Parsed Opus Troves validator config\n * @returns Set of all bannable token IDs\n */\nexport function findAllBannableEntries(\n players: Map<string, { debt: bigint; registeredTokenIds: string[] }>,\n config: OpusTrovesValidatorConfig,\n): Set<string> {\n const allBannable = new Set<string>();\n\n for (const [, { debt, registeredTokenIds }] of players) {\n const allowed = calculateOpusTrovesEntries(debt, config);\n const bannable = findBannableEntries(registeredTokenIds, allowed);\n for (const id of bannable) {\n allBannable.add(id);\n }\n }\n\n return allBannable;\n}\n","import type { Prize } from \"../types/prize\";\nimport { calculateEntryFeeBreakdown, distributePool } from \"./entryFee\";\nimport type { EntryFeeShares } from \"./entryFee\";\nimport { calculateDistribution } from \"./formatting\";\nimport { calculatePrizeValue } from \"./prizes\";\n\n/**\n * Entry fee configuration as provided by metagame contracts (e.g. Budokan SDK).\n */\nexport interface EntryFeeConfig {\n tokenAddress: string;\n amount: string;\n tournamentCreatorShare: number;\n gameCreatorShare: number;\n refundShare: number;\n distribution: unknown;\n distributionCount: number;\n}\n\n/**\n * Build Prize[] from entry fee configuration and entry count.\n *\n * Calculates the total entry fee pool, subtracts creator/game/refund shares,\n * then distributes the remaining prize pool across positions using the\n * configured distribution curve.\n *\n * @param entryFee - Entry fee configuration from the tournament\n * @param entryCount - Number of entries in the tournament\n * @returns Array of Prize objects representing entry fee prizes per position\n */\nexport function buildEntryFeePrizes(\n entryFee: EntryFeeConfig,\n entryCount: number,\n): Prize[] {\n if (!entryFee.amount || entryCount === 0 || entryFee.distributionCount <= 0) {\n return [];\n }\n\n const shares: EntryFeeShares = {\n creatorShare: entryFee.tournamentCreatorShare,\n gameCreatorShare: entryFee.gameCreatorShare,\n refundShare: entryFee.refundShare,\n };\n\n const breakdown = calculateEntryFeeBreakdown(\n BigInt(entryFee.amount),\n entryCount,\n shares,\n );\n\n if (breakdown.prizePoolAmount <= 0n) return [];\n\n // Resolve distribution curve\n const dist = entryFee.distribution as any;\n let distributionType: \"linear\" | \"exponential\" | \"uniform\" = \"uniform\";\n let weight = 10;\n\n if (dist?.type === \"linear\" || dist?.Linear !== undefined) {\n distributionType = \"linear\";\n weight = Number(dist.weight ?? dist.Linear ?? 100) / 10;\n } else if (dist?.type === \"exponential\" || dist?.Exponential !== undefined) {\n distributionType = \"exponential\";\n weight = Number(dist.weight ?? dist.Exponential ?? 100) / 10;\n }\n\n const percentages = calculateDistribution(\n entryFee.distributionCount,\n weight,\n 0,\n 0,\n 0,\n distributionType,\n );\n\n const positions = distributePool(breakdown.prizePoolAmount, percentages);\n\n return positions.map((pos) => ({\n id: `entry_fee_${pos.position}`,\n position: pos.position,\n tokenAddress: entryFee.tokenAddress,\n tokenType: \"erc20\" as const,\n amount: pos.amount.toString(),\n sponsorAddress: \"\",\n }));\n}\n\n/**\n * Token price lookup: normalized address → USD price.\n */\nexport type TokenPriceLookup = Record<string, number>;\n\n/**\n * Token decimals lookup: normalized address → decimals.\n */\nexport type TokenDecimalsLookup = Record<string, number>;\n\n/**\n * Calculate total USD value of a set of prizes.\n *\n * @param prizes - Array of Prize objects (sponsored + entry fee)\n * @param prices - Token price lookup (normalized address → USD price)\n * @param decimals - Token decimals lookup (normalized address → decimals, defaults to 18)\n * @param normalizeAddress - Function to normalize addresses for lookup (e.g. indexAddress)\n * @returns Total USD value, or 0 if any required price is missing\n */\nexport function calculateTotalPrizeValueUSD(\n prizes: Prize[],\n prices: TokenPriceLookup,\n decimals: TokenDecimalsLookup,\n normalizeAddress: (addr: string) => string = (addr) => addr,\n): number {\n let total = 0;\n\n for (const prize of prizes) {\n if (prize.tokenType !== \"erc20\") continue;\n const addr = normalizeAddress(prize.tokenAddress);\n const price = prices[addr];\n if (price === undefined) continue;\n const dec = decimals[addr] ?? 18;\n total += calculatePrizeValue(prize.amount, dec, price);\n }\n\n return total;\n}\n\n/**\n * Calculate the number of paid positions (places that receive prizes).\n *\n * Takes the maximum of sponsored prize positions and entry fee distribution count.\n *\n * @param sponsoredPrizes - Array of sponsored Prize objects\n * @param entryFeeDistributionCount - Number of positions from entry fee distribution\n * @returns Number of paid places\n */\nexport function calculatePaidPlaces(\n sponsoredPrizes: Prize[],\n entryFeeDistributionCount: number,\n): number {\n const maxSponsoredPosition = sponsoredPrizes.reduce(\n (max, p) => Math.max(max, p.position),\n 0,\n );\n return Math.max(maxSponsoredPosition, entryFeeDistributionCount);\n}\n","/**\n * Merkle API client for fetching proofs.\n *\n * The merkle validator stores tree data in a separate API service.\n * Each network has its own API instance and database.\n * Proofs are computed on-demand from the stored tree.\n */\n\nconst DEFAULT_MERKLE_API_URLS: Record<string, string> = {\n SN_SEPOLIA: \"https://merkle-api-sepolia.up.railway.app\",\n SN_MAIN: \"https://merkle-api.up.railway.app\",\n};\n\nconst merkleApiUrls: Record<string, string> = { ...DEFAULT_MERKLE_API_URLS };\n\n/**\n * Set the merkle API URL for a specific network.\n * Call this at app initialization for each network you want to override.\n * @deprecated Use `createMerkleClient({ chainId, apiUrl })` from `@provable-games/metagame-sdk/merkle` instead.\n */\nexport function setMerkleApiUrl(chainId: string, url: string): void {\n merkleApiUrls[chainId] = url;\n}\n\n/**\n * Get the merkle API URL for a specific network.\n * Falls back to SN_MAIN if the chain ID is not configured.\n * @deprecated Use `createMerkleClient({ chainId })` from `@provable-games/metagame-sdk/merkle` instead.\n */\nexport function getMerkleApiUrl(chainId?: string): string {\n if (chainId && merkleApiUrls[chainId]) {\n return merkleApiUrls[chainId];\n }\n return merkleApiUrls.SN_MAIN ?? DEFAULT_MERKLE_API_URLS.SN_MAIN;\n}\n\nexport interface MerkleTree {\n id: number;\n name: string;\n description: string;\n root: string;\n entryCount: number;\n createdAt: string;\n}\n\nexport interface MerkleProofResponse {\n address: string;\n count: number;\n proof: string[];\n qualification: string[];\n}\n\nexport interface MerkleTreesResponse {\n data: MerkleTree[];\n total: number;\n page: number;\n limit: number;\n totalPages: number;\n}\n\n/**\n * Fetch merkle trees from the API with pagination.\n *\n * @param options - Optional pagination and network parameters\n * @returns Paginated response with tree metadata, or empty result on error\n * @deprecated Use `MerkleClient.getTrees()` from `@provable-games/metagame-sdk/merkle` instead.\n */\nexport async function fetchMerkleTrees(options?: {\n page?: number;\n limit?: number;\n chainId?: string;\n}): Promise<MerkleTreesResponse> {\n const empty: MerkleTreesResponse = {\n data: [],\n total: 0,\n page: 1,\n limit: 20,\n totalPages: 0,\n };\n try {\n const baseUrl = getMerkleApiUrl(options?.chainId);\n const params = new URLSearchParams();\n if (options?.page) params.set(\"page\", String(options.page));\n if (options?.limit) params.set(\"limit\", String(options.limit));\n const qs = params.toString();\n const res = await fetch(`${baseUrl}/trees${qs ? `?${qs}` : \"\"}`);\n if (!res.ok) return empty;\n const json = await res.json();\n return {\n data: json.data ?? [],\n total: json.total ?? 0,\n page: json.page ?? 1,\n limit: json.limit ?? 20,\n totalPages: json.totalPages ?? 0,\n };\n } catch {\n return empty;\n }\n}\n\nexport interface CreateMerkleTreeRequest {\n id: number;\n name: string;\n description: string;\n entries: Array<{ address: string; count: number }>;\n}\n\nexport interface CreateMerkleTreeResponse {\n id: number;\n root: string;\n entryCount: number;\n}\n\n/**\n * Create a merkle tree in the API.\n *\n * @param request - Tree data including ID (from on-chain), name, description, and entries\n * @param chainId - Optional chain ID to select the correct API\n * @returns The created tree metadata\n * @deprecated Use `MerkleClient.storeTree()` from `@provable-games/metagame-sdk/merkle` instead.\n */\nexport async function createMerkleTree(\n request: CreateMerkleTreeRequest,\n chainId?: string,\n): Promise<CreateMerkleTreeResponse> {\n const baseUrl = getMerkleApiUrl(chainId);\n const res = await fetch(`${baseUrl}/trees`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(request),\n });\n if (!res.ok) {\n const text = await res.text();\n throw new Error(`Failed to create merkle tree: ${text}`);\n }\n return await res.json();\n}\n\nexport interface MerkleTreeEntry {\n address: string;\n count: number;\n}\n\nexport interface MerkleTreeEntriesResponse {\n data: MerkleTreeEntry[];\n total: number;\n page: number;\n limit: number;\n totalPages: number;\n}\n\n/**\n * Fetch entries for a merkle tree from the API with pagination.\n *\n * @param treeId - The on-chain tree ID\n * @param options - Optional pagination and network parameters\n * @returns Paginated response with tree entries, or empty result on error\n * @deprecated Use `MerkleClient.getTreeEntries()` from `@provable-games/metagame-sdk/merkle` instead.\n */\nexport async function fetchMerkleTreeEntries(\n treeId: string | number,\n options?: {\n page?: number;\n limit?: number;\n chainId?: string;\n },\n): Promise<MerkleTreeEntriesResponse> {\n const empty: MerkleTreeEntriesResponse = {\n data: [],\n total: 0,\n page: 1,\n limit: 50,\n totalPages: 0,\n };\n try {\n const baseUrl = getMerkleApiUrl(options?.chainId);\n const params = new URLSearchParams();\n if (options?.page) params.set(\"page\", String(options.page));\n if (options?.limit) params.set(\"limit\", String(options.limit));\n const qs = params.toString();\n const res = await fetch(\n `${baseUrl}/trees/${treeId}/entries${qs ? `?${qs}` : \"\"}`,\n );\n if (!res.ok) return empty;\n const json = await res.json();\n return {\n data: json.data ?? [],\n total: json.total ?? 0,\n page: json.page ?? 1,\n limit: json.limit ?? 50,\n totalPages: json.totalPages ?? 0,\n };\n } catch {\n return empty;\n }\n}\n\n/**\n * Fetch a merkle proof for a player address from the API.\n *\n * @param treeId - The on-chain tree ID\n * @param playerAddress - The player's address\n * @param chainId - Optional chain ID to select the correct API\n * @returns The proof data including the qualification array, or null if not found\n * @deprecated Use `MerkleClient.getProof()` from `@provable-games/metagame-sdk/merkle` instead.\n */\nexport async function fetchMerkleProof(\n treeId: string | number,\n playerAddress: string,\n chainId?: string,\n): Promise<MerkleProofResponse | null> {\n try {\n const baseUrl = getMerkleApiUrl(chainId);\n const res = await fetch(\n `${baseUrl}/trees/${treeId}/proof/${playerAddress.toLowerCase()}`,\n );\n if (!res.ok) return null;\n return await res.json();\n } catch {\n return null;\n }\n}\n","import { StandardMerkleTree } from \"@ericnordelo/strk-merkle-tree\";\nimport { hash } from \"starknet\";\n\nexport interface MerkleEntry {\n address: string;\n count: number;\n}\n\nexport interface MerkleTreeData {\n version: 2;\n createdAt: string;\n entries: MerkleEntry[];\n root: string;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n tree: any; // StandardMerkleTree dump format\n}\n\n/**\n * Compute the leaf value that gets passed to StandardMerkleTree.\n * This matches the Cairo contract's leaf computation:\n * PedersenTrait::new(0).update(address).update(count).finalize()\n *\n * The StandardMerkleTree then applies its own leaf hashing on top:\n * H(0, value, 1) using PedersenCHasher\n */\nexport function computeLeafValue(address: string, count: number): string {\n const intermediate = hash.computePedersenHash(\"0x0\", address);\n return hash.computePedersenHash(intermediate, \"0x\" + count.toString(16));\n}\n\n/**\n * Build a StandardMerkleTree from entries.\n * Each leaf is a single felt252 value (the pre-hashed leaf value).\n */\nexport function buildMerkleTree(entries: MerkleEntry[]): MerkleTreeData {\n if (entries.length === 0) {\n throw new Error(\"Cannot build merkle tree with no entries\");\n }\n\n const leaves = entries.map((e) => [computeLeafValue(e.address, e.count)]);\n\n const tree = StandardMerkleTree.of(leaves, [\"felt252\"], {\n sortLeaves: true,\n });\n\n return {\n version: 2,\n createdAt: new Date().toISOString(),\n entries,\n root: tree.root,\n tree: tree.dump(),\n };\n}\n\n/**\n * Load a tree from saved data and get the proof for an address.\n */\nexport function getProof(\n treeData: MerkleTreeData,\n address: string,\n count: number,\n): string[] | null {\n const tree = StandardMerkleTree.load(treeData.tree);\n const leafValue = computeLeafValue(address, count);\n\n for (const [index, leaf] of tree.entries()) {\n if (BigInt(leaf[0] as string) === BigInt(leafValue)) {\n return tree.getProof(index);\n }\n }\n\n return null;\n}\n\n/**\n * Verify a proof against a root (client-side).\n */\nexport function verifyProof(\n treeData: MerkleTreeData,\n address: string,\n count: number,\n proof: string[],\n): boolean {\n const leafValue = computeLeafValue(address, count);\n return StandardMerkleTree.verify(\n treeData.root,\n [\"felt252\"],\n [leafValue],\n proof,\n );\n}\n\n/**\n * Build qualification array for contract calls: [count, ...proof]\n */\nexport function buildQualification(count: number, proof: string[]): string[] {\n return [\"0x\" + count.toString(16), ...proof];\n}\n\n/**\n * Find an entry in the tree by address.\n */\nexport function findEntry(\n treeData: MerkleTreeData,\n address: string,\n): MerkleEntry | null {\n return (\n treeData.entries.find(\n (e) =>\n e.address.toLowerCase() === address.toLowerCase() ||\n BigInt(e.address) === BigInt(address),\n ) || null\n );\n}\n","/**\n * MerkleClient — chainId-aware client for the merkle API service.\n *\n * Resolves the API URL once at construction time so callers never\n * need to pass chainId on every request.\n */\n\nimport { buildMerkleTree } from \"./merkleTree\";\nimport type { MerkleEntry } from \"./merkleTree\";\n\n// ── Default API URLs per chain ──────────────────────────────────────────────\n\nconst DEFAULT_MERKLE_API_URLS: Record<string, string> = {\n SN_SEPOLIA: \"https://merkle-api-sepolia.up.railway.app\",\n SN_MAIN: \"https://merkle-api.up.railway.app\",\n};\n\n// ── Types ───────────────────────────────────────────────────────────────────\n\nexport interface MerkleClientConfig {\n /** Starknet chain ID, e.g. \"SN_MAIN\" or \"SN_SEPOLIA\" */\n chainId: string;\n /** Override the default API URL for this chain */\n apiUrl?: string;\n}\n\nexport interface MerkleTree {\n id: number;\n name: string;\n description: string;\n root: string;\n entryCount: number;\n createdAt: string;\n}\n\nexport interface MerkleTreesResponse {\n data: MerkleTree[];\n total: number;\n page: number;\n limit: number;\n totalPages: number;\n}\n\nexport interface MerkleProofResponse {\n address: string;\n count: number;\n proof: string[];\n qualification: string[];\n}\n\nexport interface MerkleTreeEntry {\n address: string;\n count: number;\n}\n\nexport interface MerkleTreeEntriesResponse {\n data: MerkleTreeEntry[];\n total: number;\n page: number;\n limit: number;\n totalPages: number;\n}\n\nexport interface CreateMerkleTreeRequest {\n id: number;\n name: string;\n description: string;\n entries: MerkleEntry[];\n}\n\nexport interface CreateMerkleTreeResponse {\n id: number;\n root: string;\n entryCount: number;\n}\n\nexport interface TreeCalldata {\n tree: ReturnType<typeof buildMerkleTree>;\n call: {\n contractAddress: string;\n entrypoint: string;\n calldata: string[];\n };\n}\n\n// ── Client ──────────────────────────────────────────────────────────────────\n\nexport class MerkleClient {\n readonly apiUrl: string;\n\n constructor(config: MerkleClientConfig) {\n this.apiUrl =\n config.apiUrl ??\n DEFAULT_MERKLE_API_URLS[config.chainId] ??\n DEFAULT_MERKLE_API_URLS.SN_MAIN;\n }\n\n /** Fetch paginated list of merkle trees. */\n async getTrees(options?: {\n page?: number;\n limit?: number;\n }): Promise<MerkleTreesResponse> {\n const empty: MerkleTreesResponse = {\n data: [],\n total: 0,\n page: 1,\n limit: 20,\n totalPages: 0,\n };\n try {\n const params = new URLSearchParams();\n if (options?.page) params.set(\"page\", String(options.page));\n if (options?.limit) params.set(\"limit\", String(options.limit));\n const qs = params.toString();\n const res = await fetch(`${this.apiUrl}/trees${qs ? `?${qs}` : \"\"}`);\n if (!res.ok) return empty;\n const json = await res.json();\n return {\n data: json.data ?? [],\n total: json.total ?? 0,\n page: json.page ?? 1,\n limit: json.limit ?? 20,\n totalPages: json.totalPages ?? 0,\n };\n } catch {\n return empty;\n }\n }\n\n /** Fetch entries for a specific merkle tree. */\n async getTreeEntries(\n treeId: string | number,\n options?: { page?: number; limit?: number },\n ): Promise<MerkleTreeEntriesResponse> {\n const empty: MerkleTreeEntriesResponse = {\n data: [],\n total: 0,\n page: 1,\n limit: 50,\n totalPages: 0,\n };\n try {\n const params = new URLSearchParams();\n if (options?.page) params.set(\"page\", String(options.page));\n if (options?.limit) params.set(\"limit\", String(options.limit));\n const qs = params.toString();\n const res = await fetch(\n `${this.apiUrl}/trees/${treeId}/entries${qs ? `?${qs}` : \"\"}`,\n );\n if (!res.ok) return empty;\n const json = await res.json();\n return {\n data: json.data ?? [],\n total: json.total ?? 0,\n page: json.page ?? 1,\n limit: json.limit ?? 50,\n totalPages: json.totalPages ?? 0,\n };\n } catch {\n return empty;\n }\n }\n\n /** Fetch a merkle proof for a player address. */\n async getProof(\n treeId: string | number,\n playerAddress: string,\n ): Promise<MerkleProofResponse | null> {\n try {\n const res = await fetch(\n `${this.apiUrl}/trees/${treeId}/proof/${playerAddress.toLowerCase()}`,\n );\n if (!res.ok) return null;\n return await res.json();\n } catch {\n return null;\n }\n }\n\n /** Store a merkle tree in the API (after on-chain registration). */\n async storeTree(\n request: CreateMerkleTreeRequest,\n ): Promise<CreateMerkleTreeResponse> {\n const res = await fetch(`${this.apiUrl}/trees`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(request),\n });\n if (!res.ok) {\n const text = await res.text();\n throw new Error(`Failed to create merkle tree: ${text}`);\n }\n return await res.json();\n }\n\n /**\n * Build a merkle tree locally and return the calldata needed\n * to register it on-chain via the validator contract.\n *\n * The consumer is responsible for executing the call with their\n * own account/signer.\n */\n buildTreeCalldata(\n entries: MerkleEntry[],\n validatorAddress: string,\n ): TreeCalldata {\n const tree = buildMerkleTree(entries);\n return {\n tree,\n call: {\n contractAddress: validatorAddress,\n entrypoint: \"create_tree\",\n calldata: [tree.root],\n },\n };\n }\n\n /**\n * Parse the tree ID from transaction receipt events.\n * Returns null if the event cannot be found.\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n parseTreeIdFromEvents(events: any[], validatorAddress: string): number | null {\n const validatorBigInt = BigInt(validatorAddress);\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const treeEvent = events.find((e: any) => {\n try {\n return BigInt(e.from_address) === validatorBigInt;\n } catch {\n return false;\n }\n });\n if (!treeEvent?.keys?.[1]) return null;\n return Number(BigInt(treeEvent.keys[1]));\n }\n\n /**\n * Store the tree in the API after on-chain registration.\n * Pass the tree ID from the on-chain event along with the original entries.\n */\n async createTree(params: {\n treeId: number;\n name: string;\n description: string;\n entries: MerkleEntry[];\n }): Promise<CreateMerkleTreeResponse> {\n return this.storeTree({\n id: params.treeId,\n name: params.name,\n description: params.description,\n entries: params.entries,\n });\n }\n}\n\n/** Factory function for creating a MerkleClient. */\nexport function createMerkleClient(config: MerkleClientConfig): MerkleClient {\n return new MerkleClient(config);\n}\n","/**\n * MetagameClient — top-level SDK client with chain-aware sub-clients.\n *\n * Resolves chain configuration once at construction time so downstream\n * methods never need chainId passed on every call.\n *\n * Usage:\n * const client = createMetagameClient({ chainId: \"SN_MAIN\" });\n * const trees = await client.merkle.getTrees();\n * const proof = await client.merkle.getProof(treeId, address);\n */\n\nimport { MerkleClient } from \"./merkle/client\";\nimport type { MerkleClientConfig } from \"./merkle/client\";\n\nexport interface MetagameClientConfig {\n /** Starknet chain ID, e.g. \"SN_MAIN\" or \"SN_SEPOLIA\" */\n chainId: string;\n /** Override the default merkle API URL */\n merkleApiUrl?: string;\n}\n\nexport class MetagameClient {\n readonly chainId: string;\n readonly merkle: MerkleClient;\n\n constructor(config: MetagameClientConfig) {\n this.chainId = config.chainId;\n\n const merkleConfig: MerkleClientConfig = {\n chainId: config.chainId,\n apiUrl: config.merkleApiUrl,\n };\n this.merkle = new MerkleClient(merkleConfig);\n }\n}\n\n/** Factory function for creating a MetagameClient. */\nexport function createMetagameClient(\n config: MetagameClientConfig,\n): MetagameClient {\n return new MetagameClient(config);\n}\n"]}