@provable-games/metagame-sdk 0.1.3 → 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.d.cts CHANGED
@@ -1,6 +1,7 @@
1
- import { P as Prize, S as StatusTimestamps, a as StatusResult, E as ExtensionAddresses, Q as QualifyingModeInfo, b as ExtensionType, c as ERC20BalanceValidatorConfig, T as TournamentValidatorConfig, O as OpusTrovesValidatorConfig, d as SnapshotValidatorConfig, Z as ZkPassportValidatorConfig, G as GovernanceValidatorConfig, e as QualificationResult, f as EntryRequirementVariant, g as QualificationProof } from './prizeAggregation-CHwIJzXr.cjs';
2
- export { D as DistributionType, h as EntryFeeBreakdown, i as EntryFeeExtensionConfig, j as EntryFeeShares, k as ExtensionCategory, l as Participant, m as PositionPrizeGroup, n as PrizeExtensionConfig, o as QualificationEntry, p as QualifyingMode, q as SponsorContribution, r as StatusVariant, s as Token, t as aggregatePrizesByPosition, u as aggregatePrizesBySponsor, v as calculateDistribution, w as calculateEntryFeeBreakdown, x as calculatePayouts, y as distributePool, z as filterClaimablePrizes, A as filterZeroPrizes, B as formatNumber, C as formatPrizeAmount, F as formatScore, H as formatTime, I as formatUsdValue, J as getOrdinalSuffix } from './prizeAggregation-CHwIJzXr.cjs';
1
+ import { P as Prize, S as StatusTimestamps, a as StatusResult, E as ExtensionAddresses, Q as QualifyingModeInfo, b as ExtensionType, c as ERC20BalanceValidatorConfig, T as TournamentValidatorConfig, O as OpusTrovesValidatorConfig, d as SnapshotValidatorConfig, Z as ZkPassportValidatorConfig, G as GovernanceValidatorConfig, M as MerkleValidatorConfig, e as QualificationResult, f as EntryRequirementVariant, g as QualificationProof } from './client-CcoKJS8i.cjs';
2
+ export { D as DistributionType, h as EntryFeeBreakdown, i as EntryFeeExtensionConfig, j as EntryFeeShares, k as ExtensionCategory, l as MetagameClient, m as MetagameClientConfig, n as Participant, o as PositionPrizeGroup, p as PrizeExtensionConfig, q as QualificationEntry, r as QualifyingMode, s as SponsorContribution, t as StatusVariant, u as Token, v as aggregatePrizesByPosition, w as aggregatePrizesBySponsor, x as calculateDistribution, y as calculateEntryFeeBreakdown, z as calculatePayouts, A as createMetagameClient, B as distributePool, C as filterClaimablePrizes, F as filterZeroPrizes, H as formatNumber, I as formatPrizeAmount, J as formatScore, K as formatTime, L as formatUsdValue, N as getOrdinalSuffix } from './client-CcoKJS8i.cjs';
3
3
  import { CairoOption, CairoCustomEnum } from 'starknet';
4
+ import './merkle.cjs';
4
5
 
5
6
  interface EntryFee {
6
7
  tokenAddress: string;
@@ -160,6 +161,12 @@ declare function parseZkPassportValidatorConfig(config: Array<string | number |
160
161
  * votes_per_entry_low, votes_per_entry_high]
161
162
  */
162
163
  declare function parseGovernanceValidatorConfig(config: Array<string | number | bigint>): GovernanceValidatorConfig | null;
164
+ /**
165
+ * Parse a Merkle validator extension config array.
166
+ *
167
+ * Config format: [tree_id]
168
+ */
169
+ declare function parseMerkleValidatorConfig(config: Array<string | number | bigint>): MerkleValidatorConfig | null;
163
170
  /**
164
171
  * Parse any extension config by first identifying its type.
165
172
  *
@@ -185,6 +192,9 @@ declare function parseExtensionConfig(extensionAddress: string, config: Array<st
185
192
  } | {
186
193
  type: "governance";
187
194
  config: GovernanceValidatorConfig;
195
+ } | {
196
+ type: "merkle";
197
+ config: MerkleValidatorConfig;
188
198
  } | {
189
199
  type: "unknown";
190
200
  config: null;
@@ -486,4 +496,114 @@ declare function calculateTotalPrizeValueUSD(prizes: Prize[], prices: TokenPrice
486
496
  */
487
497
  declare function calculatePaidPlaces(sponsoredPrizes: Prize[], entryFeeDistributionCount: number): number;
488
498
 
489
- export { type Distribution, ERC20BalanceValidatorConfig, type EntryFee, type EntryFeeConfig, type EntryRequirement, EntryRequirementVariant, ExtensionAddresses, type ExtensionQualificationInput, ExtensionType, GovernanceValidatorConfig, type GroupedTokenPrize, type NftParseResult, type NftPrizeInput, OpusTrovesValidatorConfig, Prize, QualificationProof, QualificationResult, QualifyingModeInfo, SnapshotValidatorConfig, StatusResult, StatusTimestamps, type TokenDecimalsLookup, type TokenPriceLookup, type TokenQualificationInput, type TournamentLeaderboard, type TournamentQualificationInput, type TournamentRegistration, TournamentValidatorConfig, ZkPassportValidatorConfig, bigintToHex, buildEntryFeePrizes, buildExtensionProof, buildNFTProof, buildParticipationMap, buildQualificationProof, buildTournamentExtensionProof, buildWinMap, calculateOpusTrovesEntries, calculatePaidPlaces, calculatePrizeValue, calculateTotalPrizeValueUSD, computeStatus, displayAddress, evaluateExtensionQualification, evaluateQualification, evaluateTokenQualification, findAllBannableEntries, findBannableEntries, formatCashToUSD, formatTokenAmount, getExtensionAddresses, getOpusSupportedAssets, getQualifyingModeInfo, getWhitelistedExtensionAddresses, groupPrizesByToken, identifyExtensionType, indexAddress, isBefore, isWhitelistedExtension, padAddress, parseERC20BalanceValidatorConfig, parseExtensionConfig, parseGovernanceValidatorConfig, parseNFTBulkInput, parseOpusTrovesValidatorConfig, parseSnapshotValidatorConfig, parseTournamentValidatorConfig, parseZkPassportValidatorConfig, resolveTournamentQualifications };
499
+ /**
500
+ * Merkle API client for fetching proofs.
501
+ *
502
+ * The merkle validator stores tree data in a separate API service.
503
+ * Each network has its own API instance and database.
504
+ * Proofs are computed on-demand from the stored tree.
505
+ */
506
+ /**
507
+ * Set the merkle API URL for a specific network.
508
+ * Call this at app initialization for each network you want to override.
509
+ * @deprecated Use `createMerkleClient({ chainId, apiUrl })` from `@provable-games/metagame-sdk/merkle` instead.
510
+ */
511
+ declare function setMerkleApiUrl(chainId: string, url: string): void;
512
+ /**
513
+ * Get the merkle API URL for a specific network.
514
+ * Falls back to SN_MAIN if the chain ID is not configured.
515
+ * @deprecated Use `createMerkleClient({ chainId })` from `@provable-games/metagame-sdk/merkle` instead.
516
+ */
517
+ declare function getMerkleApiUrl(chainId?: string): string;
518
+ interface MerkleTree {
519
+ id: number;
520
+ name: string;
521
+ description: string;
522
+ root: string;
523
+ entryCount: number;
524
+ createdAt: string;
525
+ }
526
+ interface MerkleProofResponse {
527
+ address: string;
528
+ count: number;
529
+ proof: string[];
530
+ qualification: string[];
531
+ }
532
+ interface MerkleTreesResponse {
533
+ data: MerkleTree[];
534
+ total: number;
535
+ page: number;
536
+ limit: number;
537
+ totalPages: number;
538
+ }
539
+ /**
540
+ * Fetch merkle trees from the API with pagination.
541
+ *
542
+ * @param options - Optional pagination and network parameters
543
+ * @returns Paginated response with tree metadata, or empty result on error
544
+ * @deprecated Use `MerkleClient.getTrees()` from `@provable-games/metagame-sdk/merkle` instead.
545
+ */
546
+ declare function fetchMerkleTrees(options?: {
547
+ page?: number;
548
+ limit?: number;
549
+ chainId?: string;
550
+ }): Promise<MerkleTreesResponse>;
551
+ interface CreateMerkleTreeRequest {
552
+ id: number;
553
+ name: string;
554
+ description: string;
555
+ entries: Array<{
556
+ address: string;
557
+ count: number;
558
+ }>;
559
+ }
560
+ interface CreateMerkleTreeResponse {
561
+ id: number;
562
+ root: string;
563
+ entryCount: number;
564
+ }
565
+ /**
566
+ * Create a merkle tree in the API.
567
+ *
568
+ * @param request - Tree data including ID (from on-chain), name, description, and entries
569
+ * @param chainId - Optional chain ID to select the correct API
570
+ * @returns The created tree metadata
571
+ * @deprecated Use `MerkleClient.storeTree()` from `@provable-games/metagame-sdk/merkle` instead.
572
+ */
573
+ declare function createMerkleTree(request: CreateMerkleTreeRequest, chainId?: string): Promise<CreateMerkleTreeResponse>;
574
+ interface MerkleTreeEntry {
575
+ address: string;
576
+ count: number;
577
+ }
578
+ interface MerkleTreeEntriesResponse {
579
+ data: MerkleTreeEntry[];
580
+ total: number;
581
+ page: number;
582
+ limit: number;
583
+ totalPages: number;
584
+ }
585
+ /**
586
+ * Fetch entries for a merkle tree from the API with pagination.
587
+ *
588
+ * @param treeId - The on-chain tree ID
589
+ * @param options - Optional pagination and network parameters
590
+ * @returns Paginated response with tree entries, or empty result on error
591
+ * @deprecated Use `MerkleClient.getTreeEntries()` from `@provable-games/metagame-sdk/merkle` instead.
592
+ */
593
+ declare function fetchMerkleTreeEntries(treeId: string | number, options?: {
594
+ page?: number;
595
+ limit?: number;
596
+ chainId?: string;
597
+ }): Promise<MerkleTreeEntriesResponse>;
598
+ /**
599
+ * Fetch a merkle proof for a player address from the API.
600
+ *
601
+ * @param treeId - The on-chain tree ID
602
+ * @param playerAddress - The player's address
603
+ * @param chainId - Optional chain ID to select the correct API
604
+ * @returns The proof data including the qualification array, or null if not found
605
+ * @deprecated Use `MerkleClient.getProof()` from `@provable-games/metagame-sdk/merkle` instead.
606
+ */
607
+ declare function fetchMerkleProof(treeId: string | number, playerAddress: string, chainId?: string): Promise<MerkleProofResponse | null>;
608
+
609
+ export { type CreateMerkleTreeRequest, type CreateMerkleTreeResponse, type Distribution, ERC20BalanceValidatorConfig, type EntryFee, type EntryFeeConfig, type EntryRequirement, EntryRequirementVariant, ExtensionAddresses, type ExtensionQualificationInput, ExtensionType, GovernanceValidatorConfig, type GroupedTokenPrize, type MerkleProofResponse, type MerkleTree, type MerkleTreeEntriesResponse, type MerkleTreeEntry, type MerkleTreesResponse, MerkleValidatorConfig, type NftParseResult, type NftPrizeInput, OpusTrovesValidatorConfig, Prize, QualificationProof, QualificationResult, QualifyingModeInfo, SnapshotValidatorConfig, StatusResult, StatusTimestamps, type TokenDecimalsLookup, type TokenPriceLookup, type TokenQualificationInput, type TournamentLeaderboard, type TournamentQualificationInput, type TournamentRegistration, TournamentValidatorConfig, ZkPassportValidatorConfig, bigintToHex, buildEntryFeePrizes, buildExtensionProof, buildNFTProof, buildParticipationMap, buildQualificationProof, buildTournamentExtensionProof, buildWinMap, calculateOpusTrovesEntries, calculatePaidPlaces, calculatePrizeValue, calculateTotalPrizeValueUSD, computeStatus, createMerkleTree, displayAddress, evaluateExtensionQualification, evaluateQualification, evaluateTokenQualification, fetchMerkleProof, fetchMerkleTreeEntries, fetchMerkleTrees, findAllBannableEntries, findBannableEntries, formatCashToUSD, formatTokenAmount, getExtensionAddresses, getMerkleApiUrl, getOpusSupportedAssets, getQualifyingModeInfo, getWhitelistedExtensionAddresses, groupPrizesByToken, identifyExtensionType, indexAddress, isBefore, isWhitelistedExtension, padAddress, parseERC20BalanceValidatorConfig, parseExtensionConfig, parseGovernanceValidatorConfig, parseMerkleValidatorConfig, parseNFTBulkInput, parseOpusTrovesValidatorConfig, parseSnapshotValidatorConfig, parseTournamentValidatorConfig, parseZkPassportValidatorConfig, resolveTournamentQualifications, setMerkleApiUrl };
package/dist/index.d.ts CHANGED
@@ -1,6 +1,7 @@
1
- import { P as Prize, S as StatusTimestamps, a as StatusResult, E as ExtensionAddresses, Q as QualifyingModeInfo, b as ExtensionType, c as ERC20BalanceValidatorConfig, T as TournamentValidatorConfig, O as OpusTrovesValidatorConfig, d as SnapshotValidatorConfig, Z as ZkPassportValidatorConfig, G as GovernanceValidatorConfig, e as QualificationResult, f as EntryRequirementVariant, g as QualificationProof } from './prizeAggregation-CHwIJzXr.js';
2
- export { D as DistributionType, h as EntryFeeBreakdown, i as EntryFeeExtensionConfig, j as EntryFeeShares, k as ExtensionCategory, l as Participant, m as PositionPrizeGroup, n as PrizeExtensionConfig, o as QualificationEntry, p as QualifyingMode, q as SponsorContribution, r as StatusVariant, s as Token, t as aggregatePrizesByPosition, u as aggregatePrizesBySponsor, v as calculateDistribution, w as calculateEntryFeeBreakdown, x as calculatePayouts, y as distributePool, z as filterClaimablePrizes, A as filterZeroPrizes, B as formatNumber, C as formatPrizeAmount, F as formatScore, H as formatTime, I as formatUsdValue, J as getOrdinalSuffix } from './prizeAggregation-CHwIJzXr.js';
1
+ import { P as Prize, S as StatusTimestamps, a as StatusResult, E as ExtensionAddresses, Q as QualifyingModeInfo, b as ExtensionType, c as ERC20BalanceValidatorConfig, T as TournamentValidatorConfig, O as OpusTrovesValidatorConfig, d as SnapshotValidatorConfig, Z as ZkPassportValidatorConfig, G as GovernanceValidatorConfig, M as MerkleValidatorConfig, e as QualificationResult, f as EntryRequirementVariant, g as QualificationProof } from './client-CD-q6Alx.js';
2
+ export { D as DistributionType, h as EntryFeeBreakdown, i as EntryFeeExtensionConfig, j as EntryFeeShares, k as ExtensionCategory, l as MetagameClient, m as MetagameClientConfig, n as Participant, o as PositionPrizeGroup, p as PrizeExtensionConfig, q as QualificationEntry, r as QualifyingMode, s as SponsorContribution, t as StatusVariant, u as Token, v as aggregatePrizesByPosition, w as aggregatePrizesBySponsor, x as calculateDistribution, y as calculateEntryFeeBreakdown, z as calculatePayouts, A as createMetagameClient, B as distributePool, C as filterClaimablePrizes, F as filterZeroPrizes, H as formatNumber, I as formatPrizeAmount, J as formatScore, K as formatTime, L as formatUsdValue, N as getOrdinalSuffix } from './client-CD-q6Alx.js';
3
3
  import { CairoOption, CairoCustomEnum } from 'starknet';
4
+ import './merkle.js';
4
5
 
5
6
  interface EntryFee {
6
7
  tokenAddress: string;
@@ -160,6 +161,12 @@ declare function parseZkPassportValidatorConfig(config: Array<string | number |
160
161
  * votes_per_entry_low, votes_per_entry_high]
161
162
  */
162
163
  declare function parseGovernanceValidatorConfig(config: Array<string | number | bigint>): GovernanceValidatorConfig | null;
164
+ /**
165
+ * Parse a Merkle validator extension config array.
166
+ *
167
+ * Config format: [tree_id]
168
+ */
169
+ declare function parseMerkleValidatorConfig(config: Array<string | number | bigint>): MerkleValidatorConfig | null;
163
170
  /**
164
171
  * Parse any extension config by first identifying its type.
165
172
  *
@@ -185,6 +192,9 @@ declare function parseExtensionConfig(extensionAddress: string, config: Array<st
185
192
  } | {
186
193
  type: "governance";
187
194
  config: GovernanceValidatorConfig;
195
+ } | {
196
+ type: "merkle";
197
+ config: MerkleValidatorConfig;
188
198
  } | {
189
199
  type: "unknown";
190
200
  config: null;
@@ -486,4 +496,114 @@ declare function calculateTotalPrizeValueUSD(prizes: Prize[], prices: TokenPrice
486
496
  */
487
497
  declare function calculatePaidPlaces(sponsoredPrizes: Prize[], entryFeeDistributionCount: number): number;
488
498
 
489
- export { type Distribution, ERC20BalanceValidatorConfig, type EntryFee, type EntryFeeConfig, type EntryRequirement, EntryRequirementVariant, ExtensionAddresses, type ExtensionQualificationInput, ExtensionType, GovernanceValidatorConfig, type GroupedTokenPrize, type NftParseResult, type NftPrizeInput, OpusTrovesValidatorConfig, Prize, QualificationProof, QualificationResult, QualifyingModeInfo, SnapshotValidatorConfig, StatusResult, StatusTimestamps, type TokenDecimalsLookup, type TokenPriceLookup, type TokenQualificationInput, type TournamentLeaderboard, type TournamentQualificationInput, type TournamentRegistration, TournamentValidatorConfig, ZkPassportValidatorConfig, bigintToHex, buildEntryFeePrizes, buildExtensionProof, buildNFTProof, buildParticipationMap, buildQualificationProof, buildTournamentExtensionProof, buildWinMap, calculateOpusTrovesEntries, calculatePaidPlaces, calculatePrizeValue, calculateTotalPrizeValueUSD, computeStatus, displayAddress, evaluateExtensionQualification, evaluateQualification, evaluateTokenQualification, findAllBannableEntries, findBannableEntries, formatCashToUSD, formatTokenAmount, getExtensionAddresses, getOpusSupportedAssets, getQualifyingModeInfo, getWhitelistedExtensionAddresses, groupPrizesByToken, identifyExtensionType, indexAddress, isBefore, isWhitelistedExtension, padAddress, parseERC20BalanceValidatorConfig, parseExtensionConfig, parseGovernanceValidatorConfig, parseNFTBulkInput, parseOpusTrovesValidatorConfig, parseSnapshotValidatorConfig, parseTournamentValidatorConfig, parseZkPassportValidatorConfig, resolveTournamentQualifications };
499
+ /**
500
+ * Merkle API client for fetching proofs.
501
+ *
502
+ * The merkle validator stores tree data in a separate API service.
503
+ * Each network has its own API instance and database.
504
+ * Proofs are computed on-demand from the stored tree.
505
+ */
506
+ /**
507
+ * Set the merkle API URL for a specific network.
508
+ * Call this at app initialization for each network you want to override.
509
+ * @deprecated Use `createMerkleClient({ chainId, apiUrl })` from `@provable-games/metagame-sdk/merkle` instead.
510
+ */
511
+ declare function setMerkleApiUrl(chainId: string, url: string): void;
512
+ /**
513
+ * Get the merkle API URL for a specific network.
514
+ * Falls back to SN_MAIN if the chain ID is not configured.
515
+ * @deprecated Use `createMerkleClient({ chainId })` from `@provable-games/metagame-sdk/merkle` instead.
516
+ */
517
+ declare function getMerkleApiUrl(chainId?: string): string;
518
+ interface MerkleTree {
519
+ id: number;
520
+ name: string;
521
+ description: string;
522
+ root: string;
523
+ entryCount: number;
524
+ createdAt: string;
525
+ }
526
+ interface MerkleProofResponse {
527
+ address: string;
528
+ count: number;
529
+ proof: string[];
530
+ qualification: string[];
531
+ }
532
+ interface MerkleTreesResponse {
533
+ data: MerkleTree[];
534
+ total: number;
535
+ page: number;
536
+ limit: number;
537
+ totalPages: number;
538
+ }
539
+ /**
540
+ * Fetch merkle trees from the API with pagination.
541
+ *
542
+ * @param options - Optional pagination and network parameters
543
+ * @returns Paginated response with tree metadata, or empty result on error
544
+ * @deprecated Use `MerkleClient.getTrees()` from `@provable-games/metagame-sdk/merkle` instead.
545
+ */
546
+ declare function fetchMerkleTrees(options?: {
547
+ page?: number;
548
+ limit?: number;
549
+ chainId?: string;
550
+ }): Promise<MerkleTreesResponse>;
551
+ interface CreateMerkleTreeRequest {
552
+ id: number;
553
+ name: string;
554
+ description: string;
555
+ entries: Array<{
556
+ address: string;
557
+ count: number;
558
+ }>;
559
+ }
560
+ interface CreateMerkleTreeResponse {
561
+ id: number;
562
+ root: string;
563
+ entryCount: number;
564
+ }
565
+ /**
566
+ * Create a merkle tree in the API.
567
+ *
568
+ * @param request - Tree data including ID (from on-chain), name, description, and entries
569
+ * @param chainId - Optional chain ID to select the correct API
570
+ * @returns The created tree metadata
571
+ * @deprecated Use `MerkleClient.storeTree()` from `@provable-games/metagame-sdk/merkle` instead.
572
+ */
573
+ declare function createMerkleTree(request: CreateMerkleTreeRequest, chainId?: string): Promise<CreateMerkleTreeResponse>;
574
+ interface MerkleTreeEntry {
575
+ address: string;
576
+ count: number;
577
+ }
578
+ interface MerkleTreeEntriesResponse {
579
+ data: MerkleTreeEntry[];
580
+ total: number;
581
+ page: number;
582
+ limit: number;
583
+ totalPages: number;
584
+ }
585
+ /**
586
+ * Fetch entries for a merkle tree from the API with pagination.
587
+ *
588
+ * @param treeId - The on-chain tree ID
589
+ * @param options - Optional pagination and network parameters
590
+ * @returns Paginated response with tree entries, or empty result on error
591
+ * @deprecated Use `MerkleClient.getTreeEntries()` from `@provable-games/metagame-sdk/merkle` instead.
592
+ */
593
+ declare function fetchMerkleTreeEntries(treeId: string | number, options?: {
594
+ page?: number;
595
+ limit?: number;
596
+ chainId?: string;
597
+ }): Promise<MerkleTreeEntriesResponse>;
598
+ /**
599
+ * Fetch a merkle proof for a player address from the API.
600
+ *
601
+ * @param treeId - The on-chain tree ID
602
+ * @param playerAddress - The player's address
603
+ * @param chainId - Optional chain ID to select the correct API
604
+ * @returns The proof data including the qualification array, or null if not found
605
+ * @deprecated Use `MerkleClient.getProof()` from `@provable-games/metagame-sdk/merkle` instead.
606
+ */
607
+ declare function fetchMerkleProof(treeId: string | number, playerAddress: string, chainId?: string): Promise<MerkleProofResponse | null>;
608
+
609
+ export { type CreateMerkleTreeRequest, type CreateMerkleTreeResponse, type Distribution, ERC20BalanceValidatorConfig, type EntryFee, type EntryFeeConfig, type EntryRequirement, EntryRequirementVariant, ExtensionAddresses, type ExtensionQualificationInput, ExtensionType, GovernanceValidatorConfig, type GroupedTokenPrize, type MerkleProofResponse, type MerkleTree, type MerkleTreeEntriesResponse, type MerkleTreeEntry, type MerkleTreesResponse, MerkleValidatorConfig, type NftParseResult, type NftPrizeInput, OpusTrovesValidatorConfig, Prize, QualificationProof, QualificationResult, QualifyingModeInfo, SnapshotValidatorConfig, StatusResult, StatusTimestamps, type TokenDecimalsLookup, type TokenPriceLookup, type TokenQualificationInput, type TournamentLeaderboard, type TournamentQualificationInput, type TournamentRegistration, TournamentValidatorConfig, ZkPassportValidatorConfig, bigintToHex, buildEntryFeePrizes, buildExtensionProof, buildNFTProof, buildParticipationMap, buildQualificationProof, buildTournamentExtensionProof, buildWinMap, calculateOpusTrovesEntries, calculatePaidPlaces, calculatePrizeValue, calculateTotalPrizeValueUSD, computeStatus, createMerkleTree, displayAddress, evaluateExtensionQualification, evaluateQualification, evaluateTokenQualification, fetchMerkleProof, fetchMerkleTreeEntries, fetchMerkleTrees, findAllBannableEntries, findBannableEntries, formatCashToUSD, formatTokenAmount, getExtensionAddresses, getMerkleApiUrl, getOpusSupportedAssets, getQualifyingModeInfo, getWhitelistedExtensionAddresses, groupPrizesByToken, identifyExtensionType, indexAddress, isBefore, isWhitelistedExtension, padAddress, parseERC20BalanceValidatorConfig, parseExtensionConfig, parseGovernanceValidatorConfig, parseMerkleValidatorConfig, parseNFTBulkInput, parseOpusTrovesValidatorConfig, parseSnapshotValidatorConfig, parseTournamentValidatorConfig, parseZkPassportValidatorConfig, resolveTournamentQualifications, setMerkleApiUrl };
package/dist/index.js CHANGED
@@ -1,4 +1,5 @@
1
- import { CairoOption, CairoOptionVariant, CairoCustomEnum } from 'starknet';
1
+ import { CairoOption, CairoOptionVariant, CairoCustomEnum, hash } from 'starknet';
2
+ import { StandardMerkleTree } from '@ericnordelo/strk-merkle-tree';
2
3
 
3
4
  // src/types/extensions.ts
4
5
  var QualifyingMode = /* @__PURE__ */ ((QualifyingMode2) => {
@@ -475,12 +476,13 @@ function parseKeyValueFormat(input) {
475
476
  // src/utils/extensions.ts
476
477
  var EXTENSION_ADDRESSES = {
477
478
  SN_SEPOLIA: {
478
- tournamentValidator: "0x04c9ba290bbebd47f87141801623748884af610230cdaf69232007b4135be3f1",
479
- erc20BalanceValidator: "0x05437210fd8231893da2317971983ae1f810d8d500344ad09e5b258b5820a908",
479
+ tournamentValidator: "0x07eade45e4317b1a036e3a8123bb1f95215d37a6f6b0cea25cdd48030a932dfc",
480
+ erc20BalanceValidator: "0x028112199f873e919963277b41ef1231365986e2fd7722501cd7d293de60b64e",
480
481
  opusTrovesValidator: "0x0317f96eeff41d1badffd9bda126d36c1806523d8c91a5b440f9bdf2aa2b9fe7",
481
- snapshotValidator: "0x02628045f0688663ecacbaefdbbc46c2e315b2da39271419e8a3443fe4120f61",
482
+ snapshotValidator: "0x05520239f16dc58c5dfdccb1f0480977e7fea18d4305e64f5eae88ae786a22fe",
482
483
  zkPassportValidator: "0x025b65137c5297e03491830635f4c5d76eb17e5b2db3bf49dbee34bba94ad3e6",
483
- governanceValidator: "0x0585e6b1aa8daac7711004a92a8d0d3b5a81eaac8c9a07db24fc34b1a4f2322c"
484
+ governanceValidator: "0x0585e6b1aa8daac7711004a92a8d0d3b5a81eaac8c9a07db24fc34b1a4f2322c",
485
+ merkleValidator: "0x07a5b716c65ac5726ecd0b023ff1b4cc9090820707a508b49f5ed42e44a401c4"
484
486
  },
485
487
  SN_MAIN: {
486
488
  tournamentValidator: "0x0771b57c0709fc4407ff8b63d573f302b96fb03638364032fad734e3c310b9e0",
@@ -488,7 +490,9 @@ var EXTENSION_ADDRESSES = {
488
490
  opusTrovesValidator: "0x0604bc0d54727f439786c65d7dc6f7d46de1aba7e129ef9caf65fef111a1644e",
489
491
  snapshotValidator: "0x03e6820e9e1cfb5c22465a86f469c651355f05397e29fc94de8e832d5f3d8ede",
490
492
  zkPassportValidator: "0x01a25f04c8a39da7bb37adcc53d595fde9e60702611d15b1c498df0657001479",
491
- governanceValidator: ""
493
+ governanceValidator: "",
494
+ // placeholder until deployed
495
+ merkleValidator: ""
492
496
  // placeholder until deployed
493
497
  }
494
498
  };
@@ -553,6 +557,9 @@ function identifyExtensionType(extensionAddress, chainId) {
553
557
  if (addresses.governanceValidator && normalizeAddr(addresses.governanceValidator) === normalized) {
554
558
  return "governance";
555
559
  }
560
+ if (addresses.merkleValidator && normalizeAddr(addresses.merkleValidator) === normalized) {
561
+ return "merkle";
562
+ }
556
563
  return "unknown";
557
564
  }
558
565
  function parseTournamentValidatorConfig(config) {
@@ -623,6 +630,12 @@ function parseGovernanceValidatorConfig(config) {
623
630
  votesPerEntry: BigInt(config[10]) << 128n | BigInt(config[9])
624
631
  };
625
632
  }
633
+ function parseMerkleValidatorConfig(config) {
634
+ if (!config || config.length === 0) return null;
635
+ return {
636
+ treeId: String(Number(BigInt(config[0] ?? "0")))
637
+ };
638
+ }
626
639
  function parseExtensionConfig(extensionAddress, config, chainId) {
627
640
  const extensionType = identifyExtensionType(extensionAddress, chainId);
628
641
  switch (extensionType) {
@@ -650,6 +663,10 @@ function parseExtensionConfig(extensionAddress, config, chainId) {
650
663
  const parsed = parseGovernanceValidatorConfig(config);
651
664
  return parsed ? { type: "governance", config: parsed } : null;
652
665
  }
666
+ case "merkle": {
667
+ const parsed = parseMerkleValidatorConfig(config);
668
+ return parsed ? { type: "merkle", config: parsed } : null;
669
+ }
653
670
  default:
654
671
  return { type: "unknown", config: null };
655
672
  }
@@ -1010,6 +1027,284 @@ function calculatePaidPlaces(sponsoredPrizes, entryFeeDistributionCount) {
1010
1027
  return Math.max(maxSponsoredPosition, entryFeeDistributionCount);
1011
1028
  }
1012
1029
 
1013
- export { QualifyingMode, aggregatePrizesByPosition, aggregatePrizesBySponsor, bigintToHex, buildEntryFeePrizes, buildExtensionProof, buildNFTProof, buildParticipationMap, buildQualificationProof, buildTournamentExtensionProof, buildWinMap, calculateDistribution, calculateEntryFeeBreakdown, calculateOpusTrovesEntries, calculatePaidPlaces, calculatePayouts, calculatePrizeValue, calculateTotalPrizeValueUSD, computeStatus, displayAddress, distributePool, evaluateExtensionQualification, evaluateQualification, evaluateTokenQualification, filterClaimablePrizes, filterZeroPrizes, findAllBannableEntries, findBannableEntries, formatCashToUSD, formatNumber, formatPrizeAmount, formatScore, formatTime, formatTokenAmount, formatUsdValue, getExtensionAddresses, getOpusSupportedAssets, getOrdinalSuffix, getQualifyingModeInfo, getWhitelistedExtensionAddresses, groupPrizesByToken, identifyExtensionType, indexAddress, isBefore, isWhitelistedExtension, padAddress, parseERC20BalanceValidatorConfig, parseExtensionConfig, parseGovernanceValidatorConfig, parseNFTBulkInput, parseOpusTrovesValidatorConfig, parseSnapshotValidatorConfig, parseTournamentValidatorConfig, parseZkPassportValidatorConfig, resolveTournamentQualifications };
1030
+ // src/utils/merkleApi.ts
1031
+ var DEFAULT_MERKLE_API_URLS = {
1032
+ SN_SEPOLIA: "https://merkle-api-sepolia.up.railway.app",
1033
+ SN_MAIN: "https://merkle-api.up.railway.app"
1034
+ };
1035
+ var merkleApiUrls = { ...DEFAULT_MERKLE_API_URLS };
1036
+ function setMerkleApiUrl(chainId, url) {
1037
+ merkleApiUrls[chainId] = url;
1038
+ }
1039
+ function getMerkleApiUrl(chainId) {
1040
+ if (chainId && merkleApiUrls[chainId]) {
1041
+ return merkleApiUrls[chainId];
1042
+ }
1043
+ return merkleApiUrls.SN_MAIN ?? DEFAULT_MERKLE_API_URLS.SN_MAIN;
1044
+ }
1045
+ async function fetchMerkleTrees(options) {
1046
+ const empty = {
1047
+ data: [],
1048
+ total: 0,
1049
+ page: 1,
1050
+ limit: 20,
1051
+ totalPages: 0
1052
+ };
1053
+ try {
1054
+ const baseUrl = getMerkleApiUrl(options?.chainId);
1055
+ const params = new URLSearchParams();
1056
+ if (options?.page) params.set("page", String(options.page));
1057
+ if (options?.limit) params.set("limit", String(options.limit));
1058
+ const qs = params.toString();
1059
+ const res = await fetch(`${baseUrl}/trees${qs ? `?${qs}` : ""}`);
1060
+ if (!res.ok) return empty;
1061
+ const json = await res.json();
1062
+ return {
1063
+ data: json.data ?? [],
1064
+ total: json.total ?? 0,
1065
+ page: json.page ?? 1,
1066
+ limit: json.limit ?? 20,
1067
+ totalPages: json.totalPages ?? 0
1068
+ };
1069
+ } catch {
1070
+ return empty;
1071
+ }
1072
+ }
1073
+ async function createMerkleTree(request, chainId) {
1074
+ const baseUrl = getMerkleApiUrl(chainId);
1075
+ const res = await fetch(`${baseUrl}/trees`, {
1076
+ method: "POST",
1077
+ headers: { "Content-Type": "application/json" },
1078
+ body: JSON.stringify(request)
1079
+ });
1080
+ if (!res.ok) {
1081
+ const text = await res.text();
1082
+ throw new Error(`Failed to create merkle tree: ${text}`);
1083
+ }
1084
+ return await res.json();
1085
+ }
1086
+ async function fetchMerkleTreeEntries(treeId, options) {
1087
+ const empty = {
1088
+ data: [],
1089
+ total: 0,
1090
+ page: 1,
1091
+ limit: 50,
1092
+ totalPages: 0
1093
+ };
1094
+ try {
1095
+ const baseUrl = getMerkleApiUrl(options?.chainId);
1096
+ const params = new URLSearchParams();
1097
+ if (options?.page) params.set("page", String(options.page));
1098
+ if (options?.limit) params.set("limit", String(options.limit));
1099
+ const qs = params.toString();
1100
+ const res = await fetch(
1101
+ `${baseUrl}/trees/${treeId}/entries${qs ? `?${qs}` : ""}`
1102
+ );
1103
+ if (!res.ok) return empty;
1104
+ const json = await res.json();
1105
+ return {
1106
+ data: json.data ?? [],
1107
+ total: json.total ?? 0,
1108
+ page: json.page ?? 1,
1109
+ limit: json.limit ?? 50,
1110
+ totalPages: json.totalPages ?? 0
1111
+ };
1112
+ } catch {
1113
+ return empty;
1114
+ }
1115
+ }
1116
+ async function fetchMerkleProof(treeId, playerAddress, chainId) {
1117
+ try {
1118
+ const baseUrl = getMerkleApiUrl(chainId);
1119
+ const res = await fetch(
1120
+ `${baseUrl}/trees/${treeId}/proof/${playerAddress.toLowerCase()}`
1121
+ );
1122
+ if (!res.ok) return null;
1123
+ return await res.json();
1124
+ } catch {
1125
+ return null;
1126
+ }
1127
+ }
1128
+ function computeLeafValue(address, count) {
1129
+ const intermediate = hash.computePedersenHash("0x0", address);
1130
+ return hash.computePedersenHash(intermediate, "0x" + count.toString(16));
1131
+ }
1132
+ function buildMerkleTree(entries) {
1133
+ if (entries.length === 0) {
1134
+ throw new Error("Cannot build merkle tree with no entries");
1135
+ }
1136
+ const leaves = entries.map((e) => [computeLeafValue(e.address, e.count)]);
1137
+ const tree = StandardMerkleTree.of(leaves, ["felt252"], {
1138
+ sortLeaves: true
1139
+ });
1140
+ return {
1141
+ version: 2,
1142
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
1143
+ entries,
1144
+ root: tree.root,
1145
+ tree: tree.dump()
1146
+ };
1147
+ }
1148
+
1149
+ // src/merkle/client.ts
1150
+ var DEFAULT_MERKLE_API_URLS2 = {
1151
+ SN_SEPOLIA: "https://merkle-api-sepolia.up.railway.app",
1152
+ SN_MAIN: "https://merkle-api.up.railway.app"
1153
+ };
1154
+ var MerkleClient = class {
1155
+ apiUrl;
1156
+ constructor(config) {
1157
+ this.apiUrl = config.apiUrl ?? DEFAULT_MERKLE_API_URLS2[config.chainId] ?? DEFAULT_MERKLE_API_URLS2.SN_MAIN;
1158
+ }
1159
+ /** Fetch paginated list of merkle trees. */
1160
+ async getTrees(options) {
1161
+ const empty = {
1162
+ data: [],
1163
+ total: 0,
1164
+ page: 1,
1165
+ limit: 20,
1166
+ totalPages: 0
1167
+ };
1168
+ try {
1169
+ const params = new URLSearchParams();
1170
+ if (options?.page) params.set("page", String(options.page));
1171
+ if (options?.limit) params.set("limit", String(options.limit));
1172
+ const qs = params.toString();
1173
+ const res = await fetch(`${this.apiUrl}/trees${qs ? `?${qs}` : ""}`);
1174
+ if (!res.ok) return empty;
1175
+ const json = await res.json();
1176
+ return {
1177
+ data: json.data ?? [],
1178
+ total: json.total ?? 0,
1179
+ page: json.page ?? 1,
1180
+ limit: json.limit ?? 20,
1181
+ totalPages: json.totalPages ?? 0
1182
+ };
1183
+ } catch {
1184
+ return empty;
1185
+ }
1186
+ }
1187
+ /** Fetch entries for a specific merkle tree. */
1188
+ async getTreeEntries(treeId, options) {
1189
+ const empty = {
1190
+ data: [],
1191
+ total: 0,
1192
+ page: 1,
1193
+ limit: 50,
1194
+ totalPages: 0
1195
+ };
1196
+ try {
1197
+ const params = new URLSearchParams();
1198
+ if (options?.page) params.set("page", String(options.page));
1199
+ if (options?.limit) params.set("limit", String(options.limit));
1200
+ const qs = params.toString();
1201
+ const res = await fetch(
1202
+ `${this.apiUrl}/trees/${treeId}/entries${qs ? `?${qs}` : ""}`
1203
+ );
1204
+ if (!res.ok) return empty;
1205
+ const json = await res.json();
1206
+ return {
1207
+ data: json.data ?? [],
1208
+ total: json.total ?? 0,
1209
+ page: json.page ?? 1,
1210
+ limit: json.limit ?? 50,
1211
+ totalPages: json.totalPages ?? 0
1212
+ };
1213
+ } catch {
1214
+ return empty;
1215
+ }
1216
+ }
1217
+ /** Fetch a merkle proof for a player address. */
1218
+ async getProof(treeId, playerAddress) {
1219
+ try {
1220
+ const res = await fetch(
1221
+ `${this.apiUrl}/trees/${treeId}/proof/${playerAddress.toLowerCase()}`
1222
+ );
1223
+ if (!res.ok) return null;
1224
+ return await res.json();
1225
+ } catch {
1226
+ return null;
1227
+ }
1228
+ }
1229
+ /** Store a merkle tree in the API (after on-chain registration). */
1230
+ async storeTree(request) {
1231
+ const res = await fetch(`${this.apiUrl}/trees`, {
1232
+ method: "POST",
1233
+ headers: { "Content-Type": "application/json" },
1234
+ body: JSON.stringify(request)
1235
+ });
1236
+ if (!res.ok) {
1237
+ const text = await res.text();
1238
+ throw new Error(`Failed to create merkle tree: ${text}`);
1239
+ }
1240
+ return await res.json();
1241
+ }
1242
+ /**
1243
+ * Build a merkle tree locally and return the calldata needed
1244
+ * to register it on-chain via the validator contract.
1245
+ *
1246
+ * The consumer is responsible for executing the call with their
1247
+ * own account/signer.
1248
+ */
1249
+ buildTreeCalldata(entries, validatorAddress) {
1250
+ const tree = buildMerkleTree(entries);
1251
+ return {
1252
+ tree,
1253
+ call: {
1254
+ contractAddress: validatorAddress,
1255
+ entrypoint: "create_tree",
1256
+ calldata: [tree.root]
1257
+ }
1258
+ };
1259
+ }
1260
+ /**
1261
+ * Parse the tree ID from transaction receipt events.
1262
+ * Returns null if the event cannot be found.
1263
+ */
1264
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1265
+ parseTreeIdFromEvents(events, validatorAddress) {
1266
+ const validatorBigInt = BigInt(validatorAddress);
1267
+ const treeEvent = events.find((e) => {
1268
+ try {
1269
+ return BigInt(e.from_address) === validatorBigInt;
1270
+ } catch {
1271
+ return false;
1272
+ }
1273
+ });
1274
+ if (!treeEvent?.keys?.[1]) return null;
1275
+ return Number(BigInt(treeEvent.keys[1]));
1276
+ }
1277
+ /**
1278
+ * Store the tree in the API after on-chain registration.
1279
+ * Pass the tree ID from the on-chain event along with the original entries.
1280
+ */
1281
+ async createTree(params) {
1282
+ return this.storeTree({
1283
+ id: params.treeId,
1284
+ name: params.name,
1285
+ description: params.description,
1286
+ entries: params.entries
1287
+ });
1288
+ }
1289
+ };
1290
+
1291
+ // src/client.ts
1292
+ var MetagameClient = class {
1293
+ chainId;
1294
+ merkle;
1295
+ constructor(config) {
1296
+ this.chainId = config.chainId;
1297
+ const merkleConfig = {
1298
+ chainId: config.chainId,
1299
+ apiUrl: config.merkleApiUrl
1300
+ };
1301
+ this.merkle = new MerkleClient(merkleConfig);
1302
+ }
1303
+ };
1304
+ function createMetagameClient(config) {
1305
+ return new MetagameClient(config);
1306
+ }
1307
+
1308
+ export { MetagameClient, QualifyingMode, aggregatePrizesByPosition, aggregatePrizesBySponsor, bigintToHex, buildEntryFeePrizes, buildExtensionProof, buildNFTProof, buildParticipationMap, buildQualificationProof, buildTournamentExtensionProof, buildWinMap, calculateDistribution, calculateEntryFeeBreakdown, calculateOpusTrovesEntries, calculatePaidPlaces, calculatePayouts, calculatePrizeValue, calculateTotalPrizeValueUSD, computeStatus, createMerkleTree, createMetagameClient, displayAddress, distributePool, evaluateExtensionQualification, evaluateQualification, evaluateTokenQualification, fetchMerkleProof, fetchMerkleTreeEntries, fetchMerkleTrees, filterClaimablePrizes, filterZeroPrizes, findAllBannableEntries, findBannableEntries, formatCashToUSD, formatNumber, formatPrizeAmount, formatScore, formatTime, formatTokenAmount, formatUsdValue, getExtensionAddresses, getMerkleApiUrl, getOpusSupportedAssets, getOrdinalSuffix, getQualifyingModeInfo, getWhitelistedExtensionAddresses, groupPrizesByToken, identifyExtensionType, indexAddress, isBefore, isWhitelistedExtension, padAddress, parseERC20BalanceValidatorConfig, parseExtensionConfig, parseGovernanceValidatorConfig, parseMerkleValidatorConfig, parseNFTBulkInput, parseOpusTrovesValidatorConfig, parseSnapshotValidatorConfig, parseTournamentValidatorConfig, parseZkPassportValidatorConfig, resolveTournamentQualifications, setMerkleApiUrl };
1014
1309
  //# sourceMappingURL=index.js.map
1015
1310
  //# sourceMappingURL=index.js.map