Metadata
BitBadges allows defining metadata for both collections and individual badges using timeline-based metadata fields. This enables rich, dynamic content that can change over time while maintaining on-chain verifiability.
Metadata Timelines
Collection Metadata Timeline
The collectionMetadataTimeline
defines metadata for the entire collection over time.
"collectionMetadataTimeline": [
{
"timelineTimes": [
{
"start": "1",
"end": "18446744073709551615"
}
],
"collectionMetadata": {
"uri": "ipfs://Qmf8xxN2fwXGgouue3qsJtN8ZRSsnoHxM9mGcynTPhh6Ub",
"customData": ""
}
}
]
Badge Metadata Timeline
The badgeMetadataTimeline
defines metadata for individual badges over time. The order of badgeMetadata
entries matters, as it uses a first-match approach via linear scan for specific badge IDs. BitBadges uses the {id}
placeholder in the badge metadata URI to replace with the actual badge ID.
"badgeMetadataTimeline": [
{
"timelineTimes": [
{
"start": "1",
"end": "18446744073709551615"
}
],
"badgeMetadata": [
{
"uri": "ipfs://Qmf8xxN2fwXGgouue3qsJtN8ZRSsnoHxM9mGcynTPhh6Ub/{id}",
"badgeIds": [
{
"start": "1",
"end": "10000000000000"
}
],
"customData": ""
}
]
}
]
Metadata Interface
The BitBadges API, Indexer, and Site expect metadata to follow this format by default:
export interface Metadata<T extends NumberType> {
name: string;
description: string;
image: string;
video?: string;
category?: string;
externalUrl?: string;
tags?: string[];
socials?: {
[key: string]: string;
};
}
Key Features
Dynamic Badge ID Replacement
If the badge metadata URI includes
"{id}"
, it's replaced with the actual badge IDExample:
"...abc.com/metadata/{id}"
becomes"...abc.com/metadata/1"
for badge ID 1Enables efficient metadata generation for large collections
First-Match Badge Metadata
Badge metadata entries are evaluated in order
First matching entry for a badge ID is used
Allows specific overrides before general rules
Permission Control
Metadata updates are controlled by collection permissions:
Collection Metadata Permission
"canUpdateCollectionMetadata": [
{
"timelineTimes": [{"start": "1", "end": "18446744073709551615"}],
"permanentlyPermittedTimes": [{"start": "1", "end": "18446744073709551615"}],
"permanentlyForbiddenTimes": []
}
]
Badge Metadata Permission
"canUpdateBadgeMetadata": [
{
"badgeIds": [{"start": "1", "end": "100"}],
"timelineTimes": [{"start": "1", "end": "18446744073709551615"}],
"permanentlyPermittedTimes": [{"start": "1", "end": "18446744073709551615"}],
"permanentlyForbiddenTimes": []
}
]
Timeline Times vs Permission Times Within Permissions
As explained in Permissions, the timelineTimes
field is used to define the timeline times that can be updated or not. The permanentlyPermittedTimes
and permanentlyForbiddenTimes
fields are used to define the times when the permission is enabled or disabled.
Usage Examples
Static Collection Metadata
{
"collectionMetadataTimeline": [
{
"timelineTimes": [{ "start": "1", "end": "18446744073709551615" }],
"collectionMetadata": {
"uri": "https://example.com/collection-metadata.json",
"customData": ""
}
}
]
}
Dynamic Badge Metadata with ID Replacement
{
"badgeMetadataTimeline": [
{
"timelineTimes": [{ "start": "1", "end": "18446744073709551615" }],
"badgeMetadata": [
{
"uri": "https://api.example.com/badges/{id}",
"badgeIds": [{ "start": "1", "end": "1000" }],
"customData": ""
}
]
}
]
}
Last updated