fdn
1 #!/usr/bin/env bash 2 3 # Forknet defaults 4 host="localhost" 5 port=10391 6 7 if [ -z "$*" ]; then 8 echo "Usage:" 9 echo 10 echo "Host/update data:" 11 echo "fdn POST [service] [name] PATH [dirpath] <identifier> <title> <description> <tags=tag1,tag2,tag3> <category> <fee> <preview (true or false)>" 12 echo "fdn POST [service] [name] STRING [data-string] <identifier>" 13 echo 14 echo "Fetch data:" 15 echo "fdn GET [service] [name] <identifier-or-default> <filepath-or-default> <rebuild>" 16 echo 17 echo "Notes:" 18 echo "- When requesting a resource, please use 'default' to indicate a file with no identifier." 19 echo "- The same applies when specifying the relative path to a file within the data structure; use 'default'" 20 echo " to indicate a single file resource." 21 echo 22 exit 23 fi 24 25 26 # Default ports for Forknet 27 mainnet_port=10391 28 testnet_port=60391 29 30 # Check if the '-t' operator is passed, if so change to utilizing testnet. 31 if [[ "$1" == "-t" ]]; then 32 # Use testnet port 33 port=$testnet_port 34 shift 35 else 36 # Use mainnet port 37 port=$mainnet_port 38 fi 39 40 script_dir=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) 41 42 if [ -f "apikey.txt" ]; then 43 apikey=$(cat "apikey.txt") 44 elif [ -f "${script_dir}/../apikey.txt" ]; then 45 apikey=$(cat "${script_dir}/../apikey.txt") 46 elif [ -f "${HOME}/forknet/apikey.txt" ]; then 47 apikey=$(cat "${HOME}/forknet/apikey.txt") 48 fi 49 50 method=$1 51 service=$2 52 name=$3 53 54 if [ -z "${method}" ]; then 55 echo "Error: missing method" 56 exit 1 57 fi 58 if [ -z "${service}" ]; then 59 echo "Error: missing service" 60 exit 1 61 fi 62 if [ -z "${name}" ]; then 63 echo "Error: missing name" 64 exit 1 65 fi 66 67 if [[ "${method}" == "POST" ]]; then 68 type=$4 69 data=$5 70 identifier=$6 71 title=$7 72 description=$8 73 tags=$9 74 category=${10} 75 fee=${11} 76 preview=${12} 77 78 79 80 if [ -z "${data}" ]; then 81 if [[ "${type}" == "PATH" ]]; then 82 echo "Error: missing directory - please use a path to a directory with a SINGLE file wishing to be published" 83 exit 1 84 elif [[ "${type}" == "STRING" ]]; then 85 echo "Error: missing data string - please input the data string you wish to publish" 86 exit 1 87 else 88 echo "Error: unrecognized type" 89 exit 1 90 fi 91 fi 92 if [ -z "${FORKNET_PRIVKEY}" ]; then 93 echo "Error: missing private key. Set it by running: export FORKNET_PRIVKEY=privkeyhere" 94 exit 1 95 fi 96 97 if [ -z "${identifier}" ]; then 98 identifier="default" 99 fi 100 101 # Create type component in URL 102 if [[ "${type}" == "PATH" ]]; then 103 type_component="" 104 elif [[ "${type}" == "STRING" ]]; then 105 type_component="/string" 106 fi 107 108 # Create tags component in URL, comma-separated list of tags, will be added to the tags call. 109 tags_component="" 110 if [ -n "${tags}" ]; then 111 IFS=',' read -ra tag_array <<< "${tags}" 112 for tag in "${tag_array[@]}"; do 113 tags_component+="&tags=${tag}" 114 done 115 fi 116 117 if [ -z ${tags_component} ]; then 118 tags_component="" 119 echo "nothing in tags, using empty tags" 120 fi 121 122 #Create category component with pre-defined list of categories. Error if category is specified but not in list. 123 allowed_categories=("ART" "AUTOMOTIVE" "BEAUTY" "BOOKS" "BUSINESS" "COMMUNICATIONS" "CRYPTOCURRENCY" "CULTURE" "DATING" "DESIGN" "ENTERTAINMENT" "EVENTS" "FAITH" "FASHION" "FINANCE" "FOOD" "GAMING" "GEOGRAPHY" "HEALTH" "HISTORY" "HOME" "KNOWLEDGE" "LANGUAGE" "LIFESTYLE" "MANUFACTURING" "MAPS" "MUSIC" "NEWS" "OTHER" "PETS" "PHILOSOPHY" "PHOTOGRAPHY" "POLITICS" "PRODUCE" "PRODUCTIVITY" "PSYCHOLOGY" "FORKNET" "SCIENCE" "SELF_CARE" "SELF_SUFFICIENCY" "SHOPPING" "SOCIAL" "SOFTWARE" "SPIRITUALITY" "SPORTS" "STORYTELLING" "TECHNOLOGY" "TOOLS" "TRAVEL" "UNCATEGORIZED" "VIDEO" "WEATHER") 124 125 if [[ -n "$category" && ! " ${allowed_categories[@]} " =~ " $category " ]]; then 126 echo "Error: Invalid category. Allowed categories are: ${allowed_categories[*]} be sure to place your overall script inputs in the correct order" 127 exit 1 128 elif [ -z "$category" ]; then 129 category="" 130 echo "No category is being set" 131 fi 132 133 if [ -n "$fee" ]; then 134 if [[ "$fee" == "1" || "$fee" == ".01" ]]; then 135 fee="1000000" 136 elif [ -z "$fee" ]; then 137 fee="" 138 else 139 echo "Error: Invalid fee value. Expected '1', '.01' or no input." 140 exit 1 141 fi 142 final_fee="${fee}" 143 fi 144 145 146 # check that preview is true/false 147 if [[ -n "$preview" && ! ( "$preview" == "true" || "$preview" == "false" ) ]]; then 148 echo "Error: Invalid preview value. Expected 'true' or 'false'. Please retry with boolean as preview entry." 149 exit 1 150 elif [ -z "$preview" ]; then 151 preview="" 152 fi 153 154 # Build the API URL 155 api_url="http://${host}:${port}/arbitrary/${service}/${name}/${identifier}${type_component}" 156 api_url+="?title=${title}&description=${description}&tags=${tags_component}&category=${category}&fee=${final_fee}&preview=${preview}" 157 158 159 echo "Creating transaction - this can take a while..." 160 tx_data=$(curl --silent --insecure -X ${method} "${api_url}" -H "accept: text/plain" -H "X-API-KEY: ${apikey}" -H "Content-Type: text/plain" -d "${data}") 161 162 if [[ "${tx_data}" == *"error"* || "${tx_data}" == *"ERROR"* ]]; then 163 echo "Error creating transaction: ${tx_data}" 164 exit 1 165 elif [ -z "${tx_data}" ]; then 166 echo "Error: no transaction data returned" 167 exit 1 168 fi 169 170 echo "Computing nonce..." 171 computed_tx_data=$(curl --silent --insecure -X POST "http://${host}:${port}/arbitrary/compute" -H "Content-Type: application/json" -H "X-API-KEY: ${apikey}" -d "${tx_data}") 172 173 if [[ "${computed_tx_data}" == *"error"* || "${computed_tx_data}" == *"ERROR"* ]]; then 174 echo "Error computing nonce: ${computed_tx_data}" 175 exit 1 176 fi 177 178 echo "Signing..." 179 signed_tx_data=$(curl --silent --insecure -X POST "http://${host}:${port}/transactions/sign" -H "Content-Type: application/json" -d "{\"privateKey\":\"${FORKNET_PRIVKEY}\",\"transactionBytes\":\"${computed_tx_data}\"}") 180 181 if [[ "${signed_tx_data}" == *"error"* || "${signed_tx_data}" == *"ERROR"* ]]; then 182 echo "Error signing transaction: ${signed_tx_data}" 183 exit 1 184 fi 185 186 echo "Broadcasting..." 187 success=$(curl --silent --insecure -X POST "http://${host}:${port}/transactions/process" -H "Content-Type: text/plain" -d "${signed_tx_data}") 188 189 if [[ "${success}" == "true" ]]; then 190 echo "Transaction broadcast successfully" 191 else 192 echo "Error when broadcasting transaction. Please try again." 193 echo "Response: ${success}" 194 fi 195 196 elif [[ "${method}" == "GET" ]]; then 197 identifier=$4 198 filepath=$5 199 rebuild=$6 200 201 if [ -z "${rebuild}" ]; then 202 rebuild="false" 203 fi 204 205 # Handle default 206 if [[ "${filepath}" == "default" ]]; then 207 filepath="" 208 fi 209 210 # We use a different API depending on whether or not an identifier is supplied 211 if [ -n "${identifier}" ]; then 212 response=$(curl --silent --insecure -X GET "http://${host}:${port}/arbitrary/${service}/${name}/${identifier}?rebuild=${rebuild}&filepath=${filepath}" -H "X-API-KEY: ${apikey}") 213 else 214 response=$(curl --silent --insecure -X GET "http://${host}:${port}/arbitrary/${service}/${name}?rebuild=${rebuild}&filepath=${filepath}" -H "X-API-KEY: ${apikey}") 215 fi 216 217 if [ -z "${response}" ]; then 218 echo "Empty response from ${host}:${port}" 219 fi 220 if [[ "${response}" == *"error"* || "${response}" == *"ERROR"* ]]; then 221 echo "${response}" 222 exit 1 223 fi 224 225 echo "${response}" 226 fi 227