PluginV2のJOBをCLIで作成する。
環境構築
~/pli_cli_job_create/
├ create_job.sh ・・・ JOB作成用シェル
├ .api ・・・ 各APIの定義情報(APIの追加はこのファイルに)
├ sample.toml ・・・ JOBのテンプレートファイル(Direct Request)
└ created-toml/ ・・・ 作成されたJOB定義のtomlが保存されるディレクトリ(ファイル名はJOB名)
mkdir ~/pli_cli_job_create
cd ~/pli_cli_job_create
.apiの作成
このファイルはAPIの定義情報を記載しています。APIを追加する場合はこのファイルに記載します。
API情報は配列で管理しています。
selections[n] ・・・ シェル実行時の選択画面に表示する文言を指定。例えば"1. Cryptocompare"など。
urls[n] ・・・ APIのURLを指定。通貨などのパラメータはBASE_CURRENCYとTARGET_CURRENCYを記載しておき、シェルにて対話式で入力した値が置換される。
paths[n] ・・・ APIのレスポンスから値を取得するためのルート。
api_keys[n] ・・・ APIにKEYが必要な場合は指定。(自身のAPI_KEYで編集してください。)
options[n] ・・・ fetchにheader情報など追加で必要な場合に指定。
explanations[n] ・・・ 通貨の組み合わせ(BASE_CURRENCYとTARGET_CURRENCY)の例。シェルでAPI選択時に参考情報として出力される。
nano .api
# Cryptocompare
selections[1]="1. Cryptocompare"
urls[1]="https://min-api.cryptocompare.com/data/price?fsym=TARGET_CURRENCY&tsyms=BASE_CURRENCY"
paths[1]="BASE_CURRENCY"
api_keys[1]=""
options[1]=""
explanations[1]="e.g.) XDC/USD -> Base Currency : USD / Target Currency : XDC"
# Coingecko
selections[2]="2. Coingecko"
urls[2]="https://api.coingecko.com/api/v3/simple/price?ids=TARGET_CURRENCY&vs_currencies=BASE_CURRENCY"
paths[2]="TARGET_CURRENCY,BASE_CURRENCY"
api_keys[2]=""
options[2]=""
explanations[2]="e.g.) plugin/usd -> Base Currency : usd / Target Currency : plugin"
# Binance
selections[3]="3. Binance"
urls[3]="https://api1.binance.com/api/v3/ticker/price?symbol=TARGET_CURRENCYBASE_CURRENCY"
paths[3]="price"
api_keys[3]=""
options[3]=""
explanations[3]="e.g.) XRP/USDT -> Base Currency : USDT / Target Currency : XRP"
# Bitrue
selections[4]="4. Bitrue"
urls[4]="https://openapi.bitrue.com/api/v1/ticker/price?symbol=TARGET_CURRENCYBASE_CURRENCY"
paths[4]="price"
api_keys[4]=""
options[4]=""
explanations[4]="e.g.) XDC/USDT -> Base Currency : USDT / Target Currency : XDC"
# Kucoin
selections[5]="5. Kucoin"
urls[5]="https://api.kucoin.com/api/v1/market/orderbook/level1?symbol=TARGET_CURRENCY-BASE_CURRENCY"
paths[5]="data,price"
api_keys[5]=""
options[5]=""
explanations[5]="e.g.) XDC/USDT -> Base Currency : USDT / Target Currency : XDC"
# CMC *API KEY required
selections[6]="6. CMC"
urls[6]="https://pro-api.coinmarketcap.com/v1/cryptocurrency/quotes/latest?symbol=TARGET_CURRENCY&convert=BASE_CURRENCY"
paths[6]="data,TARGET_CURRENCY,quote,BASE_CURRENCY,price"
api_keys[6]="your_api_key_code"
options[6]='headers="[\\"X-CMC_PRO_API_KEY\\", \\"YOUR_API_KEY\\"]"'
explanations[6]="e.g.) PLI/USDT -> Base Currency : USDT / Target Currency : PLI"
# Coinranking *API KEY required
# This URL is for XDC/USDT only
selections[7]="7. Coinranking"
urls[7]="https://api.coinranking.com/v2/coin/77jGXSqWJ1ofG?referenceCurrencyUuid=yhjMzLPhuIDl"
paths[7]="data,coin,price"
api_keys[7]="your_api_key_code"
options[7]='headers="[\\"x-access-token\\", \\"YOUR_API_KEY\\"]"'
explanations[7]="This is for XDC/USDT only. Base Currency : blank / Target Currency : blank"
# Coinpaprika
# *free version
selections[8]="8. Coinpaprika free version"
urls[8]="https://api.coinpaprika.com/v1/tickers/TARGET_CURRENCY?quotes=BASE_CURRENCY"
paths[8]="quotes,BASE_CURRENCY,price"
api_keys[8]=""
options[8]=""
explanations[8]="e.g.) Comtech Gold/USD -> Base Currency : USD / Target Currency : cgo-comtech-gold"
# Coinpaprika
# *paid version * API KEY required
selections[9]="9. Coinpaprika paid version"
urls[9]="https://api-pro.coinpaprika.com/v1/tickers/cgo-comtech-gold?quotes=USD"
paths[9]="quotes,USD,price"
api_keys[9]="your_api_key_code"
options[9]='headers="[\\"Authorization\\", \\"YOUR_API_KEY\\"]"'
explanations[9]="e.g.) Comtech Gold/USD -> Base Currency : USD / Target Currency : cgo-comtech-gold"
# Nasdaq
selections[10]="10. Nasdaq"
urls[10]="https://data.nasdaq.com/api/v3/datasets/LBMA/TARGET_CURRENCY.json?rows=1"
paths[10]="dataset,data,0,1"
api_keys[10]=""
options[10]=""
explanations[10]="This is for USD base only. Base Currency : blank / Target Currency : GOLD"
sample.tomlの作成
sample.tomlはJOB定義のtomlテンプレートです。
シェルを実行すると、このファイルをコピーして、それぞれのJOB用tomlを作成します。
このファイルはDirect Request用です。
nano sample.toml
type = "directrequest"
schemaVersion = 1
name = "NEW_JOB_NAME"
# It is recommended to give a memorable name to 'name'. You can use it for searching later.
forwardingAllowed = false
maxTaskDuration = "0s"
contractAddress = "YOUR_ORACLE_ADDRESS"
# Please replace contractAddress with your oracle address.
minContractPaymentLinkJuels = "0"
observationSource = """
decode_log [type="ethabidecodelog" abi="OracleRequest(bytes32 indexed specId, address requester, bytes32 requestId, uint256 payment, address callbackAddr, bytes4 callbackFunctionId, uint256 cancelExpiration, uint256 dataVersion, bytes data)" data="$(jobRun.logData)" topics="$(jobRun.logTopics)"]
decode_cbor [type="cborparse" data="$(decode_log.data)"]
fetch [type=http method=GET url="API_URL" allowUnrestrictedNetworkAccess="true" OPTION]
parse [type="jsonparse" path="API_PATH" data="$(fetch)"]
multiply [type="multiply" input="$(parse)" times="$(decode_cbor.times)"]
encode_data [type="ethabiencode" abi="(bytes32 requestId, uint256 value)" data="{ \\"requestId\\": $(decode_log.requestId), \\"value\\": $(multiply) }"]
encode_tx [type="ethabiencode" abi="fulfillOracleRequest2(bytes32 requestId, uint256 payment, address callbackAddress, bytes4 callbackFunctionId, uint256 expiration, bytes calldata data)"
data="{\\"requestId\\": $(decode_log.requestId), \\"payment\\": $(decode_log.payment), \\"callbackAddress\\": $(decode_log.callbackAddr), \\"callbackFunctionId\\": $(decode_log.callbackFunctionId), \\"expiration\\": $(decode_log.cancelExpiration), \\"data\\": $(encode_data)}" ]
submit_tx [type="ethtx" to="YOUR_ORACLE_ADDRESS" data="$(encode_tx)"]
decode_log -> decode_cbor -> fetch -> parse -> multiply -> encode_data -> encode_tx -> submit_tx
"""
# Please paste your oracle address in the 'to' field on the second line from the bottom.
create_job.shの作成
nano create_job.sh
JOB作成用のシェル本体です。
#!/bin/bash
GREEN='\033[0;32m'
RED='\033[0;31m'
NC='\033[0m' # No Color
sudo -l > /dev/null 2>&1
curdir=$(echo `pwd`)
workdir=$(cd $(dirname $0); pwd)
if [ "${curdir}" != "${workdir}" ]; then
echo "[INFO]change directory ${workdir}"
cd ${workdir}
fi
source .api
while true; do
echo "Select API:"
for selection in "${selections[@]}"
do
echo "$selection"
done
echo "q. Exit "
read -p "Choice : " choice
if [ "${choice}" = "q" ]; then
echo "Exiting..."
exit 0
elif [ "${selections[choice]}" = "" ]; then
echo -e "${RED}Invalid choice. Please try again.${NC}"
continue
else
echo -e "${GREEN}You selected ${selections[$choice]}"
echo -e "${explanations[$choice]}${NC}"
fi
read -p "Input Base Currency : " base_currency
read -p "Input Target Currency : " target_currency
read -p "Input Job Name : " job_name
echo -e "${GREEN}Oracle Contract Address's 'xdc' prefix is automatically converted to '0x'.${NC}"
read -p "Input Oracle Contract Address : " oca
oca="$(echo ${oca} | sed '/^$/d;/^\\s*$/d;s/^xdc/0x/g')"
url=$(echo ${urls[$choice]} | sed 's/[][^$*?+!/\\()&|'\''"]/\\&/g')
path=${paths[$choice]}
api_key=${api_keys[$choice]}
option=$(echo ${options[$choice]} | sed 's/[][^$*?+!/\\()&|'\''"]/\\&/g')
if [ ! -d "created-toml" ]; then
echo "[INFO]CREATE DIRECTORY : created-toml"
mkdir created-toml
fi
created_toml="created-toml/${job_name}.toml"
cp sample.toml "${created_toml}"
sed -i 's/NEW_JOB_NAME/'"${job_name}"'/g' "${created_toml}"
sed -i 's/YOUR_ORACLE_ADDRESS/'"${oca}"'/g' "${created_toml}"
sed -i 's/API_URL/'"${url}"'/g' "${created_toml}"
sed -i 's/API_PATH/'"${path}"'/g' "${created_toml}"
sed -i 's/BASE_CURRENCY/'"${base_currency}"'/g' "${created_toml}"
sed -i 's/TARGET_CURRENCY/'"${target_currency}"'/g' "${created_toml}"
sed -i 's/OPTION/'"${option}"'/g' "${created_toml}"
sed -i 's/YOUR_API_KEY/'"${api_key}"'/g' "${created_toml}"
echo -e "${GREEN}plugin login"
plugin admin login -f ~/pluginV2/apicredentials.txt
echo -e "${NC}"
plugin jobs create "${created_toml}"
rc=$?
echo -e "${NC}"
if [ $rc != 0 ]; then
echo -e "${RED}[ERROR] Plugin JOBS creation encoutered issues${NC}"
rm -f created-toml/${job_name}.toml
exit
else
ext_job_id_raw="$(sudo -u postgres -i psql -d plugin_mainnet_db -t -c "SELECT external_job_id FROM jobs WHERE name = '$job_name';")"
ext_job_id=$(echo $ext_job_id_raw | tr -d \-)
num_job_name=$(( ${#job_name}+9 ))
if [ $num_job_name -ge 25 ]; then
oca_prefix="$(echo "$(printf "%-${num_job_name}s\n" "Oracle Contract Address is")" " :")"
jobname_prefix="$(echo "JOB $job_name ID is :")"
else
oca_prefix="$(echo "Oracle Contract Address is :")"
jobname_prefix="$(echo "$(printf "%-25s\n" "JOB $job_name ID is")" " :")"
fi
echo -e "${GREEN}"
echo
echo -e " Local node job id - Copy to your Solidity script"
echo -e "================================================================="
echo -e
echo -e "$oca_prefix$oca"
echo -e "$jobname_prefix$ext_job_id ${NC}"
fi
echo
done
chmod +x *.sh
JOB作成
cd ~/pli_cli_job_create
./create_job.sh
[手順]
- APIを選択
- サンプル(e.g.)に従って、Base Currency(基軸通貨)とTarget Currencyを入力
- JOB名を入力
- Oracle Contract Addressを入力



