Some checks failed
Deploy to Phoenix / deploy (push) Has been cancelled
- Config, docs, scripts, and backup manifests - Submodule refs unchanged (m = modified content in submodules) Made-with: Cursor
154 lines
5.2 KiB
Bash
Executable File
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"
|