200 lines
6.1 KiB
Bash
Executable File
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 "" |