> ## Documentation Index
> Fetch the complete documentation index at: https://docs.vibechain.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Developer Documentation

Build on vibe.market's smart contracts to create your own integrations, trading bots, or applications for digital collectibles.

## Smart Contract Addresses

All vibe.market contracts are deployed on Base. Each booster pack collection has its own contract addresses for the LTC (Liquid Trading Card) (BoosterDropV2) and token (BoosterTokenV2).

**Source availability**: The core vibe.market booster contracts are now source-available in [`wieldlabs/contracts`](https://github.com/wieldlabs/contracts/tree/main/vibemarket). This includes `BoosterDropV2`, `BoosterTokenV2`, `BoosterDeployerFactoryV2`, `BoosterBondingCurveV2`, `BoosterCardSeedUtils`, and the canonical interfaces under the licenses in each source file.

We also continue to run security scanning via [Almanax](https://www.almanax.ai/).

<Card title="Contract Interfaces" icon="code" href="/docs/vibemarket/developers/interfaces">
  View the complete smart contract interfaces
</Card>

<Card title="Source-Available Contracts" icon="code" href="https://github.com/wieldlabs/contracts/tree/main/vibemarket">
  View the canonical vibe.market contract sources on GitHub
</Card>

## Common Use Cases

### 1. Buying Booster Packs

Purchase digital collectible booster packs programmatically and earn referral fees.

```javascript theme={null}
// Using ethers.js v6
import { ethers } from "ethers";

// Connect to provider
const provider = new ethers.JsonRpcProvider("https://base.llamarpc.com");
const signer = new ethers.Wallet(PRIVATE_KEY, provider);

// BoosterDropV2 contract
const boosterDrop = new ethers.Contract(
  BOOSTER_DROP_ADDRESS,
  IBoosterDropV2_ABI,
  signer
);

// Get mint price for packs (example: 5 packs)
const mintPrice = await boosterDrop.getMintPrice(5);

// Mint packs with referral (earn fees!)
await boosterDrop.mint(
  5, // amount of packs
  signer.address, // recipient
  YOUR_ADDRESS, // referrer (example: earn portion of fees)
  YOUR_ADDRESS, // originReferrer (example: earn additional portion)
  { value: mintPrice } // ETH payment
);
```

### 2. Selling Tickets (Tokens)

Trade collectible tokens through the bonding curve or Uniswap pool.

```javascript theme={null}
// BoosterTokenV2 contract
const boosterToken = new ethers.Contract(
  BOOSTER_TOKEN_ADDRESS,
  IBoosterTokenV2_ABI,
  signer
);

// Check current market type
const marketType = await boosterToken.marketType();
// 0 = BONDING_CURVE, 1 = UNISWAP_POOL

// Get sell quote for tokens (example: 100,000 tokens)
const tokenAmount = ethers.parseUnits("100000", 18);
const ethReceived = await boosterToken.getTokenSellQuote(tokenAmount);

// Sell tokens with slippage protection
const minPayout = (ethReceived * 98n) / 100n; // Example: 2% slippage
await boosterToken.sell(
  tokenAmount,
  signer.address, // recipient of ETH
  minPayout, // minimum ETH to accept
  YOUR_ADDRESS, // referrer
  YOUR_ADDRESS // originReferrer
);
```

### 3. Opening Packs and Getting Randomness

Open packs to reveal rarity using [Pyth Network](https://www.pyth.network/) entropy.

```javascript theme={null}
// Get entropy fee required for opening
const entropyFee = await boosterDrop.getEntropyFee();

// Open multiple packs (requires ETH for entropy)
const tokenIds = [1, 2, 3]; // Your unopened pack token IDs
await boosterDrop.open(tokenIds, { value: entropyFee });

// Get rarity info after randomness is fulfilled
const rarityInfo = await boosterDrop.getTokenRarity(tokenIds[0]);
console.log({
  rarity: rarityInfo.rarity, // 1=Common, 2=Rare, 3=Epic, 4=Legendary, 5=Mythic
  randomValue: rarityInfo.randomValue,
  randomness: rarityInfo.tokenSpecificRandomness,
});
```

### 4. Selling LTCs (Liquid Trading Cards) for Token Offers

Sell both opened and unopened packs back to the contract.

```javascript theme={null}
// Sell single LTC (Liquid Trading Card) (opened or unopened)
await boosterDrop.sellAndClaimOffer(tokenId);

// Batch sell multiple LTCs (Liquid Trading Cards)
const tokenIds = [1, 2, 3];
await boosterDrop.sellAndClaimOfferBatch(tokenIds);

// Exchange values are examples only - actual values vary by collection:
// Unopened packs example: 80,000-100,000 tokens (80-100% of mint cost) [100% for packs created after August 1st, 2025]
// Opened packs examples based on rarity:
// - Common: 20,000 tokens (example)
// - Rare: 120,000 tokens (example)
// - Epic: 420,000 tokens (example)
// - Legendary: 3,000,000 tokens (example)
// - Mythic: 10,000,000 tokens (example)
// Note: This optional exchange feature may not be available for all collections
```

### 5. Reading Onchain Data

Access all card data directly from the blockchain.

```javascript theme={null}
// Check if pack is opened by getting rarity
try {
  const rarityInfo = await boosterDrop.getTokenRarity(tokenId);
  console.log("Pack is opened, rarity:", rarityInfo.rarity);
} catch {
  console.log("Pack is unopened");
}

// Track mint events
const mintFilter = boosterDrop.filters.BoosterDropsMinted();
const mintEvents = await boosterDrop.queryFilter(mintFilter);

// Track pack openings
const openFilter = boosterDrop.filters.BoosterDropOpened();
const openEvents = await boosterDrop.queryFilter(openFilter);

// Get token metadata URI
const tokenURI = await boosterDrop.tokenURI(tokenId);
```

### 6. Building Games with vibe.market Cards

```javascript theme={null}
// Track user's cards via transfer events
const userAddress = "0x...";
const transferFilter = boosterDrop.filters.BoosterDropTransfer(
  null,
  userAddress
);
const transferEvents = await boosterDrop.queryFilter(transferFilter);

// Get card details including randomness for game mechanics
const userCards = [];
for (const event of transferEvents) {
  const tokenId = event.args.tokenId;

  try {
    const rarityInfo = await boosterDrop.getTokenRarity(tokenId);
    userCards.push({
      tokenId,
      rarity: rarityInfo.rarity,
      randomValue: rarityInfo.randomValue, // Use for game RNG
      randomness: rarityInfo.tokenSpecificRandomness, // Unique per card
      isOpened: true,
    });

    // Use randomness for unique card attributes (example values)
    const uniqueSeed = rarityInfo.randomValue;
    const attackPower = 100 + (uniqueSeed % 50); // Example calculation
    const defense = 80 + (uniqueSeed % 30); // Example calculation
  } catch {
    // Rarity not defined - pack hasn't been opened yet
    userCards.push({
      tokenId,
      rarity: 0,
      isOpened: false,
    });
  }
}

// Grant game benefits based on collection
const legendaryCount = userCards.filter((c) => c.rarity === 4).length;
const mythicCount = userCards.filter((c) => c.rarity === 5).length;
if (mythicCount > 0) {
  // Unlock ultra-rare game features
} else if (legendaryCount > 0) {
  // Unlock special game features
}
```

### 7. Onchain Wear & Foil

We deployed the following source-available contract at [0x002aaaa42354bf8f09f9924977bf0c531933f999](https://basescan.org/address/0x002aaaa42354bf8f09f9924977bf0c531933f999#code)
that allows you to query wear and foil onchain from `getTokenRarity` using `tokenSpecificRandomness`. `0.5%` of cards are standard foil, and `0.05%` of cards are prize foil. Wear is distributed between `0` and `1`.

```javascript theme={null}
// IBoosterCardSeedUtils contract address on Base
const SEED_UTILS_ADDRESS = "0x002aaaa42354bf8f09f9924977bf0c531933f999";

// Connect to the BoosterCardSeedUtils contract
const seedUtils = new ethers.Contract(
  SEED_UTILS_ADDRESS,
  IBoosterCardSeedUtils_ABI,
  provider
);

// Get rarity info from a card (must be opened)
const tokenId = 123; // Your opened pack token ID
const rarityInfo = await boosterDrop.getTokenRarity(tokenId);

// Use tokenSpecificRandomness as the seed for wear & foil
const seed = rarityInfo.tokenSpecificRandomness;

// Get wear value (string with 10 decimal places, e.g., "0.1234567890")
const wear = await seedUtils.wearFromSeed(seed);
console.log("Card wear:", wear);

// Get foil type (returns "Prize", "Standard", or "Normal")
const foilType = await seedUtils.getFoilMappingFromSeed(seed);
console.log("Card foil:", foilType);

// Get both wear and foil in a single call
const cardData = await seedUtils.getCardSeedData(seed);
console.log({
  wear: cardData.wear, // e.g., "0.0123456789"
  foilType: cardData.foilType, // e.g., "Normal", "Standard", or "Prize"
});

// Example: Process multiple cards to get their wear & foil
const userCards = [101, 102, 103]; // Token IDs of opened packs
const cardDetails = [];

for (const tokenId of userCards) {
  try {
    const rarityInfo = await boosterDrop.getTokenRarity(tokenId);
    const [wear, foilType] = await seedUtils.getCardSeedData(
      rarityInfo.tokenSpecificRandomness
    );

    cardDetails.push({
      tokenId,
      rarity: rarityInfo.rarity,
      wear,
      foilType,
      // Use wear for game mechanics
      condition:
        parseFloat(wear) < 0.05
          ? "Pristine"
          : parseFloat(wear) < 0.2
          ? "Mint"
          : parseFloat(wear) < 0.45
          ? "Lightly Played"
          : parseFloat(wear) < 0.75
          ? "Moderately Played"
          : "Heavily Played",
    });
  } catch (error) {
    console.log(`Token ${tokenId} is unopened or invalid`);
  }
}

// Build game features based on foil & wear
const prizeCards = cardDetails.filter((c) => c.foilType === "Prize");
const mintConditionCards = cardDetails.filter((c) => parseFloat(c.wear) < 0.05);
```

### 8. Card Rarity Distribution

Cards in a pack are mapped to specific random value ranges based on their `randomValue`. When a pack is opened, the on-chain randomness generates a value between 0-999,999 returned in `randomValue` from `getTokenRarity()`.

**Example Random Value Mapping:**

```
Random Value Range (0 - 999,999)
├─ Mythic (0 - 199): 0.02%
│  └─ Cards split range evenly (e.g., 5 cards = ~40 values each)
├─ Legendary (200 - 4,699): 0.45%
│  └─ Cards split range evenly (e.g., 10 cards = ~450 values each)
├─ Epic (4,700 - 94,699): 9.0%
│  └─ Cards split range evenly (e.g., 20 cards = ~4,500 values each)
├─ Rare (94,700 - 334,699): 24.0%
│  └─ Cards split range evenly (e.g., 30 cards = ~8,000 values each)
└─ Common (334,700 - 999,999): 66.53%
   └─ Cards split range evenly (e.g., 40 cards = ~16,625 values each)
```

## Important Considerations

**Note**: All numerical values in code examples are for illustration purposes only. Actual values, fees, and percentages are determined by a collection's smart contracts and may vary significantly. These digital collectibles are intended solely for personal enjoyment and entertainment.

* **Gas Optimization**: Batch operations when possible (e.g., opening multiple packs at once)
* **Slippage Protection**: Always use `minPayoutSize` when selling tokens
* **Referral System**: Include referral addresses to earn trading fees (example: 1% of trades, which might be 20% of a 7.5% total fee)
* **Market State**: Check if market is on bonding curve or Uniswap before trading
* **Entropy Fees**: Opening packs requires a small ETH fee for [Pyth Network](https://www.pyth.network/) randomness (example: \~\$0.01)
* **Token Offers**: The optional LTC (Liquid Trading Card) exchange feature mints new tokens when available - this feature is not guaranteed and varies by collection

## Next Steps

* Review the [contract interfaces](/docs/vibemarket/developers/interfaces) for complete method signatures
* Review the [source-available contracts](https://github.com/wieldlabs/contracts/tree/main/vibemarket) for the canonical implementations
* Join our [Discord](https://discord.gg/MfsS9Yfqae) for developer support
