Files
super_ball_thrower/throw_superball.sh
2025-12-10 13:30:32 -04:00

200 lines
6.1 KiB
Bash
Executable File

#!/bin/bash
# Colors for output
GREEN='\033[0;32m'
BLUE='\033[0;34m'
CYAN='\033[0;36m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
NC='\033[0m' # No Color
# Configuration
CONFIG_FILE="config.json"
DELAY=10 # Default 10 second delay
show_usage() {
echo "Superball Test Thrower"
echo ""
echo "Usage:"
echo " $0 [options]"
echo ""
echo "Options:"
echo " -c, --config <file> Config file path (default: config.json)"
echo " -d, --delay <seconds> Delay in seconds (default: 10)"
echo " -m, --message <text> Message to send (default: 'Test superball')"
echo " -h, --help Show this help message"
echo ""
echo "Creates a Superball routing event and throws it to the thrower."
}
# Default message includes timestamp
MESSAGE="Test superball - $(date '+%Y-%m-%d %H:%M:%S %Z')"
while [[ $# -gt 0 ]]; do
case $1 in
-c|--config)
CONFIG_FILE="$2"
shift 2
;;
-d|--delay)
DELAY="$2"
shift 2
;;
-m|--message)
MESSAGE="$2"
shift 2
;;
-h|--help)
show_usage
exit 0
;;
*)
echo "Unknown option: $1"
show_usage
exit 1
;;
esac
done
# Check if nak is installed
if ! command -v nak &> /dev/null; then
echo -e "${RED}Error: 'nak' command not found${NC}"
echo "Please install nak: https://github.com/fiatjaf/nak"
exit 1
fi
# Check if jq is installed
if ! command -v jq &> /dev/null; then
echo -e "${RED}Error: 'jq' command not found${NC}"
exit 1
fi
# Load config.json
if [[ ! -f "$CONFIG_FILE" ]]; then
echo -e "${RED}Error: Config file not found: $CONFIG_FILE${NC}"
exit 1
fi
echo -e "${BLUE}Loading configuration from $CONFIG_FILE...${NC}"
# Extract thrower pubkey from config
THROWER_PRIVKEY=$(jq -r '.thrower.privateKey // empty' "$CONFIG_FILE")
if [[ -z "$THROWER_PRIVKEY" ]]; then
echo -e "${RED}Error: Could not find thrower.privateKey in config${NC}"
exit 1
fi
THROWER_PUBKEY=$(echo "$THROWER_PRIVKEY" | nak key public)
if [[ -z "$THROWER_PUBKEY" ]]; then
echo -e "${RED}Error: Could not derive thrower pubkey${NC}"
exit 1
fi
echo -e "${GREEN}✓ Thrower pubkey: ${THROWER_PUBKEY:0:16}...${NC}"
# Get relays from config
mapfile -t RELAYS < <(jq -r '.relays[].url' "$CONFIG_FILE")
if [[ ${#RELAYS[@]} -eq 0 ]]; then
echo -e "${RED}Error: No relays found in config${NC}"
exit 1
fi
echo -e "${GREEN}✓ Loaded ${#RELAYS[@]} relay(s)${NC}"
# Generate ephemeral keypair for this superball
echo -e "${BLUE}Generating ephemeral keypair...${NC}"
EPHEMERAL_PRIVKEY=$(nak key generate)
EPHEMERAL_PUBKEY=$(echo "$EPHEMERAL_PRIVKEY" | nak key public)
echo -e "${GREEN}✓ Ephemeral pubkey: ${EPHEMERAL_PUBKEY:0:16}...${NC}"
# Generate audit tag (random 32-byte hex)
AUDIT_TAG=$(openssl rand -hex 32)
echo -e "${GREEN}✓ Audit tag: ${AUDIT_TAG:0:16}...${NC}"
# Create a simple kind 1 note as the inner event
echo -e "${BLUE}Creating inner event (kind 1 note)...${NC}"
INNER_EVENT=$(nak event -c "$MESSAGE" --kind 1 --sec "$EPHEMERAL_PRIVKEY")
echo -e "${GREEN}✓ Inner event created${NC}"
# Build the routing payload
ROUTING_PAYLOAD=$(jq -n \
--argjson event "$INNER_EVENT" \
--arg relays "$(printf '%s\n' "${RELAYS[@]}" | jq -R . | jq -s .)" \
--argjson delay "$DELAY" \
--arg audit "$AUDIT_TAG" \
'{
event: $event,
routing: {
relays: ($relays | fromjson),
delay: $delay,
padding: "+0",
audit: $audit
}
}')
echo -e "${CYAN}Routing payload:${NC}"
echo "$ROUTING_PAYLOAD" | jq '.'
# Encrypt the payload with NIP-44 using thrower's pubkey
echo -e "${BLUE}Encrypting payload with NIP-44...${NC}"
ENCRYPTED_CONTENT=$(nak encrypt --sec "$EPHEMERAL_PRIVKEY" --recipient-pubkey "$THROWER_PUBKEY" "$ROUTING_PAYLOAD")
if [[ -z "$ENCRYPTED_CONTENT" ]]; then
echo -e "${RED}Error: Failed to encrypt payload${NC}"
exit 1
fi
echo -e "${GREEN}✓ Payload encrypted (length: ${#ENCRYPTED_CONTENT})${NC}"
# Create the routing event (kind 22222)
echo -e "${BLUE}Creating routing event (kind 22222)...${NC}"
# Build tags array
TAGS=$(jq -n \
--arg thrower "$THROWER_PUBKEY" \
--arg audit "$AUDIT_TAG" \
'[
["p", $thrower],
["p", $audit]
]')
# Create the event
ROUTING_EVENT=$(nak event \
--kind 22222 \
--sec "$EPHEMERAL_PRIVKEY" \
-c "$ENCRYPTED_CONTENT" \
-t "p=$THROWER_PUBKEY" \
-t "p=$AUDIT_TAG")
if [[ -z "$ROUTING_EVENT" ]]; then
echo -e "${RED}Error: Failed to create routing event${NC}"
exit 1
fi
echo -e "${GREEN}✓ Routing event created${NC}"
echo -e "${CYAN}Full routing event JSON:${NC}"
echo "$ROUTING_EVENT" | jq '.'
# Publish to all relays
echo ""
echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
echo -e "${YELLOW}Throwing Superball to relays...${NC}"
echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
for relay in "${RELAYS[@]}"; do
echo -e "${BLUE}Publishing to: $relay${NC}"
RESPONSE=$(echo "$ROUTING_EVENT" | nak event "$relay" 2>&1)
echo "$RESPONSE"
echo ""
done
echo ""
echo -e "${GREEN}✓ Superball thrown!${NC}"
echo ""
echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
echo -e "${YELLOW}Monitoring for audit tag appearance...${NC}"
echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
echo -e "Audit tag: ${GREEN}$AUDIT_TAG${NC}"
echo -e "Expected delay: ${GREEN}${DELAY}s${NC}"
echo -e "Watch with: ${BLUE}nak req -k 22222 --stream '#p=$AUDIT_TAG' ${RELAYS[0]}${NC}"
echo ""