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
| License | Description | Effect |
|---|---|---|
SingleUse | One-time use for specific project | Data remains available |
Limited | Limited number of uses | Data remains available |
Unlimited | Unlimited commercial use | Data remains available |
Exclusive | Exclusive rights | Listing deactivated after purchase |
Exclusive licenses remove the data from the marketplace after purchase.
Constants
| Constant | Value | Description |
|---|---|---|
PROTOCOL_FEE_BPS | 300 (3%) | Protocol fee percentage |
BPS_DENOMINATOR | 10000 | Basis points denominator |
MIN_PRICE_PER_ITEM | 0.01 PRIV | Minimum price per item |
MAX_ITEMS_PER_LISTING | 10,000 | Maximum items per listing |
TREASURY_UPDATE_DELAY | 2 days | Timelock 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 metadatadataType- 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 whenNotPausedaddItems
Adds more items to an existing listing.
function addItems(uint256 listingId, uint256 additionalItems) external whenNotPauseddeactivateListing / reactivateListing
Toggle listing availability.
function deactivateListing(uint256 listingId) external
function reactivateListing(uint256 listingId) external whenNotPausedPurchasing
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 fromitemCount- Number of items to purchase
Returns:
purchaseId- Unique purchase record IDaccessToken- 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 onlyOwnerTreasury Management (with Timelock)
function proposeTreasuryUpdate(address newTreasury) external onlyOwner
function executeTreasuryUpdate() external onlyOwner
function cancelTreasuryUpdate() external onlyOwnerTreasury 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
| Feature | Description |
|---|---|
| ReentrancyGuard | Protection against reentrancy attacks |
| Pausable | Emergency pause functionality |
| Treasury Timelock | 2-day delay for treasury changes |
| SafeERC20 | Safe token transfer handling |
| Access Control | Only contributors can manage their listings |
Events Reference
| Event | Description |
|---|---|
ListingCreated | New listing created |
ListingUpdated | Listing price/metadata updated |
ItemsAdded | Items added to listing |
ListingDeactivated | Listing deactivated |
ListingReactivated | Listing reactivated |
DataPurchased | Data purchased from listing |
TreasuryUpdateProposed | Treasury change proposed |
TreasuryUpdateExecuted | Treasury change executed |
FeeManagerUpdated | FeeManager address changed |