Skip to content

Latest commit

 

History

History
168 lines (110 loc) · 6.04 KB

File metadata and controls

168 lines (110 loc) · 6.04 KB

Info Action Procedure

Here we intend to document the script and steps within to build a new Info action and submit it in a transaction.

Steps

1. Author new metadata via Google Docs

Using the Google Docs template:

2. Export markdown file

Export your metadata from Google Docs as markdown file (.md).

3. Set environment variables

Set secrets, you can use the .env file for this.

source ./scripts/.env

Optionally you can some variables to be reused.

export DEPOSIT_RETURN_ADDR="my-address"

Make sure that CARDANO_NODE_NETWORK_ID and CARDANO_NODE_SOCKET_PATH are set. These are needed to build the governance action file.

4. Create the metadata document

Convert the .md to intersect's metadata standard (this is a modified CIP-108 document).

With the metadata-create script taking the data from the doc and creating a .jsonld.

The input file must be a .md file structured with H2 headers (## Title, ## Abstract, ## Motivation, ## Rationale, ## References, ## Authors). Pass --language <BCP-47-tag> to override the default en in the generated @context.@language.

./scripts/metadata-create.sh my-metadata.md --governance-action-type info --deposit-return-addr $DEPOSIT_RETURN_ADDR

5. Sanity check the metadata

Generate a(nother) markdown representation from the created .jsonld and manually compare against the .docx.

./scripts/cip-108-markdown.sh my-metadata.jsonld

6. Validate the metadata

We can then run our validation script to check

  • compliance with CIP schema(s)
  • compliance with Intersect schemas
  • spell check (aspell personal dictionary fetched from the main branch of this repo at runtime; skip with --no-spell-check)
  • URI reachability for every uri/url field plus markdown links and bare URLs inside prose fields; ipfs://<cid> is resolved via $IPFS_GATEWAY_URI (fallback https://ipfs.io). Skip with --no-check-links.
  • body.title length ≤ 80 and body.abstract length ≤ 2500 characters (when those fields are present)

Because the metadata at this point in the procedure has not yet been signed, run with --draft:

./scripts/metadata-validate.sh my-metadata.jsonld --cip108 --cip169 --draft

At least one schema flag (--cipNNN, --intersect-schema, or --schema <URL>) is required.

The --draft flag is what suppresses the "missing author" failure at this stage; it must be omitted in step 9 below so the strict post-signing pass actually catches an empty-authors regression.

7. Add author witness(es)

If metadata passes all the above validations. We can sign it with author key(s).

You can either pass the my-metadata.jsonld to authors to sign, using something like ./scripts/author-create.sh. Or you can run ./scripts/metadata-canonize.sh and share the canonized body hash to sign via standard cardano wallets. In that case, HWW are supported too, but you need to change the witnessAlgorithm from ed25519 to CIP-0008 for those authors that do. If you are not sure how your author key signs, CIP-8 signing produces a significantly longer (214 byte) signature string than ed25519 signing (62 bytes).

8. Verify the author's witness(es)

Just to double check that all is good now, with author.

./scripts/author-validate.sh my-metadata.jsonld

Pass --no-intersect to skip the comparison against Intersect's well-known author public key.

9. Final validation

Just to double check that all is good now.

  • compliance with CIP schema(s)
  • compliance with Intersect schemas
  • spell check (skip with --no-spell-check)
  • URI reachability (skip with --no-check-links)
  • title/abstract length limits
  • structural integrity (non-empty authors)

Run without --draft so the empty-authors check is strict — this is what guarantees the document was actually signed in step 7:

./scripts/metadata-validate.sh my-metadata.jsonld --cip108 --cip169

10. Host on IPFS

Pin the metadata to different IPFS pinning services.

./scripts/ipfs-pin.sh my-metadata.jsonld

To skip a specific pinning service use --no-local, --no-pinata, --no-blockfrost, or --no-nmkr.

11. Verify IPFS hosting

This will now additionally check that the file is accessible via IPFS.

./scripts/ipfs-check.sh my-metadata.jsonld

12. Create the action file

Now we can create an Info governance action file from our metadata. The stake key must be registered via a registration certificate (auto done by e.g. pool delegations) and the deposit will eventually appear as staking reward.

./scripts/action-create-info.sh my-metadata.jsonld --deposit-return-addr $DEPOSIT_RETURN_ADDR

13. Create transaction

We can now include this .action file in a transaction. Note that the GA deposit is balanced out across all inputs, as if we were to create a new UTXO, and we can spend multiple inputs to get to the deposit. Thus, the below example with only one --tx-in consumes a UTXO that must contain 100k ada + fees.

cardano-cli latest transaction build \
  --tx-in "$(cardano-cli query utxo --address "$(< payment.addr)" --output-json | jq -r 'keys[0]')" \
  --change-address $(< payment.addr) \
  --proposal-file info.action \
  --out-file tx.raw

14. Sign transaction

We copy the contents of tx.raw to wherever the key is that contains the input we spend. No other signatures are required. Depending on the setup, e.g. for testnets, copying the raw CBOR could be used to import the tx in certain GUI wallets and sign via those. However, at the moment (Q4 2025), only the Keystone HWW supports signing Governance Actions.

cardano-cli latest transaction sign \
  --tx-body-file tx.raw \
  --signing-key-file payment.skey \
  --out-file tx.signed

15. Submit

E.g.: through CLI

cardano-cli latest transaction submit \
  --tx-file tx.signed