Personal Data Monetization Vault

What it does:
Allows users to securely store, manage, and monetize their personal data, granting access to third parties in exchange for tokens or payments.

Why it matters:
Gives individuals control over their personal data, enables fair compensation for data usage, eliminates intermediaries, and ensures privacy and transparency.

How it works:

  • Users deposit personal data metadata (encrypted or hashed) into the vault

  • Access permissions are granted to data consumers via smart contracts

  • Payments are automatically distributed to the user based on access or usage

  • Supports subscription-based access, one-time purchases, or usage-based fees

  • Integrates with Creator Subscription Wallet, AI Agent Payment Contract, or Play-to-Earn Reward Engine

  • Dashboards show data usage, payment history, and granted permissions

  • Data access can be revoked at any time while ensuring auditability

      // SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

import "@openzeppelin/contracts/access/Ownable.sol";

/**
 * @title PersonalDataVault
 * @author Nam
 * @notice Manages personal data access and monetization on-chain
 */
contract PersonalDataVault is Ownable {

    struct DataEntry {
        string metadataHash; // IPFS or encrypted reference
        address payable owner;
        uint256 accessFee; // in wei
        mapping(address => bool) accessGranted; // data consumer => granted
    }

    mapping(uint256 => DataEntry) public dataEntries;
    uint256 public dataCount;

    // -------------------- EVENTS --------------------

    event DataRegistered(uint256 indexed dataId, address owner, uint256 accessFee);
    event AccessGranted(uint256 indexed dataId, address consumer, uint256 payment);
    event AccessRevoked(uint256 indexed dataId, address consumer);

    // -------------------- DATA MANAGEMENT --------------------

    function registerData(string calldata _metadataHash, uint256 _accessFee) external {
        require(_accessFee > 0, "Fee must be >0");

        dataCount += 1;
        DataEntry storage d = dataEntries[dataCount];
        d.metadataHash = _metadataHash;
        d.owner = payable(msg.sender);
        d.accessFee = _accessFee;

        emit DataRegistered(dataCount, msg.sender, _accessFee);
    }

    function grantAccess(uint256 _dataId) external payable {
        DataEntry storage d = dataEntries[_dataId];
        require(msg.value == d.accessFee, "Incorrect payment");
        require(!d.accessGranted[msg.sender], "Access already granted");

        d.accessGranted[msg.sender] = true;
        d.owner.transfer(msg.value);

        emit AccessGranted(_dataId, msg.sender, msg.value);
    }

    function revokeAccess(uint256 _dataId, address _consumer) external {
        DataEntry storage d = dataEntries[_dataId];
        require(msg.sender == d.owner, "Not owner");

        d.accessGranted[_consumer] = false;
        emit AccessRevoked(_dataId, _consumer);
    }

    // -------------------- VIEW FUNCTIONS --------------------

    function hasAccess(uint256 _dataId, address _user) external view returns (bool) {
        return dataEntries[_dataId].accessGranted[_user];
    }

    function getDataMetadata(uint256 _dataId) external view returns (string memory) {
        return dataEntries[_dataId].metadataHash;
    }
}