This repository contains metadata for Agora effects. It contains information about how effect datums are structured, documentation about them, and versioning information.
Effect schemas are each a JSON file containing information about a particular effect script. The top level fields identify and document this effect. An example might look like this:
{
"meta": {
"name": "MintNFT",
"description": "Mints a single NFT based on the provided token name. This NFT is uniquely identified by the UTXO from which the GAT is burned is spent."
},
"scriptHash": "b00f0ebdd6ef98c82f8534b2040cd454c3cf3601b908ce212d43b74b",
"datumSchema": {
"meta": {
"name": "tokenName",
"description": "The token name of the NFT to mint."
},
"type":"string"
}
}
meta
fields each are not important to the actual functioning of the script nor its datum, but instead are useful for frontends to provide information to the user, as well as general documentation that can be placed.
scriptHash
identifies the actual script which this particular schema belongs to. This is done as a script hash.
datumSchema
is the schema that the datums that this script receives in UTXOs (as a result of a proposal passing) should follow. This is the bread and butter of this repo, as it is valuable to prevent wrong use of the script and risk potential loss of funds.
The server provided by this repository is useful for querying the registry and computing validated datums from it.
This will give you information about the server and list out the available scripts.
Example response:
{
"hostedEffectDatumSchemas": [
{
"name": "TreasuryWithdrawal",
"scriptHash": "581caabbccddeeff11223344556677889900aabbccddeeff11223344"
},
{
"name": "MintNFT",
"scriptHash": "b00f0ebdd6ef98c82f8534b2040cd454c3cf3601b908ce212d43b74b"
}
],
"revision": "main@674ccf3fc3a978a164405398b22c14ef1d04c1f2"
}
Queries the raw schema file from those that live in /effects
.
Example response:
{
"meta": {
"name": "MintNFT",
"description": "Mints a single NFT based on the provided token name. This NFT is uniquely identified by the UTXO from which the GAT is burned is spent."
},
"scriptHash": "b00f0ebdd6ef98c82f8534b2040cd454c3cf3601b908ce212d43b74b",
"datumSchema": {
"meta": {
"name": "tokenName",
"description": "The token name of the NFT to mint."
},
"type":"string"
}
}
Encode a datum that follows a particular effect schema into its hex-encoded CBOR representation. This endpoint also ensures the datum passed matches that of the schema it should be checked against, throwing an error if it doesn't.
Example request:
curl \
-X POST \
localhost:3838/encodeEffectDatum/babbccddeeff11223344556677889900aabbccddeeff112233445566 \
-H 'Content-Type: application/json' \
-d '{ "type": "integer", "value": 42 }'
Example response:
{"cborDatum":"182a"}
When writing a datum schema, a number of different building blocks are available to you. These will be listed below.
Example structure:
An integer (I
in PlutusCore.Data
):
{ "type": "integer" }
A bytestring (B
in PlutusCore.Data
):
{ "type": "bytes" }
These two types are primitive types that contain no subvalues inside of the schema. In other words: they are leaves in the schema tree.
A constr tag (Constr
in PlutusCore.Data
). This tags a particular struct with a integer tag. This is particularly useful in combination with oneOf
, to create tagged unions.
Example structure:
{ "type": "constr", "tag": ..., "fields": [..., ...] }
A homogeneous list (List
in PlutusCore.Data
). The elements
field is yet another datum schema type, which represents the type of all elements of this list. Keep in mind that the elements
field is a single type, as opposed to a list of types. This is slightly unintuitive due to the naming. See it as when you write List a
, a
is a single type to which all elements must conform to.
Example structure:
{ "type": "list", "elements": ... }
Example structure:
Represents a heterogeneous list (also List
in PlutusCore.Data
). Unlike list
, this may contain different types for each element, but they are in a particular predetermined order, as given by the elements
field.
{ "type": "shapedList", "elements": [..., ...] }
When representing a tuple of two integers, we could for example encode it like so:
{
"type": "shapedList",
"elements": [
{ "type": "integer" },
{ "type": "integer" }
]
}
In many ways, this is similar to how constr
works, but without the tag.
A map (Map
in PlutusCore.Data
). This maps keys
to values
. Both are homogeneous in their types, so they are a single subschema, similarly to list
.
Example structure:
{
"type": "map",
"keys": ...,
"values": ...
}
oneOf
allows encoding variants into the schema. This will usually be used in combination with constr
in order to encode tagged unions, but can also encode other variants.
Example structure:
{ "type": "oneOf", "options": [..., ...] }
Additionally, the following singleton schema types are available which can be used to represent frequently used plutus types:
plutus/Address
plutus/Value
plutus/Credential
plutus/Hash32
plutus/Hash28
Each can be encoded with additional metadata just like all other types.