PRIV ProtocolPRIV Docs
Contracts

DataWalletMarketplace

Marketplace for purchasing Data Wallet content including photos, videos, and voice recordings.

DataWalletMarketplace

The DataWalletMarketplace contract enables AI companies and data buyers to purchase user-contributed media content (photos, videos, voice recordings) from the Data Wallet feature.


Overview

Key Features

  • 3% protocol fee on all transactions (sent to FeeManager)
  • Multiple data types - Photos, videos, voice, text, mixed
  • License types - Single use, limited, unlimited, exclusive
  • Bulk purchases - Buy multiple items at once
  • Contributor earnings - 97% goes directly to data contributors

Fee Distribution

Purchase Amount (100 PRIV)
├── 97% to Contributor (97 PRIV)
└── 3% Protocol Fee (3 PRIV) → FeeManagerV2
    ├── 40% Burned (1.2 PRIV)
    ├── 35% to Stakers (1.05 PRIV)
    └── 25% to Treasury (0.75 PRIV)

Data Types

enum DataType {
    Photo,    // Images, selfies, scenes
    Video,    // Video clips, recordings
    Voice,    // Audio recordings, voice samples
    Text,     // Text data, chat exports
    Mixed     // Combined dataset
}

License Types

LicenseDescriptionEffect
SingleUseOne-time use for specific projectData remains available
LimitedLimited number of usesData remains available
UnlimitedUnlimited commercial useData remains available
ExclusiveExclusive rightsListing deactivated after purchase

Exclusive licenses remove the data from the marketplace after purchase.


Constants

ConstantValueDescription
PROTOCOL_FEE_BPS300 (3%)Protocol fee percentage
BPS_DENOMINATOR10000Basis points denominator
MIN_PRICE_PER_ITEM0.01 PRIVMinimum price per item
MAX_ITEMS_PER_LISTING10,000Maximum items per listing
TREASURY_UPDATE_DELAY2 daysTimelock for treasury changes

Functions

Listing Management

createListing

Creates a new data listing.

function createListing(
    uint256 pricePerItem,
    uint256 itemCount,
    bytes32 metadataHash,
    DataType dataType,
    LicenseType licenseType
) external whenNotPaused returns (uint256 listingId)

Parameters:

  • pricePerItem - Price per data item in PRIV (min 0.01 PRIV)
  • itemCount - Number of items (1 to 10,000)
  • metadataHash - IPFS hash of listing metadata
  • dataType - Type of data (Photo, Video, Voice, Text, Mixed)
  • licenseType - License terms

Returns: The created listing ID

Events:

event ListingCreated(
    uint256 indexed listingId,
    address indexed contributor,
    uint256 pricePerItem,
    uint256 itemCount,
    DataType dataType,
    LicenseType licenseType,
    bytes32 metadataHash
);

updateListing

Updates a listing's price and metadata.

function updateListing(
    uint256 listingId,
    uint256 newPricePerItem,
    bytes32 newMetadataHash
) external whenNotPaused

addItems

Adds more items to an existing listing.

function addItems(uint256 listingId, uint256 additionalItems) external whenNotPaused

deactivateListing / reactivateListing

Toggle listing availability.

function deactivateListing(uint256 listingId) external
function reactivateListing(uint256 listingId) external whenNotPaused

Purchasing

purchaseData

Purchases data items from a listing.

function purchaseData(
    uint256 listingId,
    uint256 itemCount
) external nonReentrant whenNotPaused returns (uint256 purchaseId, bytes32 accessToken)

Parameters:

  • listingId - The listing to purchase from
  • itemCount - Number of items to purchase

Returns:

  • purchaseId - Unique purchase record ID
  • accessToken - Token for accessing purchased data

Requirements:

  • Listing must be active
  • Cannot purchase own listing
  • Sufficient items available
  • Buyer must have approved PRIV transfer

Events:

event DataPurchased(
    uint256 indexed purchaseId,
    uint256 indexed listingId,
    address indexed buyer,
    address contributor,
    uint256 itemsPurchased,
    uint256 totalPaid,
    uint256 contributorShare,
    uint256 protocolFee,
    bytes32 accessToken
);

purchaseAllItems

Purchases all remaining items from a listing.

function purchaseAllItems(
    uint256 listingId
) external nonReentrant whenNotPaused returns (uint256 purchaseId, bytes32 accessToken)

View Functions

getListing

Returns full listing details.

function getListing(uint256 listingId) external view returns (Listing memory)

Listing Struct:

struct Listing {
    address contributor;
    uint256 pricePerItem;
    uint256 itemCount;
    uint256 availableItems;
    bytes32 metadataHash;
    DataType dataType;
    LicenseType licenseType;
    bool active;
    uint256 totalRevenue;
    uint256 totalPurchases;
    uint256 createdAt;
    uint256 updatedAt;
}

getPurchase

Returns full purchase details.

function getPurchase(uint256 purchaseId) external view returns (Purchase memory)

Purchase Struct:

struct Purchase {
    address buyer;
    uint256 listingId;
    uint256 itemsPurchased;
    uint256 totalPaid;
    uint256 contributorShare;
    uint256 protocolFee;
    bytes32 accessToken;
    LicenseType licenseType;
    uint256 purchasedAt;
}

calculatePurchasePrice

Preview purchase cost breakdown.

function calculatePurchasePrice(
    uint256 listingId,
    uint256 itemCount
) external view returns (
    uint256 totalPrice,
    uint256 protocolFee,
    uint256 contributorShare
)

getContributorStats

Get contributor statistics.

function getContributorStats(address contributor) external view returns (
    uint256 listingCount,
    uint256 totalEarnings
)

getMarketplaceStats

Get marketplace-wide statistics.

function getMarketplaceStats() external view returns (
    uint256 _totalListings,
    uint256 _totalPurchases,
    uint256 _totalProtocolFees,
    uint256 _totalContributorEarnings
)

Admin Functions

setFeeManager

Sets the FeeManager contract address.

function setFeeManager(address _feeManager) external onlyOwner

Treasury Management (with Timelock)

function proposeTreasuryUpdate(address newTreasury) external onlyOwner
function executeTreasuryUpdate() external onlyOwner
function cancelTreasuryUpdate() external onlyOwner

Treasury updates require a 2-day timelock for security.


Integration Example

Creating a Listing

import { ethers } from 'ethers';

const marketplace = new ethers.Contract(address, abi, signer);

// Create a photo listing
const tx = await marketplace.createListing(
  ethers.parseEther('0.05'),    // 0.05 PRIV per item
  100,                           // 100 items
  '0x...',                       // IPFS metadata hash
  0,                             // DataType.Photo
  2                              // LicenseType.Unlimited
);

const receipt = await tx.wait();
const listingId = receipt.logs[0].args.listingId;

Purchasing Data

// Approve PRIV transfer
const priv = new ethers.Contract(privTokenAddress, erc20Abi, signer);
const price = await marketplace.calculatePurchasePrice(listingId, 10);
await priv.approve(marketplace.address, price.totalPrice);

// Purchase 10 items
const tx = await marketplace.purchaseData(listingId, 10);
const receipt = await tx.wait();

const { purchaseId, accessToken } = receipt.logs[0].args;
console.log('Access token:', accessToken);

Querying Listings

// Get listing details
const listing = await marketplace.getListing(listingId);
console.log('Price per item:', ethers.formatEther(listing.pricePerItem));
console.log('Available:', listing.availableItems);

// Get contributor stats
const stats = await marketplace.getContributorStats(contributorAddress);
console.log('Total earnings:', ethers.formatEther(stats.totalEarnings));

Security Features

FeatureDescription
ReentrancyGuardProtection against reentrancy attacks
PausableEmergency pause functionality
Treasury Timelock2-day delay for treasury changes
SafeERC20Safe token transfer handling
Access ControlOnly contributors can manage their listings

Events Reference

EventDescription
ListingCreatedNew listing created
ListingUpdatedListing price/metadata updated
ItemsAddedItems added to listing
ListingDeactivatedListing deactivated
ListingReactivatedListing reactivated
DataPurchasedData purchased from listing
TreasuryUpdateProposedTreasury change proposed
TreasuryUpdateExecutedTreasury change executed
FeeManagerUpdatedFeeManager address changed