diff --git a/CIP-0072/README.md b/CIP-0072/README.md index 709e1dd497..ad32d2d51c 100644 --- a/CIP-0072/README.md +++ b/CIP-0072/README.md @@ -6,6 +6,7 @@ Category: Metadata Authors: - Bruno Martins - Mateusz Czeladka + - Daniel Main Implementors: ["Lace Wallet dApp Store", "DappsOnCardano dApp Store"] Discussions: - https://github.com/cardano-foundation/CIPs/pull/355 @@ -49,26 +50,21 @@ Stores and auditors should be able to follow the chain and find when a new dApp - **`integrity`**: The dApp's off-chain metadata should match the metadata **anchored** on-chain. - **`trust`**: The dApp's certificate should be signed by a trusted entity. It's up to the store/auditor to decide which entities are trusted and they should maintain and publish their own list of trusted entities. Although this entities might be well known, it's not the responsibility of this CIP to maintain this list. These entities could be directly associated with developer/publisher or not. -### **On-chain dApp Registration Certificate** - -The on-chain dApp registration certificate MUST follow canonical JSON and be serialised according to RFC 8785 (https://www.rfc-editor.org/rfc/rfc8785). This stipulation is to avoid any ambigiutines in the signature calculation. +### **On-chain dApp Registration** ```json { "subject": "b37aabd81024c043f53a069c91e51a5b52e4ea399ae17ee1fe3cb9c44db707eb", "rootHash": "7abcda7de6d883e7570118c1ccc8ee2e911f2e628a41ab0685ffee15f39bba96", "metadata": [ - "https://foundation.app/my_dapp_7abcda.json" + "https://foundation.app/my_dapp_7abcda/tart/", + "7abcda7de6d883e7570118c1ccc8ee2e91", + "e4ea399ae17ee1fe3cb9c44db707eb/", + "offchain.json" ], "type": { "action": "REGISTER", "comment": "New release adding zapping support." - }, - "signature": { - "r": "27159ce7d992c98fb04d5e9a59e43e75f77882b676fc6b2ccb8e952c2373da3e", - "s": "16b59ab1a9e349cd68d232f7652f238926dc24a2e435949ebe2e402a6557cfb4", - "algo": "Ed25519−EdDSA", - "pub": "b384b53d5fe9f499ecf088083e505f40d2a6c123bf7201608494fdb89a051b80" } } ``` @@ -83,19 +79,17 @@ The on-chain dApp registration certificate MUST follow canonical JSON and be ser - *`REGISTER`*: The certificate is asserting that the dApp is registered for the first time or is providing an update. - *`DE_REGISTER`*: The certificate is asserting that the dApp is deprecated / archived. So, no further dApp's on-chain update is expected. -*`rootHash`*: The hash of the entire offchain metadata tree object. This hash is used by clients to verify the integrity of the metadata tree object. When reading a metadata tree object, the client should calculate the hash of the object and compare it with the `rootHash` property. If the two hashes don't match, the client should discard the object. The metadata tree object is a JSON object that contains the dApp's metadata. The metadata tree object is described in the next section. Please note that off-chain JSON must be converted into RFC 8765 canonical form before taking the hash! - -*`metadata`*: An array of links to the dApp's metadata. The metadata is a JSON compatible RFC 8785 object that contains the dApp's metadata. +*`rootHash`*: The blake2b-256 hash of the entire offchain metadata tree object. This hash is used by clients to verify the integrity of the metadata tree object. When reading a metadata tree object, the client should calculate the hash of the object and compare it with the `rootHash` property. If the two hashes don't match, the client should discard the object. The metadata tree object is a JSON object that contains the dApp's metadata. The metadata tree object is described in the next section. Please note that off-chain JSON must be converted into RFC 8765 canonical form before taking the hash! -*`signature`*: The signature of the certificate. The publishers generate the signature is by first turning on-chain JSON into a canonical form (RFC 8765), hashing it with blake2b-256 and generating a signature of the hash. Stores / clients can verify the signature by repeating the process, they can use the public key to verify the signature of the certificate. Fields used for canonical JSON: ["subject", "rootHash", "metadata","type"]. Please note that a signature should be generated of blake2b-256 hash as a byte array, not as a hex represented string(!). +*`metadata`*: Chunks of URLs that make up the dApp's metadata are arranged in an array to accommodate the 64-character limit per chunk, allowing for the support of longer URLs. The metadata itself is a JSON object compatible with RFC 8785, containing detailed information about the dApp ### On-chain Schemas -[On-chain CDDL for registration / de-registration (Version 1)](./version_1_onchain.cddl) +[On-chain CDDL for registration / de-registration (Version 2.0.0)](./version_2.0.0_onchain.cddl) which also can be expressed using JSON schema: -[dApp on-chain certificate JSON Schema (Version 1)](./version_1_onchain.json) +[dApp on-chain certificate JSON Schema (Version 2.0.0)](./version_2.0.0_onchain.json) ### Metadata Label @@ -107,51 +101,65 @@ When submitting the transaction metadata pick the following value for `transacti The dApp Registration certificate itself doesn't enforce a particular structure to the metadata you might fetch off-chain. However, we recommend that you use the following structure: -[Off-chain dApp Registration certificate schema (Version 1)](./version_1_offchain.json) +[Off-chain dApp Registration certificate schema (Version 2)](./version_2.0.0_offchain.json) -This schema describes the minimum required fields for a store to be able to display and validate your dApp. You can add any other fields you want to the metadata, but we recommend that you use at least the ones described above. +This schema describes the minimum required fields for a store to be able to display and validate your dApp. ### Example ```json { - "subject": "9SYAJPNN", - "projectName": "My Project", - "link": "https://myProject.app", - "logo": "https://myProject.app/logo.png", - "social": { - "github": "https://mywebsite.com", - "twitter": "https://twitter.com/my_dapp", - "website": "https://github.com/my_dapp" - }, - "categories": ["Games"], + "version": "1.0.0", + "subject": "abcdef1234567890", + "projectName": "My dApp", + "link": "https://www.exampledapp.com", + "companyName": "Amazing dApp Inc.", + "companyEmail": "contact@myamazingdapp.com", + "companyWebsite": "https://www.myamazingdapp.com", + "logo": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAUAAA...", + "categories": ["DeFi", "Games"], + "screenshots": [ + "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD...", + "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEASABIAAD..." + ], + "social": [ + { + "name": "GitHub", + "link": "https://github.com/exampledapp" + }, + { + "name": "Twitter", + "link": "https://twitter.com/exampledapp" + } + ], "description": { - "short": "A story rich game where choices matter. This game is very addictive to play :)" + "short": "This is a short description of the dApp, giving an overview of its features and capabilities." }, "releases": [ { "releaseNumber": "1.0.0", - "releaseName": "V1", + "releaseName": "Initial Release", + "securityVulnerability": false, + "comment": "First major release with all core features.", "scripts": [ { - "id": "PmNd6w", - "version": 1 + "id": "script1", + "version": "1.0.0" } ] } ], "scripts": [ { - "id": "PmNd6w", - "name": "marketplace", - "purposes": ["SPEND"], + "id": "script1", + "name": "Example Script", + "purposes": ["SPEND", "MINT"], "type": "PLUTUS", "versions": [ { - "version": 1, + "version": "1.0.0", "plutusVersion": 1, - "scriptHash": "711dcb4e80d7cd0ed384da5375661cb1e074e7feebd73eea236cd68192", - "contractAddress": "addr1wywukn5q6lxsa5uymffh2esuk8s8fel7a0tna63rdntgrysv0f3ms" + "scriptHash": "abc123" } ] } @@ -205,9 +213,9 @@ Release Name is a field, which dApp developers can use on top of Release Version At the begining neither on-chain, nor off-chain JSON has been following RFC 8785 (canonical JSON) but we reached a point that, due to consistency checks, we need to take hash of both on-chain and off-chain and this forced us to stipulate that both on-chain and off-chain metadata documents need to be converted according to RFC 8785 before taking a blake2b-256 hash of them. -### On-Chain Signature Scope +### Transaction Signature Scope -On-chain part has a signature, which has a role to verify that a certain dApp owner made changes. In the initial version, a blake2b-256 signature was needed only for `rootHash` but following discussion, due to security concerns, decision has been made that the signature should attest the whole on-chain canonical JSON except signature field itself (because it would end up in an infinite recursion). +As any transaction in cardano network has a signature, which has a role to verify that a certain dApp owner made changes. ### Who Is The Owner? @@ -255,10 +263,6 @@ some app that can attest validity and conformance to JSON schema - dApp Registra We made a decision to change the schema so that scripts and releases are no longer required. This could help to get initial registration from dApp developers faster and some stores simply do not require dApps to add their scripts in order to be listed. -### Schema Version - -We discussed and analyzed idea of schema version and or even whole CIP version. It turns out that CIP is already versioned by CIP-??? where ??? is version number. During this CIP being in `PROPOSED` state we reserve our right to make small changes to the schema / document, after CIP becomes active, it will require a new CIP. This is the current process, which other CIPs are also following. - ### Tags We briefly discussed tags and we will likely introduce tags in the future. An array of tags to help stores / dApp developers categories where their dApp should show. This will complement `categories` field. diff --git a/CIP-0072/version_1_onchain.json b/CIP-0072/version_1_onchain.json deleted file mode 100644 index ef9bf510d6..0000000000 --- a/CIP-0072/version_1_onchain.json +++ /dev/null @@ -1,105 +0,0 @@ -{ - "$schema":"https://json-schema.org/draft/2020-12/schema", - "$id":"https://example.com/dApp.schema.json", - "title": "Cardano dApp Claim", - "description": "Registration of Cardano dApp claim.", - "type":"object", - "properties":{ - "subject":{ - "type":"string", - "minLength": 1, - "maxLength": 64, - "pattern":"^[0-9a-fA-F]{1,64}$", - "description":"Identifier of the claim subject (dApp). A UTF-8 encoded string, must be max 64 chars. Typically it is randomly generated hash by the dApp developer." - }, - "rootHash":{ - "type":"string", - "minLength": 64, - "maxLength": 64, - "pattern":"^[0-9a-fA-F]{64}$", - "description":"blake2b-256 hash of the metadata describing the off-chain part of the dApp." - }, - "metadata": { - "type": "array", - "description": "An array of valid URLs pointing to off-chain CIP-72 compatible metadata document. If an individual URL is longer than 64 characters, it must be expressed as an array of strings (where each string may contain at most 64 characters).", - "items": { - "anyOf": [{ - "type": "string", - "minLength": 1, - "maxLength": 64 - }, { - "type": "array", - "items": { - "type": "string", - "minLength": 1, - "maxLength": 64 - } - }], - "examples": ["https://raw.githubusercontent.com/org/repo/offchain.json", ["https://raw.githubusercontent.com/long-org-name/", "long-repo-name/offchain.json"], "ipfs://QmbQDvKJeo2NgGcGdnUiUFibTzuKNK5Uij7jzmK8ZccmWp", ["ipfs://QmbQDvKJeo2NgGcGdnUiaAdADA", "UFibTzuKNKc0jA390alDAD5Uij7jzmK8ZccmWp"]] - } - }, - "type":{ - "type":"object", - "description":"Describes the releases, if they are new or an updates.", - "properties":{ - "action":{ - "type":"string", - "enum":["REGISTER", "DE_REGISTER"], - "description":"Describes the action this certificate is claiming; i.e 'REGISTER', for a new dApp or an update, DE_REGISTER for asserting that the dApp's development is stopped, and it is deprecated. So, no further dApp's on-chain update is to be expected." - }, - "comment": { - "type": "string", - "minLength": 1, - "maxLength": 64, - "description": "A free text field to provide details about this particular changes (64 chars limited)." - } - }, - "required":[ - "action" - ] - }, - "signature":{ - "description":"Signature of the blake2b-256 hash of whole canonical (RFC 8785) JSON document (except signature property).", - "type":"object", - "properties":{ - "r":{ - "type":"string", - "description":"A hex representation of the R component of the signature.", - "minLength": 64, - "maxLength": 64, - "pattern":"^[0-9a-fA-F]{64}$" - }, - "s":{ - "type":"string", - "description":"A hex representation of the S component of the signature.", - "minLength": 64, - "maxLength": 64, - "pattern":"^[0-9a-fA-F]{64}$" - }, - "algo":{ - "const":"Ed25519-EdDSA" - }, - "pub":{ - "type":"string", - "description":"A hex representation of the public key.", - "minLength": 64, - "maxLength": 64, - "pattern":"^[0-9a-fA-F]{64}$" - } - }, - "required":[ - "r", - "s", - "algo", - "pub" - ] - } - }, - "required":[ - "subject", - "rootHash", - "type", - "signature" - ] - } - \ No newline at end of file diff --git a/CIP-0072/version_1_offchain.json b/CIP-0072/version_2.0.0_offchain.json similarity index 55% rename from CIP-0072/version_1_offchain.json rename to CIP-0072/version_2.0.0_offchain.json index d1e8b306df..2870670aa0 100644 --- a/CIP-0072/version_1_offchain.json +++ b/CIP-0072/version_2.0.0_offchain.json @@ -2,6 +2,11 @@ "$schema": "https://json-schema.org/draft/2020-12/schema", "type":"object", "properties": { + "version": { + "type": "string", + "pattern": "^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-([0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*))?(?:\\+([0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*))?$", + "description": "Off-chain schema version following Semantic Versioning" + }, "subject": { "type":"string", "minLength": 1, @@ -11,69 +16,115 @@ }, "projectName": { "type":"string", - "description": "A project name, e.g. My dApp." + "description": "A project name, e.g. My dApp.", + "maxLength": 40 }, "link": { "type":"string", - "description": "Website presenting a dApp.", - "pattern": "(https?:\/\/(?:www\\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\\.[^\\s]{2,}|www\\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\\.[^\\s]{2,}|https?:\/\/(?:www\\.|(?!www))[a-zA-Z0-9]+\\.[^\\s]{2,}|www\\.[a-zA-Z0-9]+\\.[^\\s]{2,})" - }, - "logo": { + "description": "A link a dApp or a website presenting a DApp", + "pattern": "((https?|ipfs|ipns):\/\/[\\u00C0-\\u017F-a-zA-Z0-9])", + "maxLength": 200 + }, + "companyName": { + "type":"string", + "description": "Company name", + "maxLength": 100 + }, + "companyEmail": { + "type":"string", + "description": "Contact email of the company behind the dApp", + "pattern": "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$", + "maxLength": 200 + }, + "companyWebsite": { "type":"string", - "description": "URL to the logo or the base64 encoded image." + "description": "Website of the company behind the dApp.", + "pattern": "((https?|ipfs|ipns):\/\/[\\u00C0-\\u017F-a-zA-Z0-9])", + "maxLength": 200 + }, + "logo": { + "description": "Logo encoded in base64. Minimum resolution: 512x512px, supported formats: PNG/JPG/SVG, maximum file size: 1 MB", + "type": "string", + "contentEncoding": "base64", + "oneOf": [ + { + "contentMediaType": "image/png" + }, + { + "contentMediaType": "image/jpeg" + }, + { + "contentMediaType": "image/svg+xml" + } + ], + "maxLength": 1361000 }, "categories": { "type":"array", "items": { "type": "string", - "enum":["Games", "DeFi", "Gambling", "Exchanges", "Collectibles", "Marketplaces", "Social", "Other"] + "enum": ["DeFi", "Development", "Education", "Games", "Identity", "Marketplace", "NFT", "Other", "Security"] }, "description": "One or more categories. Category MUST be one of the following schema definition." }, + "screenshots": { + "type": "array", + "maxItems": 10, + "items": { + "description": "Screenshots encoded in base64. Minimum resolution for base64 images: 1920x1080px, supported formats: PNG/JPG/SVG, maximum file size: 2 MB for base64.", + "type": "string", + "contentEncoding": "base64", + "oneOf": [ + { + "contentMediaType": "image/png" + }, + { + "contentMediaType": "image/jpeg" + }, + { + "contentMediaType": "image/svg+xml" + } + ], + "maxLength": 2722000 + }, + "description": "Screenshots of the DApp encoded in base64. We recommend to share screenshots from the dApp usage itself." + }, "social": { - "type":"object", - "properties": { - "website": { - "type":"string", - "description": "dApps website link.", - "pattern": "(https?:\/\/(?:www\\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\\.[^\\s]{2,}|www\\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\\.[^\\s]{2,}|https?:\/\/(?:www\\.|(?!www))[a-zA-Z0-9]+\\.[^\\s]{2,}|www\\.[a-zA-Z0-9]+\\.[^\\s]{2,})" - }, - "twitter": { - "type":"string", - "description": "An optional Twitter link.", - "pattern": "(https?:\/\/(?:www\\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\\.[^\\s]{2,}|www\\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\\.[^\\s]{2,}|https?:\/\/(?:www\\.|(?!www))[a-zA-Z0-9]+\\.[^\\s]{2,}|www\\.[a-zA-Z0-9]+\\.[^\\s]{2,})" - }, - "github": { - "type":"string", - "description": "An optional Github link.", - "pattern": "(https?:\/\/(?:www\\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\\.[^\\s]{2,}|www\\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\\.[^\\s]{2,}|https?:\/\/(?:www\\.|(?!www))[a-zA-Z0-9]+\\.[^\\s]{2,}|www\\.[a-zA-Z0-9]+\\.[^\\s]{2,})" - }, - "discord": { - "type":"string", - "description": "An optional Discord link.", - "pattern": "(https?:\/\/(?:www\\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\\.[^\\s]{2,}|www\\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\\.[^\\s]{2,}|https?:\/\/(?:www\\.|(?!www))[a-zA-Z0-9]+\\.[^\\s]{2,}|www\\.[a-zA-Z0-9]+\\.[^\\s]{2,})" + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "The platform or resource identifier (GitHub, Website, X.com, etc)" + }, + "link": { + "type": "string", + "pattern": "((https?|ipfs|ipns):\/\/[\\u00C0-\\u017F-a-zA-Z0-9])", + "maxLength": 200 + } } - }, - "required": ["website"] + } }, "description": { "type": "object", "properties": { "short": { "type": "string", - "description": "Short dApp description (no less than 40 and no longer than 168 characters).", + "description": "Short dApp description.", "minLength": 40, "maxLength": 168 }, "long": { "type": "string", - "description": "An optional long dApp description (no less than 40 and no longer than 1008 characters).", + "description": "An optional long dApp description.", "minLength": 40, "maxLength": 1008 } }, "required": [ - "short" + "short", + "long" ] }, "releases": { @@ -84,8 +135,8 @@ "properties": { "releaseNumber": { "type": "string", - "pattern": "^(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)(-((0|[1-9][0-9]*|[0-9]*[a-zA-Z-][0-9a-zA-Z-]*)(\\.(0|[1-9][0-9]*|[0-9]*[a-zA-Z-][0-9a-zA-Z-]*))*))?(\\+([0-9a-zA-Z-]+(\\.[0-9a-zA-Z-]+)*))?$", - "description": "Semver compatible release number (major.minor.patch) or (major.minor.patch-some_text) e.g. 1.2.3 or 1.1.1-alpha" + "pattern": "^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-([0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*))?(?:\\+([0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*))?$", + "description": "Semver compatible release number (major.minor.patch)" }, "releaseName": { "type": "string", @@ -109,7 +160,8 @@ "type": "string" }, "version": { - "type": "integer" + "type": "string", + "pattern": "^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-([0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*))?(?:\\+([0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*))?$" } }, "required": [ @@ -143,8 +195,8 @@ "purposes":{ "type":"array", "items": { - "type": "string", - "enum":["SPEND", "MINT"] + "type": "string", + "enum":["SPEND", "MINT"] }, "description": "Purpouses of the script, SPEND or MINT (notice it can be both for some modern Cardano languages)." }, @@ -158,9 +210,10 @@ { "type":"object", "properties":{ - "version":{ - "type":"integer", - "description":"Script version, monotonically increasing." + "version": { + "type": "string", + "pattern": "^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-([0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*))?(?:\\+([0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*))?$", + "description": "Script version following Semantic Versioning" }, "plutusVersion":{ "type":"integer", @@ -199,9 +252,15 @@ "subject", "projectName", "link", + "companyName", + "companyEmail", + "companyWebsite", "social", + "logo", "categories", - "description" - ] - } - \ No newline at end of file + "screenshots", + "description", + "version" + ], + "additionalProperties": false +} diff --git a/CIP-0072/version_1_onchain.cddl b/CIP-0072/version_2.0.0_onchain.cddl similarity index 79% rename from CIP-0072/version_1_onchain.cddl rename to CIP-0072/version_2.0.0_onchain.cddl index f605418180..9219871a5a 100644 --- a/CIP-0072/version_1_onchain.cddl +++ b/CIP-0072/version_2.0.0_onchain.cddl @@ -11,7 +11,6 @@ on-chain_metadata = { rootHash: sig_256, metadata: [+ string] / [+ string / [+ string]], type: registration / de-registration, - signature: signature, } registration = { @@ -22,11 +21,4 @@ registration = { de-registration = { action: "DE_REGISTER", ? comment: string, -} - -signature = { - r: string, - s: string, - algo: text .regexp "Ed25519-EdDSA", - pub: string, -} +} \ No newline at end of file diff --git a/CIP-0072/version_2.0.0_onchain.json b/CIP-0072/version_2.0.0_onchain.json new file mode 100644 index 0000000000..0942715c14 --- /dev/null +++ b/CIP-0072/version_2.0.0_onchain.json @@ -0,0 +1,59 @@ +{ + "$schema":"https://json-schema.org/draft/2020-12/schema", + "$id":"https://example.com/dApp.schema.json", + "title": "Cardano dApp Claim", + "description": "Registration of Cardano dApp claim.", + "type":"object", + "properties":{ + "subject":{ + "type":"string", + "minLength": 1, + "maxLength": 64, + "pattern":"^[0-9a-fA-F]{1,64}$", + "description":"Identifier of the claim subject (dApp). A UTF-8 encoded string, must be max 64 chars. Typically it is randomly generated hash by the dApp developer." + }, + "rootHash":{ + "type":"string", + "minLength": 64, + "maxLength": 64, + "pattern":"^[0-9a-fA-F]{64}$", + "description":"blake2b-256 hash of the metadata describing the off-chain part of the dApp." + }, + "metadata": { + "type": "array", + "description": "Chunks of URLs that make up the dApp's metadata (pointing to off-chain CIP-72) are arranged in an array to accommodate the 64-character limit per chunk, allowing for the support of longer URLs", + "items": { + "type": "string", + "minLength": 1, + "maxLength": 64 + } + }, + "type":{ + "type":"object", + "description":"Describes the releases, if they are new or an updates.", + "properties":{ + "action":{ + "type":"string", + "enum":["REGISTER", "DE_REGISTER"], + "description":"Describes the action this certificate is claiming; i.e 'REGISTER', for a new dApp or an update, DE_REGISTER for asserting that the dApp's development is stopped, and it is deprecated. So, no further dApp's on-chain update is to be expected." + }, + "comment": { + "type": "string", + "minLength": 1, + "maxLength": 64, + "description": "A free text field to provide details about this particular changes (64 chars limited)." + } + }, + "required":[ + "action" + ] + } + }, + "required":[ + "subject", + "rootHash", + "type" + ], + "additionalProperties": false +} + \ No newline at end of file