# Reward Metadata

The Rewards Metadata feature allows applications to enrich reward distributions with additional contextual information. This is facilitated through the `distributeRewardWithProofAndMetadata` function, which accepts a JSON-formatted string as metadata. \
\
The provided metadata is then emitted via the `RewardMetadata` event, enabling off-chain services to efficiently index, analyze, and utilize the data for tracking and reporting purposes.

### Suggested Metadata Structure

To maintain consistency across applications, it's recommended to follow a standardized metadata structure. Below is an example of a JSON-formatted metadata string:

```json
{
  "location": {
    "city": "Berlin",
    "country": "Germany",
    "region": "EU"
  },
  "referral_source": "social_media",
  "campaign_id": "earth_day_2025"
}

```

{% hint style="warning" %}
Keep in mind that including location metadata may require updating your privacy policy and terms of service.
{% endhint %}

### Examples

To provide metadata you need to distribute the rewards through the X2EarnRewardsPool contract with the following function:

{% tabs %}
{% tab title="JavaScript" %}

```javascript
import { ProviderInternalHDWallet, ThorClient, VeChainProvider, VeChainSigner } from "@vechain/sdk-network";
import { X2EarnRewardsPool } from "@vechain/vebetterdao-contracts";

const thor = ThorClient.fromUrl("https://mainnet.vechain.org");
const provider = new VeChainProvider(
  thor,
  new ProviderInternalHDWallet("your space separated mnemonic".split(" "))
);
const rootSigner = await provider.getSigner();

// Define metadata as an object
const metadata = {
  "location": {
    "city": "Berlin",
    "country": "Germany",
    "region": "EU"
  },
  "referral_source": "social_media",
  "campaign_id": "earth_day_2025"
};

// Call the method
const x2EarnRewardsPoolContract = thor.contracts.load(
  X2EarnRewardsPool.address.mainnet,
  X2EarnRewardsPool.abi,
  rootSigner as VeChainSigner
);

const tx = await x2EarnRewardsPoolContract.transact.distributeRewardWithProofAndMetadata(
  APP_ID,
  amount,
  receiverAddress,
  ["link", "image"],
  ["https://link-to-proof.com", "https://link-to-image.com/1.png"],
  ["waste_mass"],
  [100],
  "User performed a sustainable action on my app",
  JSON.stringify(metadata) // Convert metadata object to JSON string
);

await tx.wait();

```

{% endtab %}

{% tab title="Solidity" %}

```python
import "./interfaces/IX2EarnRewardsPool.sol";

contract MyContract {
    function sendRewardWithMetadata() onlyAdmin {
        // this declaration is needed because solidity has 
        // an issue with dynamic vs fixed-size arrays
        string[] memory proofTypes = new string[](1);
        proofTypes[0] = "link";
        
        string[] memory proofUrls = new string[](1);
        proofUrls[0] = action.proofUrl;
        
        string[] memory impactTypes = new string[](1);
        impactTypes[0] = "waste_mass";
            
        uint256[] memory impactValues = new uint256[](1);
        // let's pretend you have another function that calculates your impact
        impactValues[0] = calculateWasteMass(
            challenge.litterSize,
            challenge.litterCount
        );
        
        IX2EarnRewardsPool x2EarnRewardsPool = IX2EarnRewardsPool(x2EarnRewardsPoolAddress);
        
        // Constructing metadata JSON string
        string memory metadata = '{"location":{"city":"Berlin","country":"Germany","region":"EU"},"referral_source":"social_media","campaign_id":"earth_day_2025"}';
    
        
        // If distributeReward fails, it will revert
        x2EarnRewardsPool.distributeRewardWithProofAndMetadata(
            VBD_APP_ID,
            rewardAmount,
            receiver,
            proofTypes,
            proofUrls,
            impactTypes,
            impactValues,
            "User participated in a solo cleanup",
            metadata
        );
    }
}

```

{% endtab %}
{% endtabs %}

### Emitted Event: `RewardMetadata`

Upon successful execution of the `distributeRewardWithProofAndMetadata` function, the `RewardMetadata` event is emitted with the following parameters:

* **amount** (`uint256`): The distributed reward amount.
* **appId** (`bytes32`): The application identifier.
* **receiver** (`address`): The address receiving the reward.
* **metadata** (`string`): The JSON-formatted metadata string.
* **distributor** (`address`): The address initiating the distribution.

This event allows off-chain systems to listen for and process reward distributions along with their associated metadata.

### Guidelines

* **Optional Usage**: The `metadata` is optional. If your application doesn't require additional context, you can continue using the existing `distributeRewardWithProof` function.
* **Standardization**: Adhere to the suggested metadata structure to ensure consistency and facilitate seamless data integration across the ecosystem.
* **Data Validation**: Implement validation checks to ensure the metadata JSON is correctly formatted and contains relevant information before invoking the distribution function.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.vebetterdao.org/developer-guides/reward-metadata.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
