Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 46 additions & 43 deletions docs/2025-budget-withdrawals.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,36 @@ This is done via Google docs.

For Intersect [governance-actions](https://github.com/IntersectMBO/governance-actions) will be used as working directory.

### 2. Create the metadata documents
### 2. Set environment variables

Set secrets

```shell
source ./scripts/.env
```

Set some useful variables

```shell
export DEPOSIT_RETURN_ADDR=""
export WITHDRAWAL_ADDR=""
```

Make sure that `CARDANO_NODE_NETWORK_ID` and `CARDANO_NODE_SOCKET_PATH` are set.


### 3. Create the metadata documents

Convert the `.docx` to [intersect's metadata standard](https://github.com/IntersectMBO/governance-actions/tree/main/schemas)
this is a modified CIP-108 document.

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

```shell
./scripts/metadata-create.sh my-metadata.docx
./scripts/metadata-create.sh my-metadata.docx --deposit-return-addr $DEPOSIT_RETURN_ADDR
```

### 3. Sanity check the metadata
### 4. Sanity check the metadata

Generate a markdown representation from the created `.jsonld`
and manually compare against the `.docx`.
Expand All @@ -33,21 +51,13 @@ and manually compare against the `.docx`.
./scripts/cip-108-create-human-readable.sh my-metadata.jsonld
```

### 4. Formally validate the metadata
### 5. Validate the metadata

Ensure that the metadata documents are correct.

automated checks:
automated formal checks:
- compliance with CIP schema(s)
- compliance with Intersect schema
- spelling check

```shell
./scripts/metadata-validate.sh my-metadata.jsonld
```

### 5. Budget specific tests to validate the metadata

Then do specific budget checks:
- is author valid?
- is metadata discoverable on ipfs?
Expand All @@ -60,8 +70,12 @@ Then do specific budget checks:
- Provided withdrawal address matches the metadata
- All IPFS references are discoverable via IPFS

We will pass `--no-author` as we know there is no author witness yet.

We will pass `--no-ipfs` as we know we didn't put it on ipfs yet.

```shell
./scripts/budget-metadata-validate.sh ./my-metadata-directory
./scripts/budget-metadata-validate.sh ./my-metadata-directory --no-author --no-ipfs --deposit-return-addr $DEPOSIT_RETURN_ADDR --withdrawal-addr $WITHDRAWAL_ADDR
```

### 6. Sign with author's key
Expand All @@ -72,45 +86,34 @@ Sign it with the Intersect author key
(this will be done via an air-gapped setup)

```shell
./scripts/author-create.sh my-metadata.jsonld intersect-key.skey
./scripts/author-create.sh ./my-metadata-directory intersect-key.skey
```

### 7. Verify the author's witness

Check the author witness.
Check the author witness via the same script
as we know it checks everything.

Ensure it is from the expected intersect key.
Ensure it is from the expected intersect key

We will pass `--no-ipfs` as we know we didn't put it on ipfs yet.

```shell
./scripts/author-validate.sh my-metadata.jsonld
./scripts/budget-metadata-validate.sh ./my-metadata-directory --no-ipfs --deposit-return-addr $DEPOSIT_RETURN_ADDR --withdrawal-addr $WITHDRAWAL_ADDR
```

### 8. Host on IPFS

Pin the metadata to different IPFS pinning services.

You'll need to set the secrets for these pinning services first.

```shell
source ./scripts/.env

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

### 9. Check metadata is accessible via IPFS

Hit a couple of gateways and see if it is accessible.

```shell
./scripts/ipfs-check.sh my-metadata.jsonld
./scripts/ipfs-pin.sh ./my-metadata-directory
```

### 10. Create the action file
### 9. Create the action file

Now we can create a governance action file from our metadata.

This does require `CARDANO_NODE_NETWORK_ID` and `CARDANO_NODE_SOCKET_PATH` to be set.

This performs some validations
- can check against some known deposit return and withdrawal address
- checks that metadata fields are present and look right
Expand All @@ -122,15 +125,15 @@ This performs some validations
- has user manually confirm the addresses and the amount

```shell
./scripts/ipfs-check.sh my-metadata.jsonld --withdraw-to-script --deposit-return-addr <stake address> --withdrawal-addr <stake address>
./scripts/action-create.jsonld my-metadata.jsonld --withdraw-to-script --deposit-return-addr $DEPOSIT_RETURN_ADDR --withdrawal-addr $WITHDRAWAL_ADDR
```

### 11. Share the action file
### 10. Share the action file

Share the action file and the .json representation publicly.
Share the action file and the `.action.json` representation publicly.

Have people check that this looks good.
You dont want to mess this up.
You **don't** want to mess this up.

Checks;
- withdrawal and stake address are correct
Expand All @@ -139,7 +142,7 @@ Checks;
- metadata compliance with .docx
- hash and URI match

### 12. Check action file
### 11. Check action file

Automated checks.

Expand All @@ -153,13 +156,13 @@ Checks;
- manually have the user confirm aspects too

```shell
./scripts/action-validate.sh my-action.action
./scripts/action-validate.sh my-metadata.action --withdraw-to-script --deposit-return-addr $DEPOSIT_RETURN_ADDR --withdrawal-addr $WITHDRAWAL_ADDR
```

### 13. Build the transaction

todo
Manually, dependent on where the deposit is from.

### . check the transactions
### 14. check the transactions

todo
Manually.
89 changes: 72 additions & 17 deletions scripts/author-create.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,36 @@ DEFAULT_NEW_FILE="false" # default to false, to the script overwrites the input

##################################################

# Exit immediately if a command exits with a non-zero status,
# treat unset variables as an error, and fail if any command in a pipeline fails
set -euo pipefail

# Colors
#BLACK='\033[0;30m'
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
BLUE='\033[0;34m'
CYAN='\033[0;36m'
BRIGHTWHITE='\033[0;37;1m'
NC='\033[0m'

# Check if cardano-signer is installed
if ! command -v cardano-signer >/dev/null 2>&1; then
echo "Error: cardano-signer is not installed or not in your PATH." >&2
echo -e "${RED}Error: cardano-signer is not installed or not in your PATH.${NC}" >&2
exit 1
fi

# Usage message
usage() {
echo "Usage: $0 <jsonld-file|directory> <signing-key> [--author-name NAME] [--use-cip8] [--new-file]"
echo "Options:"
echo " --author-name NAME Specify the author name (default: $DEFAULT_AUTHOR_NAME)"
echo " --new-file Create a new file with the signed metadata (default: $DEFAULT_NEW_FILE)"
echo " --use-cip8 Use CIP-8 signing algorithm (default: $DEFAULT_USE_CIP8)"
echo -e "${YELLOW}Usage: $0 <jsonld-file|directory> <signing-key> [--author-name NAME] [--use-cip8] [--new-file]${NC}"
echo -e "${CYAN}Sign metadata files with author witness using cardano-signer${NC}"
echo -e " "
echo -e "Options:"
echo -e " --author-name NAME Specify the author name (default: ${YELLOW}$DEFAULT_AUTHOR_NAME${NC})"
echo -e " --new-file Create a new file with the signed metadata (default: ${YELLOW}$DEFAULT_NEW_FILE${NC})"
echo -e " --use-cip8 Use CIP-8 signing algorithm (default: ${YELLOW}$DEFAULT_USE_CIP8${NC})"
echo -e " -h, --help Show this help message and exit"
exit 1
}

Expand Down Expand Up @@ -70,31 +87,43 @@ done

# Check for required arguments
if [ -z "$input_path" ] || [ -z "$input_key" ]; then
echo "Error: Missing required arguments"
echo -e "${RED}Error: Missing required arguments${NC}" >&2
usage
fi

echo -e " "
echo -e "${YELLOW}Creating author witness for metadata files${NC}"
echo -e "${CYAN}This script signs JSON-LD metadata files using cardano-signer${NC}"

# Check if the key input file exists
if [ ! -f "$input_key" ]; then
echo "Error: Signing key file '$input_key' not found!"
echo -e "${RED}Error: Signing key file '$input_key' not found!${NC}" >&2
exit 1
fi

echo -e "${CYAN}Using signing key: ${YELLOW}$input_key${NC}"
echo -e "${CYAN}Author name: ${YELLOW}$author_name${NC}"
echo -e "${CYAN}Algorithm: ${YELLOW}$([ "$use_cip8" = "true" ] && echo "CIP-8" || echo "Ed25519")${NC}"
echo -e "${CYAN}Output mode: ${YELLOW}$([ "$new_file" = "true" ] && echo "New file (.authored.jsonld)" || echo "Overwrite original")${NC}"

sign_file() {
local file="$1"
local use_cip8="$2"
local new_file="$3"

echo -e " "
echo -e "${CYAN}Signing file: ${YELLOW}$file${NC}"

if [ $new_file = "true" ]; then
echo "Creating a new file with the signed metadata..."
echo -e "${CYAN}Creating a new file with the signed metadata...${NC}"
extension=".authored.jsonld" # New file will have .authored.jsonld extension
else
echo "Overwriting the original file with the signed metadata..."
echo -e "${CYAN}Overwriting the original file with the signed metadata...${NC}"
extension=".jsonld"
fi

if [ "$use_cip8" = "true" ]; then
echo "Signing with CIP-8 algorithm..."
echo -e "${CYAN}Signing with CIP-8 algorithm...${NC}"

temp_vkey=$(mktemp)
temp_hash=$(mktemp)
Expand All @@ -111,44 +140,70 @@ sign_file() {
rm "$temp_vkey"
rm "$temp_hash"

echo "Signing with CIP8 algorithm..."
echo -e "${CYAN}Using public key hash: ${YELLOW}$public_key_hash${NC}"
cardano-signer sign --cip100 \
--data-file "$file" \
--secret-key "$input_key" \
--author-name "$author_name" \
--address "$public_key_hash" \
--out-file "${file%.jsonld}$extension"
return
else
echo "Signing with Ed25519 algorithm..."
echo -e "${CYAN}Signing with Ed25519 algorithm...${NC}"
cardano-signer sign --cip100 \
--data-file "$file" \
--secret-key "$input_key" \
--author-name "$author_name" \
--out-file "${file%.jsonld}$extension"
return
fi

echo -e "${GREEN}Successfully signed: ${YELLOW}${file%.jsonld}$extension${NC}"
}

# Use cardano-signer to sign author metadata

if [ -d "$input_path" ]; then
# If input is a directory: sign all .jsonld files
echo -e " "
echo -e "${CYAN}Processing directory: ${YELLOW}$input_path${NC}"

shopt -s nullglob
jsonld_files=("$input_path"/*.jsonld)
# check if any .jsonld files were found
if [ ${#jsonld_files[@]} -eq 0 ]; then
echo "Error: No .jsonld files found in directory '$input_path'."
echo -e "${RED}Error: No .jsonld files found in directory '$input_path'.${NC}" >&2
exit 1
fi

echo -e "${CYAN}Found ${YELLOW}${#jsonld_files[@]}${NC}${CYAN} .jsonld files to process${NC}"

# for each .jsonld file in the directory, sign it
for file in "${jsonld_files[@]}"; do
echo -e " "
# skip for the first file
if [ "$file" != "${jsonld_files[0]}" ]; then
echo -e " "
echo -e "${CYAN}The next file is: ${YELLOW}$file${NC}"
read -p "Do you want to continue with the next file? (y/n): " choice
case "$choice" in
y|Y ) echo -e "${GREEN}Continuing with the next file...${NC}";;
n|N ) echo -e "${YELLOW}Exiting...${NC}"; exit 0;;
* ) echo -e "${RED}Invalid choice, exiting...${NC}"; exit 1;;
esac
fi
sign_file "$file" "$use_cip8" "$new_file"
done

echo -e " "
echo -e "${GREEN}All files processed successfully!${NC}"

elif [ -f "$input_path" ]; then
# Input is a single file
echo -e " "
echo -e "${CYAN}Processing single file: ${YELLOW}$input_path${NC}"
sign_file "$input_path" "$use_cip8" "$new_file"
echo -e " "
echo -e "${GREEN}✓ File processed successfully!${NC}"
else
echo "Error: '$input_path' is not a valid file or directory."
echo -e "${RED}Error: '$input_path' is not a valid file or directory.${NC}" >&2
exit 1
fi
Loading