Skip to content

Commit e1f2c88

Browse files
committed
feat(EVES-003): add EVM/ERC-721 token metadata support
Extend EVES-003 to support EVM chains alongside the existing Tezos/TZIP-21 token metadata path, enabling minting simulation asset NFTs as ERC-721 tokens on Ethereum-compatible chains such as Etherlink L2, as anticipated by EVES-006 and EVES-007. Spec text (eves-003.md): - Add EVES-007 and EVES-008 to requires frontmatter - Add RFC 2119 boilerplate at top of Specification section - Add [29] RFC 1766 reference for language field - Generalize abstract to reference both TZIP-21 and ERC-721 - Branch Steps 2, 4, and 5 for chain-specific token metadata files - Add EVM contract identifier (Etherlink L2) to Section 5 - Restructure into parent "6. Token Metadata" section with subsections for TZIP-21 (Tezos) and ERC-721 (EVM) - Add ERC-721/OpenSea metadata mapping table with background_color, contributors, and language rows - Add language row to TZIP-21 mapping table (backed by TZIP-21 spec) - Clarify did:ethr as cross-chain organizational identity (EVES-008) - Add ERC-7572 contract-level metadata subsection - Recommend ERC-5192 for soulbound tokens, ERC-4906 for metadata update events - Fix ontology property paths to match current SHACL shapes - Migrate ontology IRIs to w3id.org (envited-x/v3, manifest/v5, hdmap/v6) Schemas: - Fix JSON Schema draft-07 $ref sibling bug (move title into asset definition) in both schemas - Replace "e.g." with "for example" in all schema descriptions - New erc721_token_metadata-schema.json (JSON Schema draft-07) - TZIP-21: add required ["name"], update minter to DID per EVES-008, fix RFC 1776 → RFC 1766 Examples: - New erc721_token_metadata.json with background_color "111827", ontology IRIs as trait_type (lossless mapping) - TZIP-21: update minter to did:ethr per EVES-008, migrate ontology IRIs - Manifest: fix @context to array-style, update gx namespace, fix hasLicense structure per manifest SHACL Closes #35 Signed-off-by: jdsika <carlo.van-driesten@vdl.digital>
1 parent 7661aa5 commit e1f2c88

10 files changed

Lines changed: 794 additions & 76 deletions

File tree

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
name: Schema Validation
2+
3+
on:
4+
pull_request:
5+
paths:
6+
- "EVES/**/example/*.json"
7+
- "EVES/**/*-schemas/*.json"
8+
- "package.json"
9+
10+
jobs:
11+
validate:
12+
name: Validate Examples Against Schemas
13+
runs-on: ubuntu-latest
14+
steps:
15+
- name: Checkout
16+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
17+
18+
- name: Setup Node
19+
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
20+
with:
21+
node-version: "22"
22+
cache: npm
23+
24+
- name: Install dependencies
25+
run: npm ci
26+
27+
- name: Validate schemas
28+
run: npm run validate:schemas

.prettierignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
node_modules/
22
EVES/EVES-003/example/
33
EVES/EVES-003/tzip21-schemas/
4+
EVES/EVES-003/erc721-schemas/
45
.github/styles/
56
*.zip
Lines changed: 210 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,210 @@
1+
{
2+
"$schema": "http://json-schema.org/draft-07/schema#",
3+
"$comment": "EVES-003 profile of ERC-721 token metadata. Base fields (name, description, image) from the ERC-721 Metadata JSON Schema (EIP-721). Display fields (animation_url, external_url, background_color, attributes) from OpenSea Metadata Standards (de facto, no upstream schema). EVES extension fields (minter, creators, contributors, publishers, date, type, language, rights, rights_uri, identifier, formats) mirror TZIP-21 for cross-chain interoperability.",
4+
"$ref": "#/definitions/asset",
5+
"definitions": {
6+
"asset": {
7+
"title": "ERC-721 Token Metadata (EVES-003 Profile)",
8+
"type": "object",
9+
"additionalProperties": true,
10+
"required": [
11+
"name",
12+
"image"
13+
],
14+
"properties": {
15+
"name": {
16+
"type": "string",
17+
"description": "Identifies the asset to which this NFT represents."
18+
},
19+
"description": {
20+
"type": "string",
21+
"description": "Describes the asset to which this NFT represents."
22+
},
23+
"image": {
24+
"type": "string",
25+
"format": "uri-reference",
26+
"description": "A URI pointing to a resource with mime type image/* representing the asset. Maps to TZIP-21 displayUri."
27+
},
28+
"animation_url": {
29+
"type": "string",
30+
"format": "uri-reference",
31+
"description": "A URI pointing to the actual asset content (for example, asset.zip download URL). Maps to TZIP-21 artifactUri."
32+
},
33+
"external_url": {
34+
"type": "string",
35+
"format": "uri-reference",
36+
"description": "A URI pointing to an external page with additional information about the asset (for example, domain metadata on IPFS). Maps to TZIP-21 externalUri."
37+
},
38+
"background_color": {
39+
"type": "string",
40+
"pattern": "^[0-9a-fA-F]{6}$",
41+
"description": "Background color of the item on OpenSea. Must be a six-character hexadecimal without a pre-pended #."
42+
},
43+
"minter": {
44+
"type": "string",
45+
"description": "The DID of the LegalEntity (OrganizationParticipant) responsible for minting the asset, as defined in EVES-008 (for example, did:ethr:<chainIdHex>:<address>). EVES extension."
46+
},
47+
"creators": {
48+
"type": "array",
49+
"description": "The primary person, people, or organization(s) responsible for creating the intellectual content of the asset.",
50+
"uniqueItems": true,
51+
"items": {
52+
"type": "string"
53+
}
54+
},
55+
"contributors": {
56+
"type": "array",
57+
"description": "The person, people, or organization(s) that have made substantial creative contributions to the asset.",
58+
"uniqueItems": true,
59+
"items": {
60+
"type": "string"
61+
}
62+
},
63+
"publishers": {
64+
"type": "array",
65+
"description": "The person, people, or organization(s) primarily responsible for distributing or making the asset available to others in its present form.",
66+
"uniqueItems": true,
67+
"items": {
68+
"type": "string"
69+
}
70+
},
71+
"date": {
72+
"type": "string",
73+
"format": "date-time",
74+
"description": "A date associated with the creation or availability of the asset."
75+
},
76+
"type": {
77+
"type": "string",
78+
"description": "A broad definition of the type of content of the asset."
79+
},
80+
"language": {
81+
"type": "string",
82+
"description": "The language of the intellectual content of the asset as defined in RFC 1766. EVES extension."
83+
},
84+
"rights": {
85+
"type": "string",
86+
"description": "A statement about the asset rights, for example, an SPDX license identifier."
87+
},
88+
"rights_uri": {
89+
"type": "string",
90+
"format": "uri-reference",
91+
"description": "Links to a statement of rights (for example, full license text or smart contract DID). Maps to TZIP-21 rightsUri. EVES extension."
92+
},
93+
"identifier": {
94+
"type": "string",
95+
"description": "A string or number used to uniquely identify the asset. Ex. URL, URN, UUID, ISBN, DID, etc."
96+
},
97+
"formats": {
98+
"type": "array",
99+
"items": {
100+
"$ref": "#/definitions/format"
101+
}
102+
},
103+
"attributes": {
104+
"type": "array",
105+
"items": {
106+
"$ref": "#/definitions/attribute"
107+
},
108+
"description": "OpenSea-style attributes describing traits of the asset."
109+
}
110+
}
111+
},
112+
"format": {
113+
"type": "object",
114+
"additionalProperties": false,
115+
"properties": {
116+
"uri": {
117+
"type": "string",
118+
"format": "uri-reference",
119+
"description": "A URI to the asset represented in this format."
120+
},
121+
"hash": {
122+
"type": "string",
123+
"description": "A checksum hash of the content of the asset in this format."
124+
},
125+
"mimeType": {
126+
"type": "string",
127+
"description": "Media (MIME) type of the format."
128+
},
129+
"fileSize": {
130+
"type": "integer",
131+
"description": "Size in bytes of the content of the asset in this format."
132+
},
133+
"fileName": {
134+
"type": "string",
135+
"description": "Filename for the asset in this format. For display purposes."
136+
},
137+
"duration": {
138+
"type": "string",
139+
"format": "time",
140+
"description": "Time duration of the content of the asset in this format."
141+
},
142+
"dimensions": {
143+
"$ref": "#/definitions/dimensions",
144+
"description": "Dimensions of the content of the asset in this format."
145+
},
146+
"dataRate": {
147+
"$ref": "#/definitions/dataRate",
148+
"description": "Data rate which the content of the asset in this format was captured at."
149+
}
150+
}
151+
},
152+
"attribute": {
153+
"type": "object",
154+
"additionalProperties": false,
155+
"properties": {
156+
"trait_type": {
157+
"type": "string",
158+
"description": "Name of the trait."
159+
},
160+
"value": {
161+
"description": "Value of the trait.",
162+
"oneOf": [
163+
{ "type": "string" },
164+
{ "type": "number" }
165+
]
166+
},
167+
"display_type": {
168+
"type": "string",
169+
"description": "Display type hint for the trait (for example, number, boost_percentage, boost_number, date)."
170+
}
171+
},
172+
"required": [
173+
"trait_type",
174+
"value"
175+
]
176+
},
177+
"dataRate": {
178+
"type": "object",
179+
"additionalProperties": false,
180+
"properties": {
181+
"value": {
182+
"type": "integer"
183+
},
184+
"unit": {
185+
"type": "string"
186+
}
187+
},
188+
"required": [
189+
"unit",
190+
"value"
191+
]
192+
},
193+
"dimensions": {
194+
"type": "object",
195+
"additionalProperties": false,
196+
"properties": {
197+
"value": {
198+
"type": "string"
199+
},
200+
"unit": {
201+
"type": "string"
202+
}
203+
},
204+
"required": [
205+
"unit",
206+
"value"
207+
]
208+
}
209+
}
210+
}

0 commit comments

Comments
 (0)