#!/usr/bin/env bash # Upload all token logos to IPFS and output manifest (symbol/address -> CID). # Prerequisite: Run docs/04-configuration/coingecko/scripts/prepare-token-logos-512x512.sh # Supports: local ipfs daemon, or Pinata (set PINATA_JWT). # # Usage: ./scripts/upload-token-logos-to-ipfs.sh [LOGOS_DIR] # Output: LOGOS_DIR/ipfs-manifest.json set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" # Load .env if present (for PINATA_JWT) [[ -f "$REPO_ROOT/.env" ]] && set -a && source "$REPO_ROOT/.env" && set +a LOGOS_DIR="${1:-$REPO_ROOT/docs/04-configuration/coingecko/logos}" MANIFEST="$LOGOS_DIR/ipfs-manifest.json" # Chain 138 + Cronos (25): symbol -> address (for Blockscout /images/tokens/{address}.png) declare -A ADDR_BY_SYMBOL=( ["WETH"]="0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2" ["WETH10"]="0xf4BB2e28688e89fCcE3c0580D37d36A7672E8A9F" ["LINK"]="0xb7721dD53A8c629d9f1Ba31a5819AFe250002b03" ["cUSDT"]="0x93E66202A11B1772E55407B32B44e5Cd8eda7f22" ["cUSDC"]="0xf22258f57794CC8E06237084b353Ab30fFfa640b" ["ETH-USD"]="0x3304b747E565a97ec8AC220b0B6A1f6ffDB837e6" ) # Cronos (25) ISO-4217 W tokens -> address (for addressToUrl lookup) declare -A ADDR_25_BY_SYMBOL=( ["USDW"]="0x948690147D2e50ffe50C5d38C14125aD6a9FA036" ["EURW"]="0x58a8D8F78F1B65c06dAd7542eC46b299629A60dd" ["GBPW"]="0xFb4B6Cc81211F7d886950158294A44C312abCA29" ["AUDW"]="0xf9f5D0ACD71C76F9476F10B3F3d3E201F0883C68" ["JPYW"]="0xeE17bB0322383fecCA2784fbE2d4CD7d02b1905B" ["CHFW"]="0xc9750828124D4c10e7a6f4B655cA8487bD3842EB" ["CADW"]="0x328Cd365Bb35524297E68ED28c6fF2C9557d1363" ) log() { echo "[$(date +%H:%M:%S)] $*"; } err() { echo "ERROR: $*" >&2; } if [[ ! -d "$LOGOS_DIR" ]]; then err "Logos dir not found: $LOGOS_DIR" err "Run: ./docs/04-configuration/coingecko/scripts/prepare-token-logos-512x512.sh" exit 1 fi # Collect logo files (SYMBOL-512x512.png) shopt -s nullglob FILES=("$LOGOS_DIR"/*-512x512.png) if [[ ${#FILES[@]} -eq 0 ]]; then err "No *-512x512.png files in $LOGOS_DIR" exit 1 fi log "Found ${#FILES[@]} logo files" declare -A CID_BY_SYMBOL GATEWAY="${IPFS_GATEWAY:-https://ipfs.io/ipfs}" upload_via_ipfs() { local path="$1" if command -v ipfs &>/dev/null; then ipfs add -Q "$path" 2>/dev/null || true fi } upload_via_pinata() { local path="$1" local name name="$(basename "$path")" if [[ -n "${PINATA_JWT:-}" ]]; then curl -sS -X POST "https://api.pinata.cloud/pinning/pinFileToIPFS" \ -H "Authorization: Bearer $PINATA_JWT" \ -F "file=@$path" \ -F "pinataMetadata={\"name\":\"$name\"}" 2>/dev/null | jq -r '.IpfsHash // empty' fi } for f in "${FILES[@]}"; do base=$(basename "$f" -512x512.png) symbol="${base%-512x512}" cid="" if [[ -n "${PINATA_JWT:-}" ]]; then cid=$(upload_via_pinata "$f") fi if [[ -z "$cid" ]] && command -v ipfs &>/dev/null; then cid=$(upload_via_ipfs "$f") fi if [[ -n "$cid" ]]; then CID_BY_SYMBOL[$symbol]="$cid" log " $symbol -> $cid" else err " $symbol: upload failed (no ipfs or PINATA_JWT)" fi done # Build manifest JSON (use jq if available for valid JSON) log "Writing manifest to $MANIFEST" mkdir -p "$(dirname "$MANIFEST")" if command -v jq &>/dev/null; then symbols_json="{}" addr_json="{}" for symbol in "${!CID_BY_SYMBOL[@]}"; do cid="${CID_BY_SYMBOL[$symbol]}" url="${GATEWAY}/${cid}" addr="${ADDR_BY_SYMBOL[$symbol]:-}" addr25="${ADDR_25_BY_SYMBOL[$symbol]:-}" entry="{\"cid\":\"$cid\",\"url\":\"$url\"}" [[ -n "$addr" ]] && entry=$(echo "$entry" | jq -c --arg a "$addr" '. + {"address138":$a}') [[ -n "$addr25" ]] && entry=$(echo "$entry" | jq -c --arg a "$addr25" '. + {"address25":$a}') [[ -n "$addr" ]] && addr_json=$(echo "$addr_json" | jq -c --arg k "$addr" --arg v "$url" '. + {($k): $v}') [[ -n "$addr25" ]] && addr_json=$(echo "$addr_json" | jq -c --arg k "$addr25" --arg v "$url" '. + {($k): $v}') symbols_json=$(echo "$symbols_json" | jq -c --arg k "$symbol" --argjson v "$entry" '. + {($k): $v}') done echo "{\"gateway\":\"$GATEWAY\",\"symbols\":$symbols_json,\"addressToUrl\":$addr_json}" | jq '.' > "$MANIFEST" else # Fallback: simple JSON { echo '{"gateway":"'"$GATEWAY"'","symbols":{' first=true for symbol in "${!CID_BY_SYMBOL[@]}"; do cid="${CID_BY_SYMBOL[$symbol]}" url="${GATEWAY}/${cid}" addr="${ADDR_BY_SYMBOL[$symbol]:-}" addr25="${ADDR_25_BY_SYMBOL[$symbol]:-}" $first || echo ',' printf '"%s":{"cid":"%s","url":"%s"' "$symbol" "$cid" "$url" [[ -n "$addr" ]] && printf ',"address138":"%s"' "$addr" [[ -n "$addr25" ]] && printf ',"address25":"%s"' "$addr25" echo -n '}' first=false done echo '},"addressToUrl":{' first=true for symbol in "${!CID_BY_SYMBOL[@]}"; do for addr in "${ADDR_BY_SYMBOL[$symbol]:-}" "${ADDR_25_BY_SYMBOL[$symbol]:-}"; do [[ -n "$addr" ]] || continue cid="${CID_BY_SYMBOL[$symbol]}" url="${GATEWAY}/${cid}" $first || echo ',' printf '"%s":"%s"' "$addr" "$url" first=false done done echo '}}' } > "$MANIFEST" fi log "Done. Manifest: $MANIFEST" log "Use: jq -r '.symbols.WETH.url' $MANIFEST"