Files
proxmox/scripts/upload-token-logos-to-ipfs.sh
defiQUG b3a8fe4496
Some checks failed
Deploy to Phoenix / deploy (push) Has been cancelled
chore: sync all changes to Gitea
- Config, docs, scripts, and backup manifests
- Submodule refs unchanged (m = modified content in submodules)

Made-with: Cursor
2026-03-02 11:37:34 -08:00

154 lines
5.2 KiB
Bash
Executable File

#!/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"