Skip to content

Commit 4b4487b

Browse files
flhpsjdsikaCopilot
authored
feat(EVES-003): add EVM/ERC-721 token metadata support (#59)
* 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> * fix(eves-003): migrate manifest to envited-x:Manifest v3/v5 and add SHACL CI - Rewrite envited-x_manifest.json to use compact JSON-LD form with context URLs (envited-x/v3/, manifest/v5/) instead of verbose @value/@type typed literals that fail SHACL validation - Use envited-x:Manifest type with envited-x:* categories and access roles per envited-x:ManifestShape constraints - Add required iri field on hasLicense per LicenseLinkReferenceShape - Add shacl_validation.yml CI workflow using ontology-management-base --remote flag for HTTP-based ontology resolution Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: Carlo van Driesten <carlo.van-driesten@bmw.de> * docs(eves-003): add pipeline overview and harmonize example files - Add §1a Asset Lifecycle Overview with three-stage pipeline diagram (Preparation → Packaging → Publication) and example file table - Harmonize input_manifest.json to use same JSON-LD style as envited-x_manifest.json (context URLs, manifest:Link wrappers) - Update inline §1b code snippet to match the actual file - Add cross-references: §1b ↔ §4 Step 1, §4 Step 2 → §6 Token Metadata - Add stage labels to example file references throughout the spec - Note zip version skew (v2/v4 inside zip vs v3/v5 standalone) - Document input_manifest.json CI exclusion (partial Stage 1 format) - Add iri enrichment step to pipeline description Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: Carlo van Driesten <carlo.van-driesten@bmw.de> * fix(eves-003): resolve markdown lint and prettier formatting issues - Shorten Stage 2 description to stay within 300-char line limit - Apply prettier formatting to eves-003.md Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: Carlo van Driesten <carlo.van-driesten@bmw.de> * fix(EVES-003): address audit findings for EVM token metadata PR - Add missing 'name' property definition to TZIP-21 schema (was required but undefined, allowing any type) - Fix grammar in ERC-721 schema: 'to which this NFT represents' -> 'that this NFT represents' - Add normative tag-to-attribute mapping table defining canonical trait_type names for the 6 static TZIP-21 tags - Fix wrong reference [21] for hdmap SHACL shapes (was pointing to envited-x ontology); add new [30] for HD-Map Ontology - Normalize EVES-007 references to reference-link style [31] - Add empty 'contributors' array to ERC-721 example for completeness Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix(EVES-003): remove duplicate publishers key in ERC-721 example JSON parsers keep only the last occurrence of a duplicated key, so the first publishers array was dead content that schema validation could not detect. * refactor(EVES-003): remove Tezos/TZIP-21 token metadata path The ENVITED-X Data Space no longer uses Tezos. Remove the TZIP-21 metadata mapping, example, schema, and all Tezos branches from the upload and synchronization process. ERC-721 is now the only token metadata format. Since this specification and its deployments are still drafts, no backwards compatibility with previously minted Tezos assets is maintained. * docs(EVES-003): mark on-chain metadata registration as an open issue The registration mechanism is being redesigned around an evidence-based listing registry (signed authorization evidence from an SSI wallet, token minted to the registry contract, on-chain hash binding). Keep the metadata field mappings normative while flagging the registration and minting flow as subject to change. * docs(EVES-003): explain why the minter DID cannot be verified on-chain The minter field lives in the off-chain metadata JSON and names the organization's did:ethr independently of the transaction sender. ERC-1056 DID document entries (added signing keys) exist only as events, which contracts cannot read, so matching the claimed DID against the authorization evidence must happen off-chain at read time. * docs(EVES-003): finalize token registration wording for merge Replace the open-issue callouts on metadata registration and minter verification with normative prose. The point at which tokens and the claimed minter identity are verified against a root of trust remains open and is tracked under Future Improvements. * ci(shacl): install ontology-management-base from main The feat/http-artifact-resolution branch (merged as #57) now has a dangling service-characteristics submodule pointer, which breaks pip install during the SHACL validation job. * fix(EVES-005): replace dead Dataspace Protocol knowledgebase link The IDS knowledgebase page returns 404 since the protocol moved to Eclipse stewardship; point to the IDSA specification repository instead. --------- Signed-off-by: jdsika <carlo.van-driesten@vdl.digital> Signed-off-by: Carlo van Driesten <carlo.van-driesten@bmw.de> Co-authored-by: jdsika <carlo.van-driesten@vdl.digital> Co-authored-by: Carlo van Driesten <carlo.van-driesten@bmw.de> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent a7f8f7d commit 4b4487b

11 files changed

Lines changed: 1192 additions & 975 deletions
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
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
name: SHACL Validation
2+
3+
on:
4+
pull_request:
5+
paths:
6+
- "EVES/**/example/*.json"
7+
- ".github/workflows/shacl_validation.yml"
8+
9+
jobs:
10+
validate:
11+
name: Validate JSON-LD against SHACL
12+
runs-on: ubuntu-latest
13+
steps:
14+
- name: Checkout
15+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
16+
17+
- name: Setup Python
18+
uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
19+
with:
20+
python-version: "3.12"
21+
22+
- name: Install ontology-management-base
23+
run: pip install "ontology-management-base @ git+https://github.com/ASCS-eV/ontology-management-base.git@main"
24+
25+
# Only envited-x_manifest.json is validated — input_manifest.json is a
26+
# partial Stage 1 input format that intentionally omits hasManifestReference
27+
# and other computed fields, so it does not conform to the full ManifestShape.
28+
- name: Validate EVES-003 manifest
29+
run: >
30+
python -m src.tools.validators.validation_suite
31+
--remote
32+
--data-paths EVES/EVES-003/example/envited-x_manifest.json

.prettierignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
node_modules/
22
EVES/EVES-003/example/
3-
EVES/EVES-003/tzip21-schemas/
3+
EVES/EVES-003/erc721-schemas/
44
.github/styles/
55
*.zip

EVES/EVES-003/tzip21-schemas/tzip21_token_metadata-schema.json renamed to EVES/EVES-003/erc721-schemas/erc721_token_metadata-schema.json

Lines changed: 49 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,48 @@
11
{
22
"$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) follow Dublin Core naming conventions.",
34
"$ref": "#/definitions/asset",
4-
"title": "Rich Metadata",
55
"definitions": {
66
"asset": {
7+
"title": "ERC-721 Token Metadata (EVES-003 Profile)",
78
"type": "object",
89
"additionalProperties": true,
10+
"required": [
11+
"name",
12+
"image"
13+
],
914
"properties": {
15+
"name": {
16+
"type": "string",
17+
"description": "Identifies the asset that this NFT represents."
18+
},
1019
"description": {
1120
"type": "string",
12-
"description": "General notes, abstracts, or summaries about the contents of an asset."
21+
"description": "Describes the asset that 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."
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)."
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)."
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 #."
1342
},
1443
"minter": {
1544
"type": "string",
16-
"format": "tzaddress",
17-
"description": "The tz address responsible for minting the asset."
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."
1846
},
1947
"creators": {
2048
"type": "array",
@@ -45,83 +73,26 @@
4573
"format": "date-time",
4674
"description": "A date associated with the creation or availability of the asset."
4775
},
48-
"blockLevel": {
49-
"type": "integer",
50-
"description": "Chain block level associated with the creation or availability of the asset."
51-
},
5276
"type": {
5377
"type": "string",
5478
"description": "A broad definition of the type of content of the asset."
5579
},
56-
"tags": {
57-
"type": "array",
58-
"description": "A list of tags that describe the subject or content of the asset.",
59-
"uniqueItems": true,
60-
"items": {
61-
"type": "string"
62-
}
63-
},
64-
"genres": {
65-
"type": "array",
66-
"description": "A list of genres that describe the subject or content of the asset.",
67-
"uniqueItems": true,
68-
"items": {
69-
"type": "string"
70-
}
71-
},
7280
"language": {
7381
"type": "string",
74-
"format": "https://tools.ietf.org/html/rfc1766",
75-
"description": "The language of the intellectual content of the asset as defined in RFC 1776."
76-
},
77-
"identifier": {
78-
"type": "string",
79-
"description": "A string or number used to uniquely identify the asset. Ex. URL, URN, UUID, ISBN, etc."
82+
"description": "The language of the intellectual content of the asset as defined in RFC 1766. EVES extension."
8083
},
8184
"rights": {
8285
"type": "string",
83-
"description": "A statement about the asset rights."
84-
},
85-
"rightsUri": {
86-
"type": "string",
87-
"format": "uri-reference",
88-
"description": "Links to a statement of rights."
89-
},
90-
"artifactUri": {
91-
"type": "string",
92-
"format": "uri-reference",
93-
"description": "A URI to the asset."
86+
"description": "A statement about the asset rights, for example, an SPDX license identifier."
9487
},
95-
"displayUri": {
88+
"rights_uri": {
9689
"type": "string",
9790
"format": "uri-reference",
98-
"description": "A URI to an image of the asset. Used for display purposes."
91+
"description": "Links to a statement of rights (for example, full license text or smart contract DID). EVES extension."
9992
},
100-
"thumbnailUri": {
101-
"type": "string",
102-
"format": "uri-reference",
103-
"description": "A URI to an image of the asset for wallets and client applications to have a scaled down image to present to end-users. Reccomened maximum size of 350x350px."
104-
},
105-
"externalUri": {
93+
"identifier": {
10694
"type": "string",
107-
"format": "uri-reference",
108-
"description": "A URI with additional information about the subject or content of the asset."
109-
},
110-
"isTransferable": {
111-
"type": "boolean",
112-
"description": "All tokens will be transferable by default to allow end-users to send them to other end-users. However, this field exists to serve in special cases where owners will not be able to transfer the token."
113-
},
114-
"isBooleanAmount": {
115-
"type": "boolean",
116-
"description": "Describes whether an account can have an amount of exactly 0 or 1. (The purpose of this field is for wallets to determine whether or not to display balance information and an amount field when transferring.)"
117-
},
118-
"shouldPreferSymbol": {
119-
"type": "boolean",
120-
"description": "Allows wallets to decide whether or not a symbol should be displayed in place of a name."
121-
},
122-
"ttl": {
123-
"type": "integer",
124-
"description": "The maximum amount of time in seconds the asset metadata should be cached."
95+
"description": "A string or number used to uniquely identify the asset. Ex. URL, URN, UUID, ISBN, DID, etc."
12596
},
12697
"formats": {
12798
"type": "array",
@@ -134,14 +105,7 @@
134105
"items": {
135106
"$ref": "#/definitions/attribute"
136107
},
137-
"description": "Custom attributes about the subject or content of the asset."
138-
},
139-
"assets": {
140-
"type": "array",
141-
"items": {
142-
"$ref": "#/definitions/asset"
143-
},
144-
"description": "Facilitates the description of collections and other types of resources that contain multiple assets."
108+
"description": "OpenSea-style attributes describing traits of the asset."
145109
}
146110
}
147111
},
@@ -189,21 +153,24 @@
189153
"type": "object",
190154
"additionalProperties": false,
191155
"properties": {
192-
"name": {
156+
"trait_type": {
193157
"type": "string",
194-
"description": "Name of the attribute."
158+
"description": "Name of the trait."
195159
},
196160
"value": {
197-
"type": "string",
198-
"description": "Value of the attribute."
161+
"description": "Value of the trait.",
162+
"oneOf": [
163+
{ "type": "string" },
164+
{ "type": "number" }
165+
]
199166
},
200-
"type": {
167+
"display_type": {
201168
"type": "string",
202-
"description": "Type of the value. To be used for display purposes."
169+
"description": "Display type hint for the trait (for example, number, boost_percentage, boost_number, date)."
203170
}
204171
},
205172
"required": [
206-
"name",
173+
"trait_type",
207174
"value"
208175
]
209176
},

0 commit comments

Comments
 (0)