/ tools / fdn
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