From 2fd3d2b05dda32f45e479737d63a9d38b5f6b2a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20C=C3=A1rdenas?= Date: Mon, 23 May 2022 16:29:18 -0500 Subject: [PATCH 01/23] feat: token metadata updates sip --- ...TBD-token-metadata-update-notifications.md | 229 ++++++++++++++++++ .../sip-tbd/token-metadata-update-notify.clar | 30 +++ 2 files changed, 259 insertions(+) create mode 100644 sips/sip-tbd/sip-TBD-token-metadata-update-notifications.md create mode 100644 sips/sip-tbd/token-metadata-update-notify.clar diff --git a/sips/sip-tbd/sip-TBD-token-metadata-update-notifications.md b/sips/sip-tbd/sip-TBD-token-metadata-update-notifications.md new file mode 100644 index 000000000..2f3a59763 --- /dev/null +++ b/sips/sip-tbd/sip-TBD-token-metadata-update-notifications.md @@ -0,0 +1,229 @@ +# Preamble + +SIP Number: TBD + +Title: Notifications for Token Metadata Updates + +Author: Rafael Cárdenas (rafael@hiro.so), Matthew Little (matt@hiro.so) + +Consideration: Technical + +Type: Standard + +Status: Draft + +Created: 17 May 2022 + +License: GPL-3.0 + +Sign-off: TBD + +Layer: Traits + +# Abstract + +As the use of tokens (fungible and non-fungible) has grown in popularity, Stacks developers have +found novel ways to define and use metadata to describe them. This rich data is commonly cached and +indexed for future use in applications such as marketplaces, statistics aggregators, and developer +tools like the [Stacks Blockchain API](https://github.com/hirosystems/stacks-blockchain-api). + +Occasionally, however, this metadata needs to change for a number of reasons: artwork reveals, media +storage migrations, branding updates, etc. As of today, these changes do not have a standardized way +of being propagated through the network for indexers to refresh their cache, so the display of stale +metadata is a very common problem. + +This SIP aims to define a simple mechanism for developers to notify the Stacks network when metadata +for a token has changed, so interested parties can refresh their cache and display up-to-date +information in their applications. + +# Introduction + +Smart contracts that declare NFTs and FTs conform to a standard set of traits used to describe each +token (see [SIP-009](../sip-009/sip-009-nft-standard.md) and +[SIP-010](../sip-010/sip-010-fungible-token-standard.md)). One of these traits is `get-token-uri`, +which should return a URI string that resolves to a token's metadata usually in the form of a JSON +file. There is currently no defined structure for this data, and it is not considered to be +immutable. + +To illustrate a common use of `get-token-uri`, we'll look at the +[`SPSCWDV3RKV5ZRN1FQD84YE1NQFEDJ9R1F4DYQ11.newyorkcitycoin-token-v2`](https://explorer.stacks.co/txid/0x969192220b1c478ef9d18d1cd413d7c79fe02937a9b33af63d441bd5519d1715?chain=mainnet) +contract which declares the NewYorkCityCoin fungible token. + +At the time of writing, the value returned by this contract for `get-token-uri` is the string: +``` +"https://cdn.citycoins.co/metadata/newyorkcitycoin.json" +``` +When this URI is resolved, it returns a JSON file with the following metadata: +```json +{ + "name": "NewYorkCityCoin", + "description": "A CityCoin for New York City, ticker is NYC, Stack it to earn Stacks (STX)", + "image": "https://cdn.citycoins.co/logos/newyorkcitycoin.png" +} +``` +Even though the URI string is fixed, this file lives off-chain so it is concievable that its +contents could change at any point in the future. Additionally, this contract includes a way for its +owners to change this URI via a `var-set` function call: + +```clarity +(define-data-var tokenUri (optional (string-utf8 256)) (some u"https://cdn.citycoins.co/metadata/newyorkcitycoin.json")) + +;; set token URI to new value, only accessible by Auth +(define-public (set-token-uri (newUri (optional (string-utf8 256)))) + (begin + (asserts! (is-authorized-auth) ERR_UNAUTHORIZED) + (ok (var-set tokenUri newUri)) + ) +) +``` + +This setup is very flexible for administrators, but it creates a complex problem for metadata +indexers which now need to figure out if (and when) they should re-index token contracts to avoid +displaying stale metadata in their applications. + + +## Metadata staleness + +Within the Stacks ecosystem, there are a number of applications that need to index token metadata +and struggle with specific challenges caused by changed metadata. For example: + +* An NFT marketplace, which needs to display a token's artwork for users to view. + * Presenting a token's icon correctly is difficult given that the `get-token-uri` on-chain + variable could change, the off-chain JSON file could change, and/or the image served by the URL + could change. +* A [blockchain API](https://github.com/hirosystems/stacks-blockchain-api), which needs to serve FT +metadata to return account balances correctly. + * Wallets require the on-chain decimals value in order to correctly send and receive tokens. + Critical balance draining is possible when this property is zero at contract launch but updated + later. + +For indexing, developers usually run and maintain a background process that listens for new token +contracts deployed to the blockchain so they can immediately call on their metadata to save the +results. This works for new contracts, but it is insufficient for old ones that may change their +metadata after it has been processed. + +To avoid staleness, some indexers resort to a cron-like periodic refresh of all tracked contracts, +but while this may work for individual applications, it does not provide a consistent experience for +Stacks users that may interact with different metadata-aware systems with different refresh periods. +This workaround also adds unnecessary network traffic and creates extra strain on public Stacks +nodes due to aggressively polling contract-read RPC endpoints. + +## Metadata update notifications + +To solve this problem reliably, contract administrators need a way to notify the network when they +have made changes to the metadata so any indexers may then perform a refresh just for that contract. + +The proposed mechanism for these notifications leverages the [`print` Clarity +language function](https://docs.stacks.co/write-smart-contracts/language-functions#print). When +used, its output is bundled inside an event of type `contract_event`: + +```json +{ + "type": "contract_event", + "contract_event": { + "contract_identifier": "", + "topic": "print", + "value": "" + } +} +``` + +This event is then attached to a transaction object and broadcasted when the same transaction is +included in a block or microblock. + +This SIP proposes a standard message structure (similar to a notification payload) that would be +used through `print`. Existing metadata indexers would receive this event through the [Stacks node +event-emitter interface](https://github.com/stacks-network/stacks-blockchain/blob/master/docs/event-dispatcher.md#post-new_block), +parse its contents, and refresh any contracts that were updated. + +# Specification + +Notification messages for each token class are specified below. Token metadata update notifications +must be made via a contract call transaction to the pre-deployed +[reference contract](#reference-implementations) or from a call to `print` within any other +contract, including the token contract itself. + +## Fungible Tokens + +When a contract needs to notify the network that metadata has changed for a **Fungible Token**, it +shall call `print` with a tuple with the following structure: + +```clarity +{ notification: "token-metadata-update", payload: { token-class: "ft", contract-id: }} +``` + +| Key | Value | +|-----------------------|------------------------------------------------------------------------| +| `notification` | The string `"token-metadata-update"` | +| `payload.token-class` | The string `"ft"` | +| `payload.contract-id` | The contract id (principal) of the contract that declared the token | + +## Non-Fungible Tokens + +When a contract needs to notify the network that metadata has changed for a **Non-Fungible Token**, +it shall call `print` with a tuple with the following structure: + +```clarity +{ notification: "token-metadata-update", payload: { token-class: "nft", token-ids: (list u100, u101), contract-id: }} +``` + +| Key | Value | +|-----------------------|------------------------------------------------------------------------| +| `notification` | The string `"token-metadata-update"` | +| `payload.token-class` | The string `"nft"` | +| `payload.token-ids` | A list with the uint token ids that need to be refreshed | +| `payload.contract-id` | The contract id (principal) of the contract that declared the tokens | + +# Backwards compatibility + +Developers who need to update metadata for contracts that were deployed before this SIP is activated +could deploy a new one with a function that broadcasts this message or use the deployed contract +described in [Reference Implementations](#reference-implementations). + +# Activation + +TBD + +# Reference implementations + +A [reference contract](./token-metadata-update-notify.clar) has been deployed to mainnet. It +demonstrates how to send notifications for each token class and it is available for developers to +use for refreshing any existing or future token contract. If the SIP evolves to require a change to +this contract pre-activation, a new one will be deployed and noted here. + +```clarity +;; token-metadata-update-notify +;; +;; Use this contract to notify token metadata indexers that an NFT or FT needs its metadata +;; refreshed. + +(use-trait nft-trait 'SP2PABAF9FTAJYNFZH93XENAJ8FVY99RRM50D2JG9.nft-trait.nft-trait) +(use-trait ft-trait 'SP3FBR2AGK5H9QBDH3EEN6DF8EK8JY7RX8QJ5SVTE.sip-010-trait-ft-standard.sip-010-trait) + +;; Refresh the metadata for one or more NFTs from a specific contract. +(define-public (nft-metadata-update-notify (contract ) (token-ids (list 100 uint))) + (ok (print + { + notification: "token-metadata-update", + payload: { + contract-id: contract, + token-class: "nft", + token-ids: token-ids + } + }))) + +;; Refresh the metadata for a FT from a specific contract +(define-public (ft-metadata-update-notify (contract )) + (ok (print + { + notification: "token-metadata-update", + payload: { + contract-id: contract, + token-class: "ft" + } + }))) +``` + +The [Stacks Blockchain API](https://github.com/hirosystems/stacks-blockchain-api) will also add +compatibility for this standard while this SIP is being considered to demonstrate how indexers can +listen for and react to these notifications. diff --git a/sips/sip-tbd/token-metadata-update-notify.clar b/sips/sip-tbd/token-metadata-update-notify.clar new file mode 100644 index 000000000..5b2a0df23 --- /dev/null +++ b/sips/sip-tbd/token-metadata-update-notify.clar @@ -0,0 +1,30 @@ +;; token-metadata-update-notify +;; +;; Use this contract to notify token metadata indexers that an NFT or FT needs its metadata +;; refreshed. + +(use-trait nft-trait 'SP2PABAF9FTAJYNFZH93XENAJ8FVY99RRM50D2JG9.nft-trait.nft-trait) +(use-trait ft-trait 'SP3FBR2AGK5H9QBDH3EEN6DF8EK8JY7RX8QJ5SVTE.sip-010-trait-ft-standard.sip-010-trait) + +;; Refresh the metadata for one or more NFTs from a specific contract. +(define-public (nft-metadata-update-notify (contract ) (token-ids (list 100 uint))) + (ok (print + { + notification: "token-metadata-update", + payload: { + contract-id: contract, + token-class: "nft", + token-ids: token-ids + } + }))) + +;; Refresh the metadata for a FT from a specific contract +(define-public (ft-metadata-update-notify (contract )) + (ok (print + { + notification: "token-metadata-update", + payload: { + contract-id: contract, + token-class: "ft" + } + }))) From 285d250d7113a1bd3f0eca97f77697d4602c2512 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20C=C3=A1rdenas?= Date: Mon, 23 May 2022 17:52:45 -0500 Subject: [PATCH 02/23] chore: add link to deployed contract --- sips/sip-tbd/sip-TBD-token-metadata-update-notifications.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sips/sip-tbd/sip-TBD-token-metadata-update-notifications.md b/sips/sip-tbd/sip-TBD-token-metadata-update-notifications.md index 2f3a59763..bdc6d98c0 100644 --- a/sips/sip-tbd/sip-TBD-token-metadata-update-notifications.md +++ b/sips/sip-tbd/sip-TBD-token-metadata-update-notifications.md @@ -186,8 +186,9 @@ TBD # Reference implementations -A [reference contract](./token-metadata-update-notify.clar) has been deployed to mainnet. It -demonstrates how to send notifications for each token class and it is available for developers to +A [reference contract](./token-metadata-update-notify.clar) has been [deployed to +mainnet](https://explorer.stacks.co/txid/0xe92af2ea5c11e2e6fde4d31fd394de888070efff23bffad04465c549543abfa2?chain=mainnet). +It demonstrates how to send notifications for each token class and it is available for developers to use for refreshing any existing or future token contract. If the SIP evolves to require a change to this contract pre-activation, a new one will be deployed and noted here. From 2cb43cb131e5c2b754d08c087ef97de2673497df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20C=C3=A1rdenas?= Date: Tue, 24 May 2022 09:20:31 -0500 Subject: [PATCH 03/23] fix: show deployed reference contract id --- .../sip-TBD-token-metadata-update-notifications.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/sips/sip-tbd/sip-TBD-token-metadata-update-notifications.md b/sips/sip-tbd/sip-TBD-token-metadata-update-notifications.md index bdc6d98c0..73820b96c 100644 --- a/sips/sip-tbd/sip-TBD-token-metadata-update-notifications.md +++ b/sips/sip-tbd/sip-TBD-token-metadata-update-notifications.md @@ -139,9 +139,9 @@ parse its contents, and refresh any contracts that were updated. # Specification Notification messages for each token class are specified below. Token metadata update notifications -must be made via a contract call transaction to the pre-deployed -[reference contract](#reference-implementations) or from a call to `print` within any other -contract, including the token contract itself. +must be made via a contract call transaction to the [deployed reference +contract](https://explorer.stacks.co/txid/0xe92af2ea5c11e2e6fde4d31fd394de888070efff23bffad04465c549543abfa2?chain=mainnet) +or from a call to `print` within any other contract, including the token contract itself. ## Fungible Tokens @@ -186,8 +186,8 @@ TBD # Reference implementations -A [reference contract](./token-metadata-update-notify.clar) has been [deployed to -mainnet](https://explorer.stacks.co/txid/0xe92af2ea5c11e2e6fde4d31fd394de888070efff23bffad04465c549543abfa2?chain=mainnet). +A [reference contract](./token-metadata-update-notify.clar) has been deployed to mainnet as +[`SP1H6HY2ZPSFPZF6HBNADAYKQ2FJN75GHVV95YZQ.token-metadata-update-notify`](https://explorer.stacks.co/txid/0xe92af2ea5c11e2e6fde4d31fd394de888070efff23bffad04465c549543abfa2?chain=mainnet). It demonstrates how to send notifications for each token class and it is available for developers to use for refreshing any existing or future token contract. If the SIP evolves to require a change to this contract pre-activation, a new one will be deployed and noted here. From ca63cb56d6eb95fa066c0d6696a11ff58f40afec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20C=C3=A1rdenas?= Date: Tue, 24 May 2022 09:33:49 -0500 Subject: [PATCH 04/23] fix: add legend about message reusability --- sips/sip-tbd/sip-TBD-token-metadata-update-notifications.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sips/sip-tbd/sip-TBD-token-metadata-update-notifications.md b/sips/sip-tbd/sip-TBD-token-metadata-update-notifications.md index 73820b96c..85a55590d 100644 --- a/sips/sip-tbd/sip-TBD-token-metadata-update-notifications.md +++ b/sips/sip-tbd/sip-TBD-token-metadata-update-notifications.md @@ -143,6 +143,9 @@ must be made via a contract call transaction to the [deployed reference contract](https://explorer.stacks.co/txid/0xe92af2ea5c11e2e6fde4d31fd394de888070efff23bffad04465c549543abfa2?chain=mainnet) or from a call to `print` within any other contract, including the token contract itself. +The message structure was designed to be reusable by other SIPs who wish to establish new +notification standards in the future (i.e. by varying the `notification` and `payload` key values). + ## Fungible Tokens When a contract needs to notify the network that metadata has changed for a **Fungible Token**, it From 3530f2751b910e72eac87bf38a0123cb480c3e22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20C=C3=A1rdenas?= Date: Tue, 24 May 2022 14:36:00 -0500 Subject: [PATCH 05/23] chore: include activation proposal --- sips/sip-tbd/sip-TBD-token-metadata-update-notifications.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sips/sip-tbd/sip-TBD-token-metadata-update-notifications.md b/sips/sip-tbd/sip-TBD-token-metadata-update-notifications.md index 85a55590d..34353073c 100644 --- a/sips/sip-tbd/sip-TBD-token-metadata-update-notifications.md +++ b/sips/sip-tbd/sip-TBD-token-metadata-update-notifications.md @@ -185,7 +185,8 @@ described in [Reference Implementations](#reference-implementations). # Activation -TBD +This SIP will be activated when at least 10 unique contracts have had metadata updates triggered via +contract-call transactions that print the proposed notification payload. # Reference implementations From 104740922f107cf67f6167d34ea3e6b3934cd62d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20C=C3=A1rdenas?= Date: Mon, 30 May 2022 22:50:41 -0500 Subject: [PATCH 06/23] fix: backwards comp and activation --- .../sip-TBD-token-metadata-update-notifications.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/sips/sip-tbd/sip-TBD-token-metadata-update-notifications.md b/sips/sip-tbd/sip-TBD-token-metadata-update-notifications.md index 34353073c..a610e90ec 100644 --- a/sips/sip-tbd/sip-TBD-token-metadata-update-notifications.md +++ b/sips/sip-tbd/sip-TBD-token-metadata-update-notifications.md @@ -179,14 +179,16 @@ it shall call `print` with a tuple with the following structure: # Backwards compatibility -Developers who need to update metadata for contracts that were deployed before this SIP is activated -could deploy a new one with a function that broadcasts this message or use the deployed contract -described in [Reference Implementations](#reference-implementations). +Developers who need to emit metadata update notifications for tokens declared in older contracts +(that were deployed before this notification standard was established) could do so by either calling +the contract described in [Reference Implementations](#reference-implementations) or by deploying a +new separate contract containing a public function that emits this notification. # Activation This SIP will be activated when at least 10 unique contracts have had metadata updates triggered via -contract-call transactions that print the proposed notification payload. +contract-call transactions that print the proposed notification payload. If the Stacks blockchain +reaches block height 170000 and this has not happened, this SIP will be considered rejected. # Reference implementations From b0a8895eab3d822c5db059873888ee91f4db1bbe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20C=C3=A1rdenas?= Date: Mon, 30 May 2022 23:36:52 -0500 Subject: [PATCH 07/23] feat: add considerations for indexers --- ...TBD-token-metadata-update-notifications.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/sips/sip-tbd/sip-TBD-token-metadata-update-notifications.md b/sips/sip-tbd/sip-TBD-token-metadata-update-notifications.md index a610e90ec..fdca21681 100644 --- a/sips/sip-tbd/sip-TBD-token-metadata-update-notifications.md +++ b/sips/sip-tbd/sip-TBD-token-metadata-update-notifications.md @@ -177,6 +177,25 @@ it shall call `print` with a tuple with the following structure: | `payload.token-ids` | A list with the uint token ids that need to be refreshed | | `payload.contract-id` | The contract id (principal) of the contract that declared the tokens | +## Considerations for metadata indexers + +Metadata indexers should review the following implications when reacting to token metadata update +notifications: + +* Notifications can come at any point in time and are persistent in the Stacks blockchain. + * When performing a local sync to the chain tip, old notifications for old metadata updates could + not necessarily have a distinct effect in metadata responses when processed in the present. +* Multiple notifications for the same tokens will not necessarily correspond to multiple metadata + updates. + * Refreshing a token's metadata should be an idempotent operation. Repeated refreshes should not + create distinct records in the internal metadata database. +* Notifications could be gratuitous. + * To prevent slow performance and guard against any Denial of Service attack attempts, contract + call rate limiting should be implemented locally. +* Notifications can be delayed and out of order. + * A notification transaction's timestamp should not be considered to be the time when the token + metadata was actually updated. + # Backwards compatibility Developers who need to emit metadata update notifications for tokens declared in older contracts From 67de4172b6a3d5d538ab865849b0939780ebc14c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20C=C3=A1rdenas?= Date: Wed, 8 Jun 2022 14:53:55 -0500 Subject: [PATCH 08/23] feat: call it sip 019 --- .../sip-019-token-metadata-update-notifications.md} | 6 +++--- sips/{sip-tbd => sip-019}/token-metadata-update-notify.clar | 0 2 files changed, 3 insertions(+), 3 deletions(-) rename sips/{sip-tbd/sip-TBD-token-metadata-update-notifications.md => sip-019/sip-019-token-metadata-update-notifications.md} (99%) rename sips/{sip-tbd => sip-019}/token-metadata-update-notify.clar (100%) diff --git a/sips/sip-tbd/sip-TBD-token-metadata-update-notifications.md b/sips/sip-019/sip-019-token-metadata-update-notifications.md similarity index 99% rename from sips/sip-tbd/sip-TBD-token-metadata-update-notifications.md rename to sips/sip-019/sip-019-token-metadata-update-notifications.md index fdca21681..214f5b08c 100644 --- a/sips/sip-tbd/sip-TBD-token-metadata-update-notifications.md +++ b/sips/sip-019/sip-019-token-metadata-update-notifications.md @@ -1,6 +1,6 @@ # Preamble -SIP Number: TBD +SIP Number: 019 Title: Notifications for Token Metadata Updates @@ -10,13 +10,13 @@ Consideration: Technical Type: Standard -Status: Draft +Status: Accepted Created: 17 May 2022 License: GPL-3.0 -Sign-off: TBD +Sign-off: Jude Nelson Layer: Traits diff --git a/sips/sip-tbd/token-metadata-update-notify.clar b/sips/sip-019/token-metadata-update-notify.clar similarity index 100% rename from sips/sip-tbd/token-metadata-update-notify.clar rename to sips/sip-019/token-metadata-update-notify.clar From f98033908076917992a657943a82d90258c70e41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20C=C3=A1rdenas?= Date: Thu, 9 Jun 2022 11:09:32 -0500 Subject: [PATCH 09/23] chore: fix typo --- sips/sip-019/sip-019-token-metadata-update-notifications.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sips/sip-019/sip-019-token-metadata-update-notifications.md b/sips/sip-019/sip-019-token-metadata-update-notifications.md index 214f5b08c..60e0e0b3b 100644 --- a/sips/sip-019/sip-019-token-metadata-update-notifications.md +++ b/sips/sip-019/sip-019-token-metadata-update-notifications.md @@ -61,7 +61,7 @@ When this URI is resolved, it returns a JSON file with the following metadata: "image": "https://cdn.citycoins.co/logos/newyorkcitycoin.png" } ``` -Even though the URI string is fixed, this file lives off-chain so it is concievable that its +Even though the URI string is fixed, this file lives off-chain so it is conceivable that its contents could change at any point in the future. Additionally, this contract includes a way for its owners to change this URI via a `var-set` function call: From 429f436e0a983b4c9525d21b986dd375372f8269 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20C=C3=A1rdenas?= Date: Thu, 9 Jun 2022 11:21:37 -0500 Subject: [PATCH 10/23] fix: add more activation criteria --- ...019-token-metadata-update-notifications.md | 20 ++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/sips/sip-019/sip-019-token-metadata-update-notifications.md b/sips/sip-019/sip-019-token-metadata-update-notifications.md index 60e0e0b3b..8e7d5ebe2 100644 --- a/sips/sip-019/sip-019-token-metadata-update-notifications.md +++ b/sips/sip-019/sip-019-token-metadata-update-notifications.md @@ -196,18 +196,28 @@ notifications: * A notification transaction's timestamp should not be considered to be the time when the token metadata was actually updated. +Given these constraints the notifications this SIP proposes should be taken as _hints_ to metadata +indexers. Metadata indexers are not obliged to follow them. + # Backwards compatibility Developers who need to emit metadata update notifications for tokens declared in older contracts (that were deployed before this notification standard was established) could do so by either calling -the contract described in [Reference Implementations](#reference-implementations) or by deploying a -new separate contract containing a public function that emits this notification. +the contract described in [Reference Implementations](#reference-implementations) or by first +deploying a new separate contract containing a public function that prints this notification and +then calling it to have it emitted. # Activation -This SIP will be activated when at least 10 unique contracts have had metadata updates triggered via -contract-call transactions that print the proposed notification payload. If the Stacks blockchain -reaches block height 170000 and this has not happened, this SIP will be considered rejected. +This SIP will be activated when the following conditions are met: + +1. At least 10 unique contracts have had metadata updates triggered via contract-call transactions + that print the proposed notification payload. +1. At least 3 metadata indexers (like the Stacks Blockchain API or an NFT marketplace) start + listening for and reacting to the emitted notifications. + +If the Stacks blockchain reaches block height 170000 and the above has not happened, this SIP will +be considered rejected. # Reference implementations From 001a9273d3c3caf45f3d1d850115186311140916 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20C=C3=A1rdenas?= Date: Mon, 13 Jun 2022 10:40:54 -0500 Subject: [PATCH 11/23] chore: add notification requirements section --- ...-019-token-metadata-update-notifications.md | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/sips/sip-019/sip-019-token-metadata-update-notifications.md b/sips/sip-019/sip-019-token-metadata-update-notifications.md index 8e7d5ebe2..505faa13a 100644 --- a/sips/sip-019/sip-019-token-metadata-update-notifications.md +++ b/sips/sip-019/sip-019-token-metadata-update-notifications.md @@ -134,7 +134,7 @@ included in a block or microblock. This SIP proposes a standard message structure (similar to a notification payload) that would be used through `print`. Existing metadata indexers would receive this event through the [Stacks node event-emitter interface](https://github.com/stacks-network/stacks-blockchain/blob/master/docs/event-dispatcher.md#post-new_block), -parse its contents, and refresh any contracts that were updated. +parse and validate its contents, and refresh any contracts that were updated. # Specification @@ -179,8 +179,19 @@ it shall call `print` with a tuple with the following structure: ## Considerations for metadata indexers -Metadata indexers should review the following implications when reacting to token metadata update -notifications: +For a token metadata update notification to be considered valid by metadata indexers, it must meet +the following requirements: + +1. Its payload structure should be correct whether it is updating a [FT](#fungible-tokens) or a + [NFT](#non-fungible-tokens). +1. The STX address that initiated the contract call which emits the notification should match the + owner of the token contract being updated. + * The transaction's `sender_address` principal should match the principal contained in the + notification's `payload.contract-id`. + +Notifications that do not meet these requirements must be ignored. + +### Other implications * Notifications can come at any point in time and are persistent in the Stacks blockchain. * When performing a local sync to the chain tip, old notifications for old metadata updates could @@ -189,7 +200,6 @@ notifications: updates. * Refreshing a token's metadata should be an idempotent operation. Repeated refreshes should not create distinct records in the internal metadata database. -* Notifications could be gratuitous. * To prevent slow performance and guard against any Denial of Service attack attempts, contract call rate limiting should be implemented locally. * Notifications can be delayed and out of order. From 4355e623072d72ee43bfd9ff8530d2bf2d70622a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20C=C3=A1rdenas?= Date: Mon, 13 Jun 2022 11:13:26 -0500 Subject: [PATCH 12/23] chore: mark token-ids as optional for nfts --- sips/sip-019/sip-019-token-metadata-update-notifications.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sips/sip-019/sip-019-token-metadata-update-notifications.md b/sips/sip-019/sip-019-token-metadata-update-notifications.md index 505faa13a..f3719372d 100644 --- a/sips/sip-019/sip-019-token-metadata-update-notifications.md +++ b/sips/sip-019/sip-019-token-metadata-update-notifications.md @@ -174,9 +174,12 @@ it shall call `print` with a tuple with the following structure: |-----------------------|------------------------------------------------------------------------| | `notification` | The string `"token-metadata-update"` | | `payload.token-class` | The string `"nft"` | -| `payload.token-ids` | A list with the uint token ids that need to be refreshed | +| `payload.token-ids` | (optional) A list with the uint token ids that need to be refreshed | | `payload.contract-id` | The contract id (principal) of the contract that declared the tokens | +If a notification does not contain a value for `payload.token-ids`, it means it is requesting an +update for all tokens. + ## Considerations for metadata indexers For a token metadata update notification to be considered valid by metadata indexers, it must meet From 66619cdd48304bea83955adb0d1906db0fbfd26e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20C=C3=A1rdenas?= Date: Mon, 13 Jun 2022 11:27:53 -0500 Subject: [PATCH 13/23] fix: tx-sender --- sips/sip-019/sip-019-token-metadata-update-notifications.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sips/sip-019/sip-019-token-metadata-update-notifications.md b/sips/sip-019/sip-019-token-metadata-update-notifications.md index f3719372d..f3e34ebf5 100644 --- a/sips/sip-019/sip-019-token-metadata-update-notifications.md +++ b/sips/sip-019/sip-019-token-metadata-update-notifications.md @@ -189,7 +189,7 @@ the following requirements: [NFT](#non-fungible-tokens). 1. The STX address that initiated the contract call which emits the notification should match the owner of the token contract being updated. - * The transaction's `sender_address` principal should match the principal contained in the + * The transaction's `tx-sender` principal should match the principal contained in the notification's `payload.contract-id`. Notifications that do not meet these requirements must be ignored. From 364a5ad413b349beef5d8f45dd5b5d47c3de87fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20C=C3=A1rdenas?= Date: Tue, 14 Jun 2022 11:26:20 -0500 Subject: [PATCH 14/23] feat: add related work section --- ...019-token-metadata-update-notifications.md | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/sips/sip-019/sip-019-token-metadata-update-notifications.md b/sips/sip-019/sip-019-token-metadata-update-notifications.md index f3e34ebf5..373287563 100644 --- a/sips/sip-019/sip-019-token-metadata-update-notifications.md +++ b/sips/sip-019/sip-019-token-metadata-update-notifications.md @@ -212,6 +212,26 @@ Notifications that do not meet these requirements must be ignored. Given these constraints the notifications this SIP proposes should be taken as _hints_ to metadata indexers. Metadata indexers are not obliged to follow them. +# Related work + +An alternative considered for token metadata update notifications is for them to be transmitted via +an off-chain notification service such as an official mailing list or a forum post. While this +channel would have had the advantage of being easier to update and faster to propagate, it has a few +key disadvantages that make it inadequate for this SIP's intended use: + +1. It introduces a third party dependency + * An off-chain notification service would most likely be maintained by centralized entities + unrelated to the Stacks ecosystem which at any time may modify the channel, its reach, or its + rules. +1. It does not leave a permanent record in the blockchain + * If a new network participant wishes to recreate the entire Stacks chain history, they will not + be able to determine at which points metadata was updated for tokens without having to query + the off-chain notification service and performing a manual match. +1. It is not future proof + * It the selected off-chain service changes at any point, a migration to another notification + channel will be much more difficult once the Stacks ecosystem has more token applications and + metadata indexers. + # Backwards compatibility Developers who need to emit metadata update notifications for tokens declared in older contracts From d322848c554e6d2fde743ca4a343288871f316c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20C=C3=A1rdenas?= Date: Fri, 17 Jun 2022 11:12:40 -0500 Subject: [PATCH 15/23] chore: rewrite related work portions --- ...019-token-metadata-update-notifications.md | 29 +++++++++++-------- 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/sips/sip-019/sip-019-token-metadata-update-notifications.md b/sips/sip-019/sip-019-token-metadata-update-notifications.md index 373287563..c7f459fce 100644 --- a/sips/sip-019/sip-019-token-metadata-update-notifications.md +++ b/sips/sip-019/sip-019-token-metadata-update-notifications.md @@ -215,20 +215,25 @@ indexers. Metadata indexers are not obliged to follow them. # Related work An alternative considered for token metadata update notifications is for them to be transmitted via -an off-chain notification service such as an official mailing list or a forum post. While this -channel would have had the advantage of being easier to update and faster to propagate, it has a few -key disadvantages that make it inadequate for this SIP's intended use: +an off-chain notification service that indexer developers may subscribe to, such as: -1. It introduces a third party dependency +* An official mailing list +* A forum post +* An authoritative API service + +While these channels would have several advantages like being simpler to update, faster to +propagate, and easier to moderate, they have key disadvantages that make them inadequate for this +SIP's intended use: + +1. They introduce a third party dependency * An off-chain notification service would most likely be maintained by centralized entities - unrelated to the Stacks ecosystem which at any time may modify the channel, its reach, or its - rules. -1. It does not leave a permanent record in the blockchain - * If a new network participant wishes to recreate the entire Stacks chain history, they will not - be able to determine at which points metadata was updated for tokens without having to query - the off-chain notification service and performing a manual match. -1. It is not future proof - * It the selected off-chain service changes at any point, a migration to another notification + unrelated to the Stacks ecosystem. As such, they could modify the channel, its reach, or its + rules at any time while affecting the entire network. + * Accepting third party solutions would invite developers to use many different hinting service + APIs and implementations, defeating the standardization purpose of this SIP. Moving + notifications to the blockchain establishes a canonical way to store and access them. +1. They are not future proof + * If the selected off-chain service changes at any point, a migration to another notification channel will be much more difficult once the Stacks ecosystem has more token applications and metadata indexers. From 960c8a5f418403c499d6f2690474f0d5a686f379 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20C=C3=A1rdenas?= Date: Wed, 22 Jun 2022 18:08:05 -0500 Subject: [PATCH 16/23] chore: expand on future reusability --- .../sip-019-token-metadata-update-notifications.md | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/sips/sip-019/sip-019-token-metadata-update-notifications.md b/sips/sip-019/sip-019-token-metadata-update-notifications.md index c7f459fce..c94cde1e0 100644 --- a/sips/sip-019/sip-019-token-metadata-update-notifications.md +++ b/sips/sip-019/sip-019-token-metadata-update-notifications.md @@ -143,9 +143,6 @@ must be made via a contract call transaction to the [deployed reference contract](https://explorer.stacks.co/txid/0xe92af2ea5c11e2e6fde4d31fd394de888070efff23bffad04465c549543abfa2?chain=mainnet) or from a call to `print` within any other contract, including the token contract itself. -The message structure was designed to be reusable by other SIPs who wish to establish new -notification standards in the future (i.e. by varying the `notification` and `payload` key values). - ## Fungible Tokens When a contract needs to notify the network that metadata has changed for a **Fungible Token**, it @@ -212,6 +209,15 @@ Notifications that do not meet these requirements must be ignored. Given these constraints the notifications this SIP proposes should be taken as _hints_ to metadata indexers. Metadata indexers are not obliged to follow them. +## Notification structure reusability + +Even though establishing a generalized smart contract notification standard is out of scope for this +SIP, the proposed `print` message structure was designed for reusability by future SIPs that wish to +standardize other events. + +For example, developers could vary the `notification` and `payload` values to notify the network +when an NFT collection has been fully minted or another important milestone is reached. + # Related work An alternative considered for token metadata update notifications is for them to be transmitted via From a0d985ee8debe3f943594a4b738af1465e70d92e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20C=C3=A1rdenas?= Date: Thu, 30 Jun 2022 13:49:50 -0500 Subject: [PATCH 17/23] fix: tweak valid notification conditions --- .../sip-019-token-metadata-update-notifications.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/sips/sip-019/sip-019-token-metadata-update-notifications.md b/sips/sip-019/sip-019-token-metadata-update-notifications.md index c94cde1e0..365a09e1d 100644 --- a/sips/sip-019/sip-019-token-metadata-update-notifications.md +++ b/sips/sip-019/sip-019-token-metadata-update-notifications.md @@ -184,10 +184,11 @@ the following requirements: 1. Its payload structure should be correct whether it is updating a [FT](#fungible-tokens) or a [NFT](#non-fungible-tokens). -1. The STX address that initiated the contract call which emits the notification should match the - owner of the token contract being updated. - * The transaction's `tx-sender` principal should match the principal contained in the - notification's `payload.contract-id`. +1. Either the `contract_identifier` field of the contract event must be equal to the + `payload.contract-id` (i.e., the event was produced by the contract that owns the metadata) or + the transaction's `tx-sender` principal should match the principal contained in the + notification's `payload.contract-id` (i.e., the STX address that sent the transaction which emits + the notification should match the owner of the token contract being updated). Notifications that do not meet these requirements must be ignored. From 6f3fc160132cb1061e9d18a591e35c635d28f5b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20C=C3=A1rdenas?= Date: Thu, 30 Jun 2022 13:52:03 -0500 Subject: [PATCH 18/23] feat: add aaron to sign-off --- sips/sip-019/sip-019-token-metadata-update-notifications.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sips/sip-019/sip-019-token-metadata-update-notifications.md b/sips/sip-019/sip-019-token-metadata-update-notifications.md index 365a09e1d..84bf57432 100644 --- a/sips/sip-019/sip-019-token-metadata-update-notifications.md +++ b/sips/sip-019/sip-019-token-metadata-update-notifications.md @@ -16,7 +16,7 @@ Created: 17 May 2022 License: GPL-3.0 -Sign-off: Jude Nelson +Sign-off: Jude Nelson (jude@stacks.org), Aaron Blankstein (aaron@hiro.so) Layer: Traits From 478685c99467ad204660a5dc9258f35404882af0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20C=C3=A1rdenas?= Date: Thu, 30 Jun 2022 13:54:29 -0500 Subject: [PATCH 19/23] feat: move status to activation-in-progress --- sips/sip-019/sip-019-token-metadata-update-notifications.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sips/sip-019/sip-019-token-metadata-update-notifications.md b/sips/sip-019/sip-019-token-metadata-update-notifications.md index 84bf57432..65bdf2bb9 100644 --- a/sips/sip-019/sip-019-token-metadata-update-notifications.md +++ b/sips/sip-019/sip-019-token-metadata-update-notifications.md @@ -10,7 +10,7 @@ Consideration: Technical Type: Standard -Status: Accepted +Status: Activation-in-Progress Created: 17 May 2022 From 28b3d0a706429ff0c98fd1eb749ee0d8fd3889b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20C=C3=A1rdenas?= Date: Sat, 15 Oct 2022 11:35:39 -0500 Subject: [PATCH 20/23] feat: add update modes --- ...019-token-metadata-update-notifications.md | 35 ++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/sips/sip-019/sip-019-token-metadata-update-notifications.md b/sips/sip-019/sip-019-token-metadata-update-notifications.md index 65bdf2bb9..319b14c1b 100644 --- a/sips/sip-019/sip-019-token-metadata-update-notifications.md +++ b/sips/sip-019/sip-019-token-metadata-update-notifications.md @@ -157,6 +157,8 @@ shall call `print` with a tuple with the following structure: | `notification` | The string `"token-metadata-update"` | | `payload.token-class` | The string `"ft"` | | `payload.contract-id` | The contract id (principal) of the contract that declared the token | +| `payload.update-mode` | _[optional]_ Metadata update mode (see section below) | +| `payload.ttl` | _[optional]_ Time-to-live for `payload.update-mode: dynamic` | ## Non-Fungible Tokens @@ -171,12 +173,43 @@ it shall call `print` with a tuple with the following structure: |-----------------------|------------------------------------------------------------------------| | `notification` | The string `"token-metadata-update"` | | `payload.token-class` | The string `"nft"` | -| `payload.token-ids` | (optional) A list with the uint token ids that need to be refreshed | | `payload.contract-id` | The contract id (principal) of the contract that declared the tokens | +| `payload.token-ids` | _[optional]_ A list with the uint token ids that need to be refreshed | +| `payload.update-mode` | _[optional]_ Metadata update mode (see section below) | +| `payload.ttl` | _[optional]_ Time-to-live for `payload.update-mode: dynamic` | If a notification does not contain a value for `payload.token-ids`, it means it is requesting an update for all tokens. +## Metadata update modes + +Applications may use tokens for very different purposes. Some of these could require none or very +few metadata updates ever (e.g. digital artwork that never changes except for reveals), while others +could need to alter it several times a day (e.g. NFTs for in-game items that are traded and modded +continuously). + +This use-case variety also affects how developers decide to host their metadata JSON files. For +example, they could choose to use IPFS for low-frequency updates and finality, versus Amazon S3 for +high-frequency off-chain updates. + +In order to allow creators and app developers to specify how token metadata should be treated by +indexers, notifications support an optional `payload.update-mode` key that may contain one of the +following values: + +* `standard`: The new metadata will be valid until the next notification comes. + + This is the default mode if none is specified. +* `frozen`: This token's metadata will never change again, ever. + + Indexers should ignore new notifications for this token, even if valid. +* `dynamic`: The new metadata is expected to change very quickly and many times in the future (even + off-chain). + + Indexers should not expect to receive explicit notifications for each of these changes and +should consider refreshing this token's metadata frequently. Token developers may suggest a +reasonable amount of time between refreshes by adding an estimated value (defined in seconds) to the +`payload.ttl` notification property. + ## Considerations for metadata indexers For a token metadata update notification to be considered valid by metadata indexers, it must meet From 60164aaa5d2b702057dfe4a660fe9a8f926fe9cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20C=C3=A1rdenas?= Date: Sun, 16 Oct 2022 10:01:17 -0500 Subject: [PATCH 21/23] feat: expand print advantages --- ...019-token-metadata-update-notifications.md | 21 +++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/sips/sip-019/sip-019-token-metadata-update-notifications.md b/sips/sip-019/sip-019-token-metadata-update-notifications.md index 319b14c1b..7512b3d8e 100644 --- a/sips/sip-019/sip-019-token-metadata-update-notifications.md +++ b/sips/sip-019/sip-019-token-metadata-update-notifications.md @@ -133,8 +133,23 @@ included in a block or microblock. This SIP proposes a standard message structure (similar to a notification payload) that would be used through `print`. Existing metadata indexers would receive this event through the [Stacks node -event-emitter interface](https://github.com/stacks-network/stacks-blockchain/blob/master/docs/event-dispatcher.md#post-new_block), -parse and validate its contents, and refresh any contracts that were updated. +event-emitter +interface](https://github.com/stacks-network/stacks-blockchain/blob/master/docs/event-dispatcher.md#post-new_block), +parse and validate its contents, and refresh any contracts that were updated. `print` was also +selected for the following reasons: + +1. There is precedent for the use of `print` notifications in the Stacks ecosystem: the BNS +contract, for example, uses it to notify the network when a change to a name or its zonefile has +occurred. The PoX-2 contract for Stacks 2.1 will make heavy use of it to record stacking state +changes across addresses. This SIP aims to continue this trend. +1. For chain indexers, consuming it is practically free if they already process transactions. This +would enable, for example, a notification to be clearly displayed in the Stacks Explorer alongside +its transaction. +1. Adding a `print` notification to a function's Clarity code also serves as self-explanatory + documentation. +1. If there is a new notification use case in the future, a newer SIP can propose an additional + `print` structure and indexers would be quick to adopt these if they need to. See [Notification + structure reusability](#notification-structure-reusability). # Specification @@ -272,6 +287,8 @@ SIP's intended use: * Accepting third party solutions would invite developers to use many different hinting service APIs and implementations, defeating the standardization purpose of this SIP. Moving notifications to the blockchain establishes a canonical way to store and access them. + * Even if a decentralized off-chain third-party solution is found, it could still add a layer + of friction for developer adoption. 1. They are not future proof * If the selected off-chain service changes at any point, a migration to another notification channel will be much more difficult once the Stacks ecosystem has more token applications and From fdca993d81af1444e32b8780cd545de1e4361a8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20C=C3=A1rdenas?= Date: Fri, 10 Mar 2023 14:21:27 -0600 Subject: [PATCH 22/23] feat: include specification for sft updates --- ...019-token-metadata-update-notifications.md | 37 +++++++++++++++---- 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/sips/sip-019/sip-019-token-metadata-update-notifications.md b/sips/sip-019/sip-019-token-metadata-update-notifications.md index 7512b3d8e..fdb63a3e3 100644 --- a/sips/sip-019/sip-019-token-metadata-update-notifications.md +++ b/sips/sip-019/sip-019-token-metadata-update-notifications.md @@ -38,12 +38,13 @@ information in their applications. # Introduction -Smart contracts that declare NFTs and FTs conform to a standard set of traits used to describe each -token (see [SIP-009](../sip-009/sip-009-nft-standard.md) and -[SIP-010](../sip-010/sip-010-fungible-token-standard.md)). One of these traits is `get-token-uri`, -which should return a URI string that resolves to a token's metadata usually in the form of a JSON -file. There is currently no defined structure for this data, and it is not considered to be -immutable. +Smart contracts that declare NFTs, FTs and SFTs conform to a standard set of traits used to describe +each token (see [SIP-009](../sip-009/sip-009-nft-standard.md), +[SIP-010](../sip-010/sip-010-fungible-token-standard.md) and +[SIP-013](https://github.com/stacksgov/sips/blob/main/sips/sip-013/sip-013-semi-fungible-token-standard.md)). +One of these traits is `get-token-uri`, which should return a URI string that resolves to a token's +metadata usually in the form of a JSON file. There is currently no defined structure for this data, +and it is not considered to be immutable. To illustrate a common use of `get-token-uri`, we'll look at the [`SPSCWDV3RKV5ZRN1FQD84YE1NQFEDJ9R1F4DYQ11.newyorkcitycoin-token-v2`](https://explorer.stacks.co/txid/0x969192220b1c478ef9d18d1cd413d7c79fe02937a9b33af63d441bd5519d1715?chain=mainnet) @@ -196,6 +197,26 @@ it shall call `print` with a tuple with the following structure: If a notification does not contain a value for `payload.token-ids`, it means it is requesting an update for all tokens. +## Semi-Fungible Tokens + +When a contract needs to notify the network that metadata has changed for a **Semi-Fungible Token**, +it shall call `print` with a tuple with the following structure: + +```clarity +{ notification: "token-metadata-update", payload: { token-class: "sft", token-ids: (list u100, u101), contract-id: }} +``` + +| Key | Value | +|-----------------------|------------------------------------------------------------------------| +| `notification` | The string `"token-metadata-update"` | +| `payload.token-class` | The string `"sft"` | +| `payload.contract-id` | The contract id (principal) of the contract that declared the tokens | +| `payload.token-ids` | A list with the uint token ids that need to be refreshed | +| `payload.update-mode` | _[optional]_ Metadata update mode (see section below) | +| `payload.ttl` | _[optional]_ Time-to-live for `payload.update-mode: dynamic` | + +Notifications for SFTs must include a value for `payload.token-ids`. + ## Metadata update modes Applications may use tokens for very different purposes. Some of these could require none or very @@ -230,8 +251,8 @@ reasonable amount of time between refreshes by adding an estimated value (define For a token metadata update notification to be considered valid by metadata indexers, it must meet the following requirements: -1. Its payload structure should be correct whether it is updating a [FT](#fungible-tokens) or a - [NFT](#non-fungible-tokens). +1. Its payload structure should be correct whether it is updating a [FT](#fungible-tokens), an + [NFT](#non-fungible-tokens) or an [SFT](#semi-fungible-tokens). 1. Either the `contract_identifier` field of the contract event must be equal to the `payload.contract-id` (i.e., the event was produced by the contract that owns the metadata) or the transaction's `tx-sender` principal should match the principal contained in the From 72e9d3ccd7db86002c8606e9d9ac55d305dde49e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20C=C3=A1rdenas?= Date: Fri, 9 Jun 2023 13:07:14 -0500 Subject: [PATCH 23/23] chore: update status to Ratified --- sips/sip-019/sip-019-token-metadata-update-notifications.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sips/sip-019/sip-019-token-metadata-update-notifications.md b/sips/sip-019/sip-019-token-metadata-update-notifications.md index fdb63a3e3..f76cf1047 100644 --- a/sips/sip-019/sip-019-token-metadata-update-notifications.md +++ b/sips/sip-019/sip-019-token-metadata-update-notifications.md @@ -10,13 +10,13 @@ Consideration: Technical Type: Standard -Status: Activation-in-Progress +Status: Ratified Created: 17 May 2022 License: GPL-3.0 -Sign-off: Jude Nelson (jude@stacks.org), Aaron Blankstein (aaron@hiro.so) +Sign-off: Jude Nelson (jude@stacks.org), Aaron Blankstein (aaron@hiro.so), Marvin Janssen (http://github.com/MarvinJanssen) Layer: Traits