Documentation Index
Fetch the complete documentation index at: https://docs.peridotvault.com/llms.txt
Use this file to discover all available pages before exploring further.
Overview
PGC-1 is the ownership and access layer for a single game in Peridot.
Responsibilities:
- Store canonical
gameId
- Store canonical publisher address
- Store canonical metadata URI
- Initialize canonical game state during deployment
- Mint non-transferable licenses
- Provide entitlement and access checks
- Manage authorized minters
- Preserve the strongest valid entitlement for each user
PGC-1 does NOT handle pricing, payments, moderation, catalog listing, or publisher-wide subscriptions.
Data Structures
LicensePolicy
| Field | Type | Description |
|---|
| issuedAt | uint64 | Timestamp when license is minted |
| expiresAt | uint64 | Expiration timestamp |
Rules
expiresAt = 0 means permanent license
expiresAt > now means temporary valid license
expiresAt < now means expired license
State
| Variable | Type | Description |
|---|
| gameId | string | Canonical game identifier |
| publisher | address | Canonical publisher address |
| metadataURI | string | Canonical metadata URI |
| minters | mapping(address => bool) | Authorized minters |
| licenses | mapping(address => LicensePolicy) | User license policy per account |
Functions
1. initialize
Initializes canonical game state.
function initialize(gameId, publisher, metadataURI, initialMinter)
Params
| Name | Type | Description |
|---|
| gameId | string | Canonical game identifier |
| publisher | address | Canonical publisher address |
| metadataURI | string | Canonical metadata URI |
| initialMinter | address | Initial authorized minter |
Rules
- MUST only be callable once
gameId MUST NOT be empty
publisher MUST NOT be zero address
metadataURI MUST NOT be empty
initialMinter MUST NOT be zero address
Behavior
- set canonical
gameId
- set canonical
publisher
- set canonical
metadataURI
- authorize
initialMinter
Notes
- On EVM implementations this MAY be represented by constructor arguments
- On non-constructor environments this SHOULD be represented by an initialization function
2. mintLicense
Grants or upgrades a license for a user.
function mintLicense(to, expiresAt)
Params
| Name | Type | Description |
|---|
| to | address | Receiver address |
| expiresAt | uint64 | License expiration timestamp |
Rules
- Only authorized minter
to MUST NOT be zero address
- Permanent license MUST NOT be downgraded by a temporary license
- The strongest valid entitlement MUST be preserved
Behavior
If the user has no license:
If the user has an expired license:
- replace with incoming license
If the user has a temporary license and incoming license is permanent:
If the user has a permanent license and incoming license is temporary:
- keep permanent license
- incoming temporary license MUST NOT downgrade access
If the user has a temporary license and incoming temporary license expires later:
- extend or replace with later expiry
If the user has a temporary license and incoming temporary license expires earlier:
3. hasLicense
Returns whether a user owns a valid license for this game.
function hasLicense(user)
Params
| Name | Type | Description |
|---|
| user | address | User address |
Returns
| Type | Description |
|---|
| bool | True if user owns a valid license |
Rules
- Expired licenses MUST return
false
4. canAccessGame
Returns whether a user can currently access this game.
function canAccessGame(user)
Params
| Name | Type | Description |
|---|
| user | address | User address |
Returns
| Type | Description |
|---|
| bool | True if user has a valid non-expired license |
Rules
- Expired licenses MUST return
false
Notes
- This function is suitable as an entitlement check for launcher access, download authorization, and future DRM-like enforcement
- This function alone is NOT a complete DRM system
5. getLicensePolicy
Returns license policy data for a user.
function getLicensePolicy(user)
Params
| Name | Type | Description |
|---|
| user | address | User address |
Returns
| Name | Type | Description |
|---|
| issuedAt | uint64 | Timestamp when license was minted |
| expiresAt | uint64 | Expiration timestamp |
6. setMinter
Updates minter authorization.
function setMinter(account, isAuthorized)
Params
| Name | Type | Description |
|---|
| account | address | Minter address |
| isAuthorized | bool | Authorization status |
Rules
- Only publisher
account MUST NOT be zero address
- Event SHOULD be emitted
7. isMinter
Returns whether an account is an authorized minter.
function isMinter(account)
Params
| Name | Type | Description |
|---|
| account | address | Account address |
Returns
| Type | Description |
|---|
| bool | Authorized minter status |
8. getPublisher
Returns canonical publisher address.
function getPublisher()
Returns
| Type | Description |
|---|
| address | Publisher address |
Returns canonical metadata URI.
function getMetadataURI()
Returns
| Type | Description |
|---|
| string | Metadata URI |
10. getGameId
Returns canonical game identifier.
function getGameId()
Returns
| Type | Description |
|---|
| string | Game identifier |
11. setPublisher
Updates publisher address.
function setPublisher(publisher)
Params
| Name | Type | Description |
|---|
| publisher | address | New publisher address |
Rules
- Only current publisher
publisher MUST NOT be zero address
- Event SHOULD be emitted
Notes
- This function is optional if publisher is intended to be immutable in a specific implementation
Updates metadata URI.
function setMetadataURI(metadataURI)
Params
| Name | Type | Description |
|---|
| metadataURI | string | New metadata URI |
Rules
- Only publisher
metadataURI MUST NOT be empty
- Event SHOULD be emitted
Notes
- This function is optional if metadata is intended to be immutable in a specific implementation
Access Control
| Function | Access |
|---|
| initialize | Deployment only |
| mintLicense | Authorized Minter |
| hasLicense | Public |
| canAccessGame | Public |
| getLicensePolicy | Public |
| setMinter | Publisher |
| isMinter | Public |
| getPublisher | Public |
| getMetadataURI | Public |
| getGameId | Public |
| setPublisher | Publisher |
| setMetadataURI | Publisher |
Requirements
initialize() MUST set canonical gameId, publisher, and metadataURI
initialize() MUST only be executable once
gameId MUST be stored in PGC-1
publisher MUST be stored in PGC-1
metadataURI MUST be stored in PGC-1
mintLicense() MUST only be callable by authorized minters
getPublisher() MUST return the canonical publisher for the game
getMetadataURI() MUST return the canonical metadata URI for the game
getGameId() MUST return the canonical game identifier
hasLicense(user) MUST return false for expired licenses
canAccessGame(user) MUST return false for expired licenses
- Licenses MUST remain non-transferable
- Permanent licenses MUST NOT be downgraded by temporary licenses
- The strongest valid entitlement MUST be preserved for each user
Transferability
PGC-1 licenses are strictly non-transferable.
Implementations MUST ensure:
- licenses cannot be transferred between users
- any transfer attempt MUST fail
Subscription Compatibility
PGC-1 is intended for game-specific entitlement.
Publisher-wide subscriptions, game bundles, or ecosystem-wide passes SHOULD be implemented in a separate access layer or contract.
Such systems MAY grant additional access, but MUST NOT invalidate or downgrade a stronger permanent game license already held by the user.
Notes
- PGC-1 is the source of truth for publisher and metadata
- Registry is the source of truth for game validity and moderation
- Game Store is the source of truth for pricing and purchase flow
- PGC-1 should remain minimal and ownership-focused
Chain Support
PGC-1 is designed to be chain-agnostic.
EVM
- Built on top of ERC-1155
- Extended with license logic
- Transfer behavior MUST be disabled or restricted
Solana
- Implemented using Token-2022
- Extensions: NonTransferable, Metadata Pointer