Migrated to postgres and added pub32 tests

This commit is contained in:
kexkey
2021-11-05 22:46:36 -04:00
parent da35fc50e3
commit 8a62c146a9
44 changed files with 2299 additions and 530 deletions

View File

@@ -22,7 +22,8 @@ createbatcher() {
local request=${1}
local response
local label=$(echo "${request}" | jq ".batcherLabel")
local returncode
local label=$(echo "${request}" | jq -r ".batcherLabel")
trace "[createbatcher] label=${label}"
local conf_target=$(echo "${request}" | jq ".confTarget")
trace "[createbatcher] conf_target=${conf_target}"
@@ -37,13 +38,18 @@ createbatcher() {
local batcher_id
batcher_id=$(sql "INSERT OR IGNORE INTO batcher (label, conf_target, feerate) VALUES (${label}, ${conf_target}, ${feerate}); SELECT LAST_INSERT_ROWID();")
batcher_id=$(sql "INSERT INTO batcher (label, conf_target, feerate)"\
" VALUES ('${label}', ${conf_target}, ${feerate})"\
" RETURNING id" \
"SELECT id FROM batcher WHERE label='${label}'")
returncode=$?
trace_rc ${returncode}
if ("${batcher_id}" -eq "0"); then
if ("${returncode}" -ne "0"); then
trace "[createbatcher] Could not insert"
response='{"result":null,"error":{"code":-32700,"message":"Could not create batcher, label probably already exists","data":'${request}'}}'
else
trace "[createbatcher] Inserted"
trace "[createbatcher] Inserted, response=${batcher_id}"
response='{"result":{"batcherId":'${batcher_id}'},"error":null}'
fi
@@ -79,7 +85,7 @@ updatebatcher() {
local id=$(echo "${request}" | jq ".batcherId")
trace "[updatebatcher] id=${id}"
local label=$(echo "${request}" | jq ".batcherLabel")
local label=$(echo "${request}" | jq -r ".batcherLabel")
trace "[updatebatcher] label=${label}"
local conf_target=$(echo "${request}" | jq ".confTarget")
trace "[updatebatcher] conf_target=${conf_target}"
@@ -99,12 +105,12 @@ updatebatcher() {
# fi
if [ "${id}" = "null" ]; then
whereclause="label=${label}"
whereclause="label='${label}'"
else
whereclause="id = ${id}"
fi
sql "UPDATE batcher set label=${label}, conf_target=${conf_target}, feerate=${feerate} WHERE ${whereclause}"
sql "UPDATE batcher set label='${label}', conf_target=${conf_target}, feerate=${feerate} WHERE ${whereclause}"
returncode=$?
trace_rc ${returncode}
if [ "${returncode}" -ne 0 ]; then
@@ -151,13 +157,13 @@ addtobatch() {
trace "[addtobatch] address=${address}"
local amount=$(echo "${request}" | jq ".amount")
trace "[addtobatch] amount=${amount}"
local label=$(echo "${request}" | jq ".outputLabel")
local label=$(echo "${request}" | jq -r ".outputLabel")
trace "[addtobatch] label=${label}"
local batcher_id=$(echo "${request}" | jq ".batcherId")
trace "[addtobatch] batcher_id=${batcher_id}"
local batcher_label=$(echo "${request}" | jq ".batcherLabel")
local batcher_label=$(echo "${request}" | jq -r ".batcherLabel")
trace "[addtobatch] batcher_label=${batcher_label}"
local webhook_url=$(echo "${request}" | jq ".webhookUrl")
local webhook_url=$(echo "${request}" | jq -r ".webhookUrl")
trace "[addtobatch] webhook_url=${webhook_url}"
# Let's lowercase bech32 addresses
@@ -185,7 +191,7 @@ addtobatch() {
if [ "${batcher_id}" = "null" ]; then
# Using batcher_label
batcher_id=$(sql "SELECT id FROM batcher WHERE label=${batcher_label}")
batcher_id=$(sql "SELECT id FROM batcher WHERE label='${batcher_label}'")
returncode=$?
trace_rc ${returncode}
fi
@@ -195,7 +201,7 @@ addtobatch() {
response='{"result":null,"error":{"code":-32700,"message":"batcher not found","data":'${request}'}}'
else
# Check if address already pending for this batcher...
inserted_id=$(sql "SELECT id FROM recipient WHERE LOWER(address)=LOWER(\"${address}\") AND tx_id IS NULL AND batcher_id=${batcher_id}")
inserted_id=$(sql "SELECT id FROM recipient WHERE LOWER(address)=LOWER('${address}') AND tx_id IS NULL AND batcher_id=${batcher_id}")
returncode=$?
trace_rc ${returncode}
@@ -211,7 +217,9 @@ addtobatch() {
fi
# Insert the new destination
inserted_id=$(sql "INSERT INTO recipient (address, amount, webhook_url, batcher_id, label) VALUES (\"${address}\", ${amount}, ${webhook_url}, ${batcher_id}, ${label}); SELECT LAST_INSERT_ROWID();")
inserted_id=$(sql "INSERT INTO recipient (address, amount, webhook_url, batcher_id, label)"\
" VALUES ('${address}', ${amount}, '${webhook_url}', ${batcher_id}, '${label}')"\
" RETURNING id")
returncode=$?
trace_rc ${returncode}
@@ -280,7 +288,7 @@ removefrombatch() {
if [ "${returncode}" -ne 0 ]; then
response='{"result":null,"error":{"code":-32700,"message":"Output was not removed","data":'${request}'}}'
else
row=$(sql "SELECT COUNT(id), COALESCE(MIN(inserted_ts), 0), COALESCE(SUM(amount), 0.00000000) FROM recipient WHERE tx_id IS NULL AND batcher_id=${batcher_id}")
row=$(sql "SELECT COUNT(id), COALESCE(MIN(inserted_ts), DATE '0001-01-01'), COALESCE(SUM(amount), 0.00000000) FROM recipient WHERE tx_id IS NULL AND batcher_id=${batcher_id}")
returncode=$?
trace_rc ${returncode}
@@ -336,7 +344,7 @@ batchspend() {
local batcher_id=$(echo "${request}" | jq ".batcherId")
trace "[batchspend] batcher_id=${batcher_id}"
local batcher_label=$(echo "${request}" | jq ".batcherLabel")
local batcher_label=$(echo "${request}" | jq -r ".batcherLabel")
trace "[batchspend] batcher_label=${batcher_label}"
local conf_target=$(echo "${request}" | jq ".confTarget")
trace "[batchspend] conf_target=${conf_target}"
@@ -351,7 +359,7 @@ batchspend() {
if [ "${batcher_id}" = "null" ]; then
# Using batcher_label
whereclause="label=${batcher_label}"
whereclause="label='${batcher_label}'"
else
whereclause="id=${batcher_id}"
fi
@@ -423,11 +431,11 @@ batchspend() {
trace "[batchspend] webhook_url=${webhook_url}"
if [ -z "${recipientsjson}" ]; then
whereclause="\"${recipient_id}\""
whereclause="${recipient_id}"
recipientsjson="\"${address}\":${amount}"
webhooks_data="{\"outputId\":${recipient_id},\"address\":\"${address}\",\"amount\":${amount},\"webhookUrl\":\"${webhook_url}\"}"
else
whereclause="${whereclause},\"${recipient_id}\""
whereclause="${whereclause},${recipient_id}"
recipientsjson="${recipientsjson},\"${address}\":${amount}"
webhooks_data="${webhooks_data},{\"outputId\":${recipient_id},\"address\":\"${address}\",\"amount\":${amount},\"webhookUrl\":\"${webhook_url}\"}"
fi
@@ -452,7 +460,7 @@ batchspend() {
tx_raw_details=$(get_rawtransaction ${txid} | tr -d '\n')
# Amounts and fees are negative when spending so we absolute those fields
local tx_hash=$(echo "${tx_raw_details}" | jq '.result.hash')
local tx_hash=$(echo "${tx_raw_details}" | jq -r '.result.hash')
local tx_ts_firstseen=$(echo "${tx_details}" | jq '.result.timereceived')
local tx_amount=$(echo "${tx_details}" | jq '.result.amount | fabs' | awk '{ printf "%.8f", $0 }')
local tx_size=$(echo "${tx_raw_details}" | jq '.result.size')
@@ -462,25 +470,20 @@ batchspend() {
tx_replaceable=$([ "${tx_replaceable}" = "yes" ] && echo "true" || echo "false")
trace "[batchspend] tx_replaceable=${tx_replaceable}"
local fees=$(echo "${tx_details}" | jq '.result.fee | fabs' | awk '{ printf "%.8f", $0 }')
# Sometimes raw tx are too long to be passed as paramater, so let's write
# it to a temp file for it to be read by sqlite3 and then delete the file
echo "${tx_raw_details}" > batchspend-rawtx-${txid}-$$.blob
# Get the info on the batch before setting it to done
row=$(sql "SELECT COUNT(id), COALESCE(MIN(inserted_ts), 0), COALESCE(SUM(amount), 0.00000000) FROM recipient WHERE tx_id IS NULL AND batcher_id=${batcher_id}")
row=$(sql "SELECT COUNT(id), COALESCE(MIN(inserted_ts), DATE '0001-01-01'), COALESCE(SUM(amount), 0.00000000) FROM recipient WHERE tx_id IS NULL AND batcher_id=${batcher_id}")
returncode=$?
trace_rc ${returncode}
# Let's insert the txid in our little DB -- then we'll already have it when receiving confirmation
sql_rawtx "INSERT OR IGNORE INTO rawtx (txid, hash, confirmations, timereceived, fee, size, vsize, is_replaceable, conf_target, raw_tx) VALUES (\"${txid}\", ${tx_hash}, 0, ${tx_ts_firstseen}, ${fees}, ${tx_size}, ${tx_vsize}, ${tx_replaceable}, ${conf_target}, readfile('batchspend-rawtx-${txid}-$$.blob'))"
trace_rc $?
id_inserted=$(sql "INSERT OR IGNORE INTO tx (txid, hash, confirmations, timereceived, fee, size, vsize, is_replaceable, conf_target) VALUES (\"${txid}\", ${tx_hash}, 0, ${tx_ts_firstseen}, ${fees}, ${tx_size}, ${tx_vsize}, ${tx_replaceable}, ${conf_target}); SELECT LAST_INSERT_ROWID();")
id_inserted=$(sql "INSERT INTO tx (txid, hash, confirmations, timereceived, fee, size, vsize, is_replaceable, conf_target)"\
" VALUES ('${txid}', '${tx_hash}', 0, ${tx_ts_firstseen}, ${fees}, ${tx_size}, ${tx_vsize}, ${tx_replaceable}, ${conf_target})"\
" RETURNING id" \
"SELECT id FROM tx WHERE txid='${txid}'")
returncode=$?
trace_rc ${returncode}
if [ "${returncode}" -eq 0 ]; then
if [ "${id_inserted}" -eq 0 ]; then
id_inserted=$(sql "SELECT id FROM tx WHERE txid=\"${txid}\"")
fi
trace "[batchspend] id_inserted: ${id_inserted}"
sql "UPDATE recipient SET tx_id=${id_inserted} WHERE id IN (${whereclause})"
trace_rc $?
@@ -495,13 +498,10 @@ batchspend() {
trace "[batchspend] total=${total}"
response='{"result":{"batcherId":'${batcher_id}',"confTarget":'${conf_target}',"nbOutputs":'${count}',"oldest":"'${oldest}'","total":'${total}
response="${response},\"status\":\"accepted\",\"txid\":\"${txid}\",\"hash\":${tx_hash},\"details\":{\"firstseen\":${tx_ts_firstseen},\"size\":${tx_size},\"vsize\":${tx_vsize},\"replaceable\":${tx_replaceable},\"fee\":${fees}},\"outputs\":[${webhooks_data}]}"
response="${response},\"status\":\"accepted\",\"txid\":\"${txid}\",\"hash\":\"${tx_hash}\",\"details\":{\"firstseen\":${tx_ts_firstseen},\"size\":${tx_size},\"vsize\":${tx_vsize},\"replaceable\":${tx_replaceable},\"fee\":${fees}},\"outputs\":[${webhooks_data}]}"
response="${response},\"error\":null}"
# Delete the temp file containing the raw tx (see above)
rm batchspend-rawtx-${txid}-$$.blob
batch_webhooks "[${webhooks_data}]" '"batcherId":'${batcher_id}',"confTarget":'${conf_target}',"nbOutputs":'${count}',"oldest":"'${oldest}'","total":'${total}',"status":"accepted","txid":"'${txid}'","hash":'${tx_hash}',"details":{"firstseen":'${tx_ts_firstseen}',"size":'${tx_size}',"vsize":'${tx_vsize}',"replaceable":'${tx_replaceable}',"fee":'${fees}'}'
batch_webhooks "[${webhooks_data}]" '"batcherId":'${batcher_id}',"confTarget":'${conf_target}',"nbOutputs":'${count}',"oldest":"'${oldest}'","total":'${total}',"status":"accepted","txid":"'${txid}'","hash":"'${tx_hash}'","details":{"firstseen":'${tx_ts_firstseen}',"size":'${tx_size}',"vsize":'${tx_vsize}',"replaceable":'${tx_replaceable}',"fee":'${fees}'}'
else
local message=$(echo "${data}" | jq -e ".error.message")
@@ -578,7 +578,7 @@ batch_check_webhooks() {
# I know this query for each output is not very efficient, but this function should not execute often, only in case of
# failed callbacks on batches...
# Get the info on the batch
row=$(sql "SELECT COUNT(id), COALESCE(MIN(inserted_ts), 0), COALESCE(SUM(amount), 0.00000000) FROM recipient r WHERE tx_id=\"${tx_id}\"")
row=$(sql "SELECT COUNT(id), COALESCE(MIN(inserted_ts), DATE '0001-01-01'), COALESCE(SUM(amount), 0.00000000) FROM recipient r WHERE tx_id='${tx_id}'")
# Use the selected row above
count=$(echo "${row}" | cut -d '|' -f1)
@@ -654,7 +654,7 @@ batch_webhooks() {
fi
done
sql "UPDATE recipient SET calledback=1, calledback_ts=CURRENT_TIMESTAMP WHERE id IN (${successful_recipient_ids})"
sql "UPDATE recipient SET calledback=true, calledback_ts=CURRENT_TIMESTAMP WHERE id IN (${successful_recipient_ids})"
trace_rc $?
}
@@ -671,7 +671,7 @@ listbatchers() {
# "error":null}
local batchers=$(sql "SELECT b.id, '{\"batcherId\":' || b.id || ',\"batcherLabel\":\"' || b.label || '\",\"confTarget\":' || conf_target || ',\"nbOutputs\":' || COUNT(r.id) || ',\"oldest\":\"' ||COALESCE(MIN(r.inserted_ts), 0) || '\",\"total\":' ||COALESCE(SUM(amount), 0.00000000) || '}' FROM batcher b LEFT JOIN recipient r ON r.batcher_id=b.id AND r.tx_id IS NULL GROUP BY b.id")
local batchers=$(sql "SELECT b.id, '{\"batcherId\":' || b.id || ',\"batcherLabel\":\"' || b.label || '\",\"confTarget\":' || conf_target || ',\"nbOutputs\":' || COUNT(r.id) || ',\"oldest\":\"' ||COALESCE(MIN(r.inserted_ts), DATE '0001-01-01') || '\",\"total\":' ||COALESCE(SUM(amount), 0.00000000) || '}' FROM batcher b LEFT JOIN recipient r ON r.batcher_id=b.id AND r.tx_id IS NULL GROUP BY b.id ORDER BY b.id")
trace "[listbatchers] batchers=${batchers}"
local returncode
@@ -717,7 +717,7 @@ getbatcher() {
local batcher_id=$(echo "${request}" | jq ".batcherId")
trace "[getbatcher] batcher_id=${batcher_id}"
local batcher_label=$(echo "${request}" | jq ".batcherLabel")
local batcher_label=$(echo "${request}" | jq -r ".batcherLabel")
trace "[getbatcher] batcher_label=${batcher_label}"
if [ "${batcher_id}" = "null" ] && [ "${batcher_label}" = "null" ]; then
@@ -728,13 +728,13 @@ getbatcher() {
if [ "${batcher_id}" = "null" ]; then
# Using batcher_label
whereclause="b.label=${batcher_label}"
whereclause="b.label='${batcher_label}'"
else
# Using batcher_id
whereclause="b.id=${batcher_id}"
fi
batcher=$(sql "SELECT b.id, '{\"batcherId\":' || b.id || ',\"batcherLabel\":\"' || b.label || '\",\"confTarget\":' || conf_target || ',\"nbOutputs\":' || COUNT(r.id) || ',\"oldest\":\"' ||COALESCE(MIN(r.inserted_ts), 0) || '\",\"total\":' ||COALESCE(SUM(amount), 0.00000000) || '}' FROM batcher b LEFT JOIN recipient r ON r.batcher_id=b.id AND r.tx_id IS NULL WHERE ${whereclause} GROUP BY b.id")
batcher=$(sql "SELECT b.id, '{\"batcherId\":' || b.id || ',\"batcherLabel\":\"' || b.label || '\",\"confTarget\":' || conf_target || ',\"nbOutputs\":' || COUNT(r.id) || ',\"oldest\":\"' ||COALESCE(MIN(r.inserted_ts), DATE '0001-01-01') || '\",\"total\":' ||COALESCE(SUM(amount), 0.00000000) || '}' FROM batcher b LEFT JOIN recipient r ON r.batcher_id=b.id AND r.tx_id IS NULL WHERE ${whereclause} GROUP BY b.id")
trace "[getbatcher] batcher=${batcher}"
if [ -n "${batcher}" ]; then
@@ -797,9 +797,9 @@ getbatchdetails() {
local batcher_id=$(echo "${request}" | jq ".batcherId")
trace "[getbatchdetails] batcher_id=${batcher_id}"
local batcher_label=$(echo "${request}" | jq ".batcherLabel")
local batcher_label=$(echo "${request}" | jq -r ".batcherLabel")
trace "[getbatchdetails] batcher_label=${batcher_label}"
local txid=$(echo "${request}" | jq ".txid")
local txid=$(echo "${request}" | jq -r ".txid")
trace "[getbatchdetails] txid=${txid}"
if [ "${batcher_id}" = "null" ] && [ "${batcher_label}" = "null" ]; then
@@ -810,7 +810,7 @@ getbatchdetails() {
if [ "${batcher_id}" = "null" ]; then
# Using batcher_label
whereclause="b.label=${batcher_label}"
whereclause="b.label='${batcher_label}'"
else
# Using batcher_id
whereclause="b.id=${batcher_id}"
@@ -818,7 +818,7 @@ getbatchdetails() {
if [ "${txid}" != "null" ]; then
# Using txid
whereclause="${whereclause} AND t.txid=${txid}"
whereclause="${whereclause} AND t.txid='${txid}'"
else
# null txid
whereclause="${whereclause} AND t.txid IS NULL"
@@ -826,7 +826,7 @@ getbatchdetails() {
fi
# First get the batch summary
batch=$(sql "SELECT b.id, COALESCE(t.id, NULL), '{\"batcherId\":' || b.id || ',\"batcherLabel\":\"' || b.label || '\",\"confTarget\":' || b.conf_target || ',\"nbOutputs\":' || COUNT(r.id) || ',\"oldest\":\"' ||COALESCE(MIN(r.inserted_ts), 0) || '\",\"total\":' ||COALESCE(SUM(amount), 0.00000000) FROM batcher b LEFT JOIN recipient r ON r.batcher_id=b.id ${outerclause} LEFT JOIN tx t ON t.id=r.tx_id WHERE ${whereclause} GROUP BY b.id")
batch=$(sql "SELECT b.id, COALESCE(t.id, NULL), '{\"batcherId\":' || b.id || ',\"batcherLabel\":\"' || b.label || '\",\"confTarget\":' || b.conf_target || ',\"nbOutputs\":' || COUNT(r.id) || ',\"oldest\":\"' ||COALESCE(MIN(r.inserted_ts), DATE '0001-01-01') || '\",\"total\":' ||COALESCE(SUM(amount), 0.00000000) FROM batcher b LEFT JOIN recipient r ON r.batcher_id=b.id ${outerclause} LEFT JOIN tx t ON t.id=r.tx_id WHERE ${whereclause} GROUP BY b.id, t.id")
trace "[getbatchdetails] batch=${batch}"
if [ -n "${batch}" ]; then
@@ -839,7 +839,7 @@ getbatchdetails() {
# Using txid
outerclause="AND r.tx_id=${tx_id}"
tx=$(sql "SELECT '\"txid\":\"' || txid || '\",\"hash\":\"' || hash || '\",\"details\":{\"firstseen\":' || timereceived || ',\"size\":' || size || ',\"vsize\":' || vsize || ',\"replaceable\":' || CASE is_replaceable WHEN 1 THEN 'true' ELSE 'false' END || ',\"fee\":' || fee || '}' FROM tx WHERE id=${tx_id}")
tx=$(sql "SELECT '\"txid\":\"' || txid || '\",\"hash\":\"' || hash || '\",\"details\":{\"firstseen\":' || timereceived || ',\"size\":' || size || ',\"vsize\":' || vsize || ',\"replaceable\":' || CASE is_replaceable WHEN true THEN 'true' ELSE 'false' END || ',\"fee\":' || fee || '}' FROM tx WHERE id=${tx_id}")
else
# null txid
outerclause="AND r.tx_id IS NULL"

View File

@@ -78,6 +78,14 @@ convert_pub32() {
local checksum
local pub32_dest
case "${pub32_from}" in
${to_type}*)
trace "[convert_pub32] Already in the right format, exiting"
echo "${pub32_from}"
return
;;
esac
case "${to_type}" in
tpub)
versionbytes="043587cf"

View File

@@ -8,8 +8,8 @@ ln_call_lightningd() {
local response
local returncode
trace "[ln_call_lightningd] ./lightning-cli $@"
response=$(./lightning-cli $@)
trace "[ln_call_lightningd] ./lightning-cli $(printf " \"%s\"" "$@")"
response=$(./lightning-cli "$@")
returncode=$?
trace_rc ${returncode}
@@ -39,7 +39,7 @@ ln_create_invoice() {
if [ "${callback_url}" != "null" ]; then
# If not null, let's add double-quotes so we don't need to add the double-quotes in the sql insert,
# so if it's null, it will insert the actual sql NULL value.
callback_url="\"${callback_url}\""
callback_url="'${callback_url}'"
fi
#/proxy $ ./lightning-cli invoice 10000 "t1" "t1d" 60
@@ -71,36 +71,33 @@ ln_create_invoice() {
# Let's get the connect string if provided in configuration
local connectstring=$(get_connection_string)
if [ "${msatoshi}" = "null" ]; then
sql "INSERT OR IGNORE INTO ln_invoice (label, bolt11, callback_url, payment_hash, expires_at, description, status) VALUES (\"${label}\", \"${bolt11}\", ${callback_url}, \"${payment_hash}\", ${expires_at}, \"${description}\", \"unpaid\")"
else
sql "INSERT OR IGNORE INTO ln_invoice (label, bolt11, callback_url, payment_hash, expires_at, msatoshi, description, status) VALUES (\"${label}\", \"${bolt11}\", ${callback_url}, \"${payment_hash}\", ${expires_at}, ${msatoshi}, \"${description}\", \"unpaid\")"
fi
trace_rc $?
id=$(sql "SELECT id FROM ln_invoice WHERE bolt11=\"${bolt11}\"")
id=$(sql "INSERT INTO ln_invoice (label, bolt11, callback_url, payment_hash, expires_at, msatoshi, description, status)"\
" VALUES ('${label}','${bolt11}', ${callback_url},'${payment_hash}', ${expires_at}, ${msatoshi}, '${description}', 'unpaid')"\
" RETURNING id" \
"SELECT id FROM ln_invoice WHERE bolt11='${bolt11}'")
trace_rc $?
# {
# "id":"",
# "id":123,
# "label":"",
# "bolt11":"",
# "connectstring":"",
# "callbackUrl":"",
# "payment_hash":"",
# "msatoshi":,
# "msatoshi":123456,
# "status":"unpaid",
# "description":"",
# "expires_at":
# "expires_at":21312312
# }
data="{\"id\":\"${id}\","
data="{\"id\":${id},"
data="${data}\"label\":\"${label}\","
data="${data}\"bolt11\":\"${bolt11}\","
if [ -n "${connectstring}" ]; then
data="${data}\"connectstring\":\"${connectstring}\","
fi
if [ "${callback_url}" != "null" ]; then
data="${data}\"callbackUrl\":${callback_url},"
data="${data}\"callbackUrl\":\"${callback_url}\","
fi
data="${data}\"payment_hash\":\"${payment_hash}\","
if [ "${msatoshi}" != "null" ]; then

View File

@@ -10,8 +10,17 @@ do_callbacks() {
trace "Entering do_callbacks()..."
# If called because we received a confirmation for a specific txid, let's only
# process that txid-related callbacks...
local txid=${1}
local txid_where
if [ -n "${txid}" ]; then
trace "[do_callbacks] txid=${txid}"
txid_where=" AND txid='${txid}'"
fi
# Let's fetch all the watching addresses still being watched but not called back
local callbacks=$(sql 'SELECT DISTINCT w.callback0conf, address, txid, vout, amount, confirmations, timereceived, fee, size, vsize, blockhash, blockheight, blocktime, w.id, is_replaceable, pub32_index, pub32, w32.label, derivation_path, event_message, hash FROM watching w LEFT JOIN watching_tx ON w.id = watching_id LEFT JOIN tx ON tx.id = tx_id LEFT JOIN watching_by_pub32 w32 ON watching_by_pub32_id = w32.id WHERE NOT calledback0conf AND watching_id NOT NULL AND w.callback0conf NOT NULL AND w.watching')
local callbacks=$(sql "SELECT DISTINCT w.callback0conf, address, txid, vout, amount, confirmations, timereceived, fee, size, vsize, blockhash, blockheight, blocktime, w.id, is_replaceable, pub32_index, pub32, w32.label, derivation_path, event_message, hash FROM watching w LEFT JOIN watching_tx ON w.id = watching_id LEFT JOIN tx ON tx.id = tx_id LEFT JOIN watching_by_pub32 w32 ON w.watching_by_pub32_id = w32.id WHERE NOT calledback0conf AND watching_id IS NOT NULL AND w.callback0conf IS NOT NULL AND w.watching${txid_where}")
trace "[do_callbacks] callbacks0conf=${callbacks}"
local returncode
@@ -25,12 +34,12 @@ do_callbacks() {
trace_rc ${returncode}
if [ "${returncode}" -eq 0 ]; then
address=$(echo "${row}" | cut -d '|' -f2)
sql "UPDATE watching SET calledback0conf=1 WHERE address=\"${address}\""
sql "UPDATE watching SET calledback0conf=true WHERE address='${address}'"
trace_rc $?
fi
done
callbacks=$(sql 'SELECT DISTINCT w.callback1conf, address, txid, vout, amount, confirmations, timereceived, fee, size, vsize, blockhash, blockheight, blocktime, w.id, is_replaceable, pub32_index, pub32, w32.label, derivation_path, event_message, hash FROM watching w, watching_tx wt, tx t LEFT JOIN watching_by_pub32 w32 ON watching_by_pub32_id = w32.id WHERE w.id = watching_id AND tx_id = t.id AND NOT calledback1conf AND confirmations>0 AND w.callback1conf NOT NULL AND w.watching')
callbacks=$(sql "SELECT DISTINCT w.callback1conf, address, txid, vout, amount, confirmations, timereceived, fee, size, vsize, blockhash, blockheight, blocktime, w.id, is_replaceable, pub32_index, pub32, w32.label, derivation_path, event_message, hash FROM watching w JOIN watching_tx wt ON w.id = wt.watching_id JOIN tx t ON wt.tx_id = t.id LEFT JOIN watching_by_pub32 w32 ON watching_by_pub32_id = w32.id WHERE NOT calledback1conf AND confirmations>0 AND w.callback1conf IS NOT NULL AND w.watching${txid_where}")
trace "[do_callbacks] callbacks1conf=${callbacks}"
for row in ${callbacks}
@@ -39,19 +48,25 @@ do_callbacks() {
returncode=$?
if [ "${returncode}" -eq 0 ]; then
address=$(echo "${row}" | cut -d '|' -f2)
sql "UPDATE watching SET calledback1conf=1, watching=0 WHERE address=\"${address}\""
sql "UPDATE watching SET calledback1conf=true, watching=false WHERE address='${address}'"
trace_rc $?
fi
done
callbacks=$(sql "SELECT id, label, bolt11, callback_url, payment_hash, msatoshi, status, pay_index, msatoshi_received, paid_at, description, expires_at FROM ln_invoice WHERE NOT calledback AND callback_failed")
trace "[do_callbacks] ln_callbacks=${callbacks}"
if [ -z "${txid}" ]; then
trace "[do_callbacks] Processing LN callbacks..."
for row in ${callbacks}
do
ln_manage_callback ${row}
trace_rc $?
done
callbacks=$(sql "SELECT id, label, bolt11, callback_url, payment_hash, msatoshi, status, pay_index, msatoshi_received, paid_at, description, expires_at FROM ln_invoice WHERE NOT calledback AND callback_failed")
trace "[do_callbacks] ln_callbacks=${callbacks}"
for row in ${callbacks}
do
ln_manage_callback ${row}
trace_rc $?
done
else
trace "[do_callbacks] called for a specific txid, skipping LN callbacks"
fi
) 200>./.callbacks.lock
}
@@ -70,7 +85,7 @@ ln_manage_callback() {
if [ -z "${callback_url}" ]; then
# No callback url provided for that invoice
trace "[ln_manage_callback] No callback url provided for that invoice"
sql "UPDATE ln_invoice SET calledback=1 WHERE id=\"${id}\""
sql "UPDATE ln_invoice SET calledback=true WHERE id=${id}"
trace_rc $?
return
fi
@@ -112,7 +127,7 @@ ln_manage_callback() {
# "expires_at":
# }
data="{\"id\":\"${id}\","
data="{\"id\":${id},"
data="${data}\"label\":\"${label}\","
data="${data}\"bolt11\":\"${bolt11}\","
data="${data}\"callback_url\":\"${callback_url}\","
@@ -132,11 +147,11 @@ ln_manage_callback() {
returncode=$?
trace_rc ${returncode}
if [ "${returncode}" -eq 0 ]; then
sql "UPDATE ln_invoice SET calledback=1 WHERE id=\"${id}\""
sql "UPDATE ln_invoice SET calledback=true WHERE id=${id}"
trace_rc $?
else
trace "[ln_manage_callback] callback failed: ${callback_url}"
sql "UPDATE ln_invoice SET callback_failed=1 WHERE id=\"${id}\""
sql "UPDATE ln_invoice SET callback_failed=true WHERE id=${id}"
trace_rc $?
fi
@@ -212,7 +227,7 @@ build_callback() {
vsize=$(echo "${row}" | cut -d '|' -f10)
trace "[build_callback] vsize=${vsize}"
is_replaceable=$(echo "${row}" | cut -d '|' -f15)
is_replaceable=$([ "${is_replaceable}" -eq "1" ] && echo "true" || echo "false")
is_replaceable=$([ "${is_replaceable}" = "t" ] && echo "true" || echo "false")
trace "[build_callback] is_replaceable=${is_replaceable}"
blockhash=$(echo "${row}" | cut -d '|' -f11)
trace "[build_callback] blockhash=${blockhash}"
@@ -234,7 +249,7 @@ build_callback() {
event_message=$(echo "${row}" | cut -d '|' -f20)
trace "[build_callback] event_message=${event_message}"
data="{\"id\":\"${id}\","
data="{\"id\":${id},"
data="${data}\"address\":\"${address}\","
data="${data}\"txid\":\"${txid}\","
data="${data}\"hash\":\"${hash}\","

View File

@@ -9,8 +9,10 @@ do_callbacks_txid() {
trace "Entering do_callbacks_txid()..."
# Let's check the 1-conf (newly mined) watched txid that are included in the new block...
# Let's fetch all the watching txid still being watched but not called back
local callbacks=$(sql 'SELECT id, txid, callback1conf, 1 FROM watching_by_txid WHERE watching AND callback1conf NOT NULL AND NOT calledback1conf')
local callbacks=$(sql "SELECT id, txid, callback1conf, 1 FROM watching_by_txid WHERE watching AND callback1conf IS NOT NULL AND NOT calledback1conf")
trace "[do_callbacks_txid] callbacks1conf=${callbacks}"
local returncode
@@ -25,14 +27,16 @@ do_callbacks_txid() {
trace_rc ${returncode}
if [ "${returncode}" -eq "0" ]; then
id=$(echo "${row}" | cut -d '|' -f1)
sql "UPDATE watching_by_txid SET calledback1conf=1 WHERE id=\"${id}\""
sql "UPDATE watching_by_txid SET calledback1conf=true WHERE id=${id}"
trace_rc $?
else
trace "[do_callbacks_txid] callback returncode has error, we don't flag as calledback yet."
fi
done
local callbacks=$(sql 'SELECT id, txid, callbackxconf, nbxconf FROM watching_by_txid WHERE watching AND calledback1conf AND callbackxconf NOT NULL AND NOT calledbackxconf')
# For the n-conf, let's only check the watched txids that are already at least 1-conf...
local callbacks=$(sql "SELECT id, txid, callbackxconf, nbxconf FROM watching_by_txid WHERE watching AND calledback1conf AND callbackxconf IS NOT NULL AND NOT calledbackxconf")
trace "[do_callbacks_txid] callbacksxconf=${callbacks}"
for row in ${callbacks}
@@ -42,7 +46,7 @@ do_callbacks_txid() {
trace_rc ${returncode}
if [ "${returncode}" -eq "0" ]; then
id=$(echo "${row}" | cut -d '|' -f1)
sql "UPDATE watching_by_txid SET calledbackxconf=1, watching=0 WHERE id=\"${id}\""
sql "UPDATE watching_by_txid SET calledbackxconf=true, watching=false WHERE id=${id}"
trace_rc $?
else
trace "[do_callbacks_txid] callback returncode has error, we don't flag as calledback yet."

View File

@@ -64,16 +64,10 @@ compute_vin_total_amount()
for vin_txid_vout in ${vin_txids_vout}
do
vin_txid=$(echo "${vin_txid_vout}" | tr -d '"' | cut -d '-' -f1)
# Check if we already have the tx in our DB
vin_raw_tx=$(sql_rawtx "SELECT raw_tx FROM rawtx WHERE txid=\"${vin_txid}\"")
trace_rc $?
if [ -z "${vin_raw_tx}" ]; then
txid_already_inserted=false
vin_raw_tx=$(get_rawtransaction "${vin_txid}" | tr -d '\n')
returncode=$?
if [ "${returncode}" -ne 0 ]; then
return ${returncode}
fi
vin_raw_tx=$(get_rawtransaction "${vin_txid}" | tr -d '\n')
returncode=$?
if [ "${returncode}" -ne 0 ]; then
return ${returncode}
fi
vout=$(echo "${vin_txid_vout}" | tr -d '"' | cut -d '-' -f2)
trace "[compute_vin_total_amount] vout=${vout}"
@@ -81,27 +75,23 @@ compute_vin_total_amount()
trace "[compute_vin_total_amount] vin_vout_amount=${vin_vout_amount}"
vin_total_amount=$(awk "BEGIN { printf(\"%.8f\", ${vin_total_amount}+${vin_vout_amount}); exit}")
trace "[compute_vin_total_amount] vin_total_amount=${vin_total_amount}"
vin_hash=$(echo "${vin_raw_tx}" | jq ".result.hash")
vin_hash=$(echo "${vin_raw_tx}" | jq -r ".result.hash")
vin_confirmations=$(echo "${vin_raw_tx}" | jq ".result.confirmations")
vin_timereceived=$(echo "${vin_raw_tx}" | jq ".result.time")
vin_size=$(echo "${vin_raw_tx}" | jq ".result.size")
vin_vsize=$(echo "${vin_raw_tx}" | jq ".result.vsize")
vin_blockhash=$(echo "${vin_raw_tx}" | jq ".result.blockhash")
vin_blockhash=$(echo "${vin_raw_tx}" | jq -r ".result.blockhash")
vin_blockheight=$(echo "${vin_raw_tx}" | jq ".result.blockheight")
vin_blocktime=$(echo "${vin_raw_tx}" | jq ".result.blocktime")
# Let's insert the vin tx in the DB just in case it would be useful
if ! ${txid_already_inserted}; then
# Sometimes raw tx are too long to be passed as paramater, so let's write
# it to a temp file for it to be read by sqlite3 and then delete the file
echo "${vin_raw_tx}" > vin-rawtx-${vin_txid}-$$.blob
sql "INSERT OR IGNORE INTO tx (txid, hash, confirmations, timereceived, size, vsize, blockhash, blockheight, blocktime) VALUES (\"${vin_txid}\", ${vin_hash}, ${vin_confirmations}, ${vin_timereceived}, ${vin_size}, ${vin_vsize}, ${vin_blockhash}, ${vin_blockheight}, ${vin_blocktime})"
trace_rc $?
sql_rawtx "INSERT OR IGNORE INTO rawtx (txid, hash, confirmations, timereceived, size, vsize, blockhash, blockheight, blocktime, raw_tx) VALUES (\"${vin_txid}\", ${vin_hash}, ${vin_confirmations}, ${vin_timereceived}, ${vin_size}, ${vin_vsize}, ${vin_blockhash}, ${vin_blockheight}, ${vin_blocktime}, readfile('vin-rawtx-${vin_txid}-$$.blob'))"
trace_rc $?
rm vin-rawtx-${vin_txid}-$$.blob
txid_already_inserted=true
fi
sql "INSERT INTO tx (txid, hash, confirmations, timereceived, size, vsize, blockhash, blockheight, blocktime)"\
" VALUES ('${vin_txid}', '${vin_hash}', ${vin_confirmations}, ${vin_timereceived}, ${vin_size}, ${vin_vsize}, '${vin_blockhash}', ${vin_blockheight}, ${vin_blocktime})"\
" ON CONFLICT (txid) DO"\
" UPDATE SET blockhash='${vin_blockhash}', blockheight=${vin_blockheight}, blocktime=${vin_blocktime}, confirmations=${vin_confirmations}"\
" RETURNING id" \
"SELECT id FROM tx WHERE txid='${vin_txid}'"
trace_rc $?
done
echo "${vin_total_amount}"

View File

@@ -44,7 +44,7 @@ confirmation() {
# First of all, let's make sure we're working on watched addresses...
local address
local addresseswhere
local addresses=$(echo "${tx_details}" | jq ".result.details[].address")
local addresses=$(echo "${tx_details}" | jq -r ".result.details[].address")
local notfirst=false
local IFS=$'\n'
@@ -53,9 +53,9 @@ confirmation() {
trace "[confirmation] address=${address}"
if ${notfirst}; then
addresseswhere="${addresseswhere},${address}"
addresseswhere="${addresseswhere},'${address}'"
else
addresseswhere="${address}"
addresseswhere="'${address}'"
notfirst=true
fi
done
@@ -66,11 +66,11 @@ confirmation() {
fi
########################################################################################################
local tx=$(sql "SELECT id FROM tx WHERE txid=\"${txid}\"")
local tx=$(sql "SELECT id FROM tx WHERE txid='${txid}'")
local id_inserted
local tx_raw_details=$(get_rawtransaction ${txid} | tr -d '\n')
local tx_nb_conf=$(echo "${tx_details}" | jq -r '.result.confirmations // 0')
local tx_hash=$(echo "${tx_raw_details}" | jq '.result.hash')
local tx_hash=$(echo "${tx_raw_details}" | jq -r '.result.hash')
# Sometimes raw tx are too long to be passed as paramater, so let's write
# it to a temp file for it to be read by sqlite3 and then delete the file
@@ -100,45 +100,33 @@ confirmation() {
local tx_blocktime=null
if [ "${tx_nb_conf}" -gt "0" ]; then
trace "[confirmation] tx_nb_conf=${tx_nb_conf}"
tx_blockhash=$(echo "${tx_details}" | jq '.result.blockhash')
tx_blockheight=$(get_block_info $(echo ${tx_blockhash} | tr -d '"') | jq '.result.height')
tx_blockhash="$(echo "${tx_details}" | jq -r '.result.blockhash')"
tx_blockheight=$(get_block_info ${tx_blockhash} | jq '.result.height')
tx_blockhash="'${tx_blockhash}'"
tx_blocktime=$(echo "${tx_details}" | jq '.result.blocktime')
fi
sql "INSERT OR IGNORE INTO tx (txid, hash, confirmations, timereceived, fee, size, vsize, is_replaceable, blockhash, blockheight, blocktime) VALUES (\"${txid}\", ${tx_hash}, ${tx_nb_conf}, ${tx_ts_firstseen}, ${fees}, ${tx_size}, ${tx_vsize}, ${tx_replaceable}, ${tx_blockhash}, ${tx_blockheight}, ${tx_blocktime})"
trace_rc $?
sql_rawtx "INSERT OR IGNORE INTO rawtx (txid, hash, confirmations, timereceived, fee, size, vsize, is_replaceable, blockhash, blockheight, blocktime, raw_tx) VALUES (\"${txid}\", ${tx_hash}, ${tx_nb_conf}, ${tx_ts_firstseen}, ${fees}, ${tx_size}, ${tx_vsize}, ${tx_replaceable}, ${tx_blockhash}, ${tx_blockheight}, ${tx_blocktime}, readfile('rawtx-${txid}-$$.blob'))"
trace_rc $?
id_inserted=$(sql "SELECT id FROM tx WHERE txid=\"${txid}\"")
id_inserted=$(sql "INSERT INTO tx (txid, hash, confirmations, timereceived, fee, size, vsize, is_replaceable, blockhash, blockheight, blocktime)"\
" VALUES ('${txid}', '${tx_hash}', ${tx_nb_conf}, ${tx_ts_firstseen}, ${fees}, ${tx_size}, ${tx_vsize}, ${tx_replaceable}, ${tx_blockhash}, ${tx_blockheight}, ${tx_blocktime})"\
" ON CONFLICT (txid) DO"\
" UPDATE SET blockhash=${tx_blockhash}, blockheight=${tx_blockheight}, blocktime=${tx_blocktime}, confirmations=${tx_nb_conf}"\
" RETURNING id" \
"SELECT id FROM tx WHERE txid='${txid}'")
trace_rc $?
else
# TX found in our DB.
# 1-conf or executecallbacks on an unconfirmed tx or spending watched address (in this case, we probably missed conf) or spending to a watched address (in this case, spend inserted the tx in the DB)
local tx_blockhash=$(echo "${tx_details}" | jq '.result.blockhash')
local tx_blockhash=$(echo "${tx_details}" | jq -r '.result.blockhash')
trace "[confirmation] tx_blockhash=${tx_blockhash}"
if [ "${tx_blockhash}" = "null" ]; then
trace "[confirmation] probably being called by executecallbacks without any confirmations since the last time we checked"
else
local tx_blockheight=$(get_block_info $(echo "${tx_blockhash}" | tr -d '"') | jq '.result.height')
local tx_blockheight=$(get_block_info "${tx_blockhash}" | jq '.result.height')
local tx_blocktime=$(echo "${tx_details}" | jq '.result.blocktime')
sql "UPDATE tx SET
confirmations=${tx_nb_conf},
blockhash=${tx_blockhash},
blockheight=${tx_blockheight},
blocktime=${tx_blocktime}
WHERE txid=\"${txid}\""
trace_rc $?
sql_rawtx "UPDATE rawtx SET
confirmations=${tx_nb_conf},
blockhash=${tx_blockhash},
blockheight=${tx_blockheight},
blocktime=${tx_blocktime},
raw_tx=readfile('rawtx-${txid}-$$.blob')
WHERE txid=\"${txid}\""
sql "UPDATE tx SET confirmations=${tx_nb_conf}, blockhash='${tx_blockhash}', blockheight=${tx_blockheight}, blocktime=${tx_blocktime} WHERE txid='${txid}'"
trace_rc $?
fi
id_inserted=${tx}
@@ -171,7 +159,8 @@ confirmation() {
# If the tx is batched and pays multiple watched addresses, we have to insert
# those additional addresses in watching_tx!
watching_id=$(echo "${row}" | cut -d '|' -f1)
sql "INSERT OR IGNORE INTO watching_tx (watching_id, tx_id, vout, amount) VALUES (${watching_id}, ${id_inserted}, ${tx_vout_n}, ${tx_vout_amount})"
sql "INSERT INTO watching_tx (watching_id, tx_id, vout, amount) VALUES (${watching_id}, ${id_inserted}, ${tx_vout_n}, ${tx_vout_amount})"\
" ON CONFLICT DO NOTHING"
trace_rc $?
else
trace "[confirmation] For this tx, there's already watching_tx rows"
@@ -211,7 +200,7 @@ confirmation() {
# for next cron.
if [ -z "${bypass_callbacks}" ]; then
trace "[confirmation] Let's do the callbacks!"
do_callbacks
do_callbacks "${txid}"
fi
echo '{"result":"confirmed"}'

View File

@@ -12,8 +12,8 @@ get_txns_by_watchlabel(){
INNER JOIN watching AS w ON w32.id = w.watching_by_pub32_id
INNER JOIN watching_tx AS wtxn ON w.id = wtxn.watching_id
INNER JOIN tx AS tx ON wtxn.tx_id = tx.id
WHERE w32.label="$1"
LIMIT 0,${2-10}
WHERE w32.label='${1}'
LIMIT ${2-10} OFFSET 0
HERE
)
label_txns=$(sql "$query")
@@ -38,12 +38,12 @@ get_unused_addresses_by_watchlabel(){
SELECT w32.id, w32.label, w32.pub32, w.pub32_index, w.address
FROM watching as w
INNER JOIN watching_by_pub32 AS w32 ON w.watching_by_pub32_id = w32.id
WHERE w32.label="$1"
WHERE w32.label='${1}'
AND NOT EXISTS (
SELECT 1 FROM watching_tx WHERE watching_id = w.id
)
ORDER BY w.pub32_index ASC
LIMIT 0,${2-10}
LIMIT ${2-10} OFFSET 0
HERE
)
label_unused_addrs=$(sql "$query")
@@ -67,7 +67,7 @@ getactivewatches() {
local watches
# Let's build the string directly with sqlite instead of manipulating multiple strings afterwards, it's faster.
# {"id":"${id}","address":"${address}","imported":"${imported}","unconfirmedCallbackURL":"${cb0conf_url}","confirmedCallbackURL":"${cb1conf_url}","watching_since":"${timestamp}"}
watches=$(sql "SELECT '{\"id\":' || id || ',\"address\":\"' || address || '\",\"imported\":' || imported || ',\"unconfirmedCallbackURL\":\"' || COALESCE(callback0conf, '') || '\",\"confirmedCallbackURL\":\"' || COALESCE(callback1conf, '') || '\",\"label\":\"' || COALESCE(label, '') || '\",\"watching_since\":\"' || inserted_ts || '\"}' FROM watching WHERE watching AND NOT calledback1conf")
watches=$(sql "SELECT '{\"id\":' || id || ',\"address\":\"' || address || '\",\"imported\":' || imported || ',\"unconfirmedCallbackURL\":' || CASE WHEN callback0conf IS NULL THEN 'null' ELSE ('\"' || callback0conf || '\"') END || ',\"confirmedCallbackURL\":' || CASE WHEN callback1conf IS NULL THEN 'null' ELSE ('\"' || callback1conf || '\"') END || ',\"label\":\"' || COALESCE(label, '') || '\",\"watching_since\":\"' || inserted_ts || '\"}' FROM watching WHERE watching AND NOT calledback1conf ORDER BY id")
returncode=$?
trace_rc ${returncode}
@@ -99,7 +99,7 @@ getactivewatchesbyxpub() {
local xpub=${1}
local returncode
getactivewatchesxpub "pub32" ${xpub}
getactivewatchesxpub "pub32" "${xpub}"
returncode=$?
trace_rc ${returncode}
@@ -112,7 +112,7 @@ getactivewatchesbylabel() {
local label=${1}
local returncode
getactivewatchesxpub "label" ${label}
getactivewatchesxpub "label" "${label}"
returncode=$?
trace_rc ${returncode}
@@ -130,7 +130,7 @@ getactivewatchesxpub() {
# Let's build the string directly with sqlite instead of manipulating multiple strings afterwards, it's faster.
# {"id":"${id}","address":"${address}","imported":"${imported}","unconfirmedCallbackURL":"${cb0conf_url}","confirmedCallbackURL":"${cb1conf_url}","watching_since":"${timestamp}","derivation_path":"${derivation_path}","pub32_index":"${pub32_index}"}
watches=$(sql "SELECT '{\"id\":' || w.id || ',\"address\":\"' || address || '\",\"imported\":' || imported || ',\"unconfirmedCallbackURL\":\"' || COALESCE(w.callback0conf, '') || '\",\"confirmedCallbackURL\":\"' || COALESCE(w.callback1conf, '') || '\",\"watching_since\":\"' || w.inserted_ts || '\",\"derivation_path\":\"' || derivation_path || '\",\"pub32_index\":' || pub32_index || '}' FROM watching w, watching_by_pub32 w32 WHERE watching_by_pub32_id = w32.id AND ${where} = \"${value}\" AND w.watching AND NOT calledback1conf")
watches=$(sql "SELECT '{\"id\":' || w.id || ',\"address\":\"' || address || '\",\"imported\":' || imported || ',\"unconfirmedCallbackURL\":' || CASE WHEN w.callback0conf IS NULL THEN 'null' ELSE ('\"' || w.callback0conf || '\"') END || ',\"confirmedCallbackURL\":' || CASE WHEN w.callback1conf IS NULL THEN 'null' ELSE ('\"' || w.callback1conf || '\"') END || ',\"watching_since\":\"' || w.inserted_ts || '\",\"derivation_path\":\"' || derivation_path || '\",\"pub32_index\":' || pub32_index || '}' FROM watching w, watching_by_pub32 w32 WHERE watching_by_pub32_id = w32.id AND w32.${where} = '${value}' AND w.watching AND NOT calledback1conf ORDER BY w.id")
returncode=$?
trace_rc ${returncode}
@@ -162,7 +162,7 @@ getactivexpubwatches() {
local watches
# Let's build the string directly with sqlite instead of manipulating multiple strings afterwards, it's faster.
# {"id":"${id}","pub32":"${pub32}","label":"${label}","derivation_path":"${derivation_path}","last_imported_n":${last_imported_n},"unconfirmedCallbackURL":"${cb0conf_url}","confirmedCallbackURL":"${cb1conf_url}","watching_since":"${timestamp}"}
watches=$(sql "SELECT '{\"id\":' || id || ',\"pub32\":\"' || pub32 || '\",\"label\":\"' || label || '\",\"derivation_path\":\"' || derivation_path || '\",\"last_imported_n\":' || last_imported_n || ',\"unconfirmedCallbackURL\":\"' || COALESCE(callback0conf, '') || '\",\"confirmedCallbackURL\":\"' || COALESCE(callback1conf, '') || '\",\"watching_since\":\"' || inserted_ts || '\"}' FROM watching_by_pub32 WHERE watching")
watches=$(sql "SELECT '{\"id\":' || id || ',\"pub32\":\"' || pub32 || '\",\"label\":\"' || label || '\",\"derivation_path\":\"' || derivation_path || '\",\"last_imported_n\":' || last_imported_n || ',\"unconfirmedCallbackURL\":' || CASE WHEN callback0conf IS NULL THEN 'null' ELSE ('\"' || callback0conf || '\"') END || ',\"confirmedCallbackURL\":' || CASE WHEN callback1conf IS NULL THEN 'null' ELSE ('\"' || callback1conf || '\"') END || ',\"watching_since\":\"' || inserted_ts || '\"}' FROM watching_by_pub32 WHERE watching ORDER BY id")
returncode=$?
trace_rc ${returncode}

View File

@@ -11,7 +11,7 @@ importaddress_rpc() {
if [ -z "${label}" ]; then
label="null"
fi
local data='{"method":"importaddress","params":{"address":"'${address}'","label":'${label}',"rescan":false}}'
local data='{"method":"importaddress","params":{"address":"'${address}'","label":"'${label}'","rescan":false}}'
# local data="{\"method\":\"importaddress\",\"params\":[\"${address}\",\"\",false]}"
local result
result=$(send_to_watcher_node ${data})
@@ -39,7 +39,7 @@ importmulti_rpc() {
# {"address":"2N6Q9kBcLtNswgMSLSQ5oduhbctk7hxEJW8"},
# {"scriptPubKey":{"address":"2N6Q9kBcLtNswgMSLSQ5oduhbctk7hxEJW8"},"timestamp":"now","watchonly":true,"label":"xpub"},
addresses=$(echo "${addresses}" | sed "s/\"address\"/\"scriptPubKey\":\{\"address\"/g" | sed "s/}/},\"timestamp\":\"now\",\"watchonly\":true,\"label\":${label}}/g")
addresses=$(echo "${addresses}" | sed "s/\"address\"/\"scriptPubKey\":\{\"address\"/g" | sed "s/}/},\"timestamp\":\"now\",\"watchonly\":true,\"label\":\"${label}\"}/g")
# trace "[importmulti_rpc] addresses=${addresses}"
# Now we use that in the RPC string

View File

@@ -25,7 +25,7 @@ manage_not_imported() {
returncode=$?
trace_rc ${returncode}
if [ "${returncode}" -eq 0 ]; then
sql "UPDATE watching SET imported=1 WHERE address=\"${address}\""
sql "UPDATE watching SET imported=true WHERE address='${address}'"
fi
done
@@ -41,8 +41,8 @@ manage_missed_conf() {
trace "[Entering manage_missed_conf()]"
local watches=$(sql 'SELECT DISTINCT address FROM watching w LEFT JOIN watching_tx ON w.id = watching_id LEFT JOIN tx t ON t.id = tx_id WHERE watching AND imported AND (tx_id IS NULL OR t.confirmations=0) ORDER BY address')
trace "[manage_missed_conf] watches=${watches}"
local watches=$(sql "SELECT DISTINCT address FROM watching w LEFT JOIN watching_tx ON w.id = watching_id LEFT JOIN tx t ON t.id = tx_id WHERE watching AND imported AND (tx_id IS NULL OR t.confirmations=0) ORDER BY address")
# trace "[manage_missed_conf] watches=${watches}"
if [ ${#watches} -eq 0 ]; then
trace "[manage_missed_conf] Nothing missed!"
return 0
@@ -55,7 +55,7 @@ manage_missed_conf() {
data='{"method":"listreceivedbyaddress","params":[0,false,true]}'
received=$(send_to_watcher_node "${data}")
received_addresses=$(echo "${received}" | jq -r ".result[].address" | sort)
trace "[manage_missed_conf] received_addresses=${received_addresses}"
# trace "[manage_missed_conf] received_addresses=${received_addresses}"
# Let's extract addresses that are in the watches list as well as in the received_addresses list
echo "${watches}" > watches-$$
@@ -81,7 +81,7 @@ manage_missed_conf() {
local IFS=$'\n'
for address in ${received_watches}
do
watching=$(sql 'SELECT address, inserted_ts FROM watching WHERE address="'${address}'"')
watching=$(sql "SELECT address, inserted_ts FROM watching WHERE address='${address}'")
trace "[manage_missed_conf] watching=${watching}"
if [ ${#watching} -eq 0 ]; then
trace "[manage_missed_conf] Nothing missed!"
@@ -90,7 +90,7 @@ manage_missed_conf() {
# Let's get confirmed received txs for the address
# address=$(echo "${watches}" | cut -d '|' -f1)
inserted_ts=$(date -d "$(echo "${watching}" | cut -d '|' -f2)" +"%s")
inserted_ts=$(date -d "$(echo "${watching}" | cut -d '|' -f2)" -D '%Y-%m-%d %H:%M:%S' +"%s")
trace "[manage_missed_conf] inserted_ts=${inserted_ts}"
received_address=$(echo "${received}" | jq -Mc ".result | map(select(.address==\"${address}\" and .confirmations>0))[0]")

View File

@@ -25,6 +25,7 @@ newblock() {
returncode=$?
trace_rc ${returncode}
# do_callbacks_txid "$(echo "${blockinfo}" | jq ".result.tx[]")"
do_callbacks_txid
batch_check_webhooks

View File

@@ -49,18 +49,20 @@ serve_ots_stamp() {
returncode=$?
fi
else
sql "INSERT OR IGNORE INTO stamp (hash, callbackUrl) VALUES (\"${hash}\", \"${callbackUrl}\")"
id_inserted=$(sql "INSERT INTO stamp (hash, callbackUrl)"\
" VALUES ('${hash}','${callbackUrl}')"\
" RETURNING id" \
"SELECT id FROM stamp WHERE hash='${hash}'")
returncode=$?
trace_rc ${returncode}
if [ "${returncode}" -eq "0" ]; then
id_inserted=$(sql "SELECT id FROM stamp WHERE hash='${hash}'")
trace_rc $?
errorstring=$(request_ots_stamp "${hash}" ${id_inserted})
returncode=$?
trace_rc ${returncode}
else
trace "[serve_ots_stamp] Stamp request could not be inserted in DB"
errorstring="Stamp request could not be inserted in DB, please retry later"
id_inserted=null
returncode=1
fi
fi
@@ -114,7 +116,7 @@ request_ots_stamp() {
if [ "${returncode}" -eq "0" ]; then
# "already exists" found, let's try updating DB again
trace "[request_ots_stamp] was already requested to the OTS server... let's update the DB, looks like it didn't work on first try"
sql "UPDATE stamp SET requested=1 WHERE id=${id}"
sql "UPDATE stamp SET requested=true WHERE id=${id}"
errorstring="Duplicate stamping request, hash already exists in DB and been OTS requested"
returncode=1
else
@@ -125,7 +127,7 @@ request_ots_stamp() {
fi
else
trace "[request_ots_stamp] Stamping request sent successfully!"
sql "UPDATE stamp SET requested=1 WHERE id=${id}"
sql "UPDATE stamp SET requested=true WHERE id=${id}"
errorstring=""
returncode=0
fi
@@ -198,7 +200,7 @@ serve_ots_backoffice() {
else
# No failure, upgraded
trace "[serve_ots_backoffice] just upgraded!"
sql "UPDATE stamp SET upgraded=1 WHERE id=${id}"
sql "UPDATE stamp SET upgraded=true WHERE id=${id}"
trace_rc $?
upgraded=1
@@ -221,13 +223,13 @@ serve_ots_backoffice() {
# Even if curl executed ok, we need to make sure the http return code is also ok
if [ "${returncode}" -eq "0" ]; then
sql "UPDATE stamp SET calledback=1 WHERE id=${id}"
sql "UPDATE stamp SET calledback=true WHERE id=${id}"
trace_rc $?
fi
else
trace "[serve_ots_backoffice] url is empty, obviously won't try to call it!"
sql "UPDATE stamp SET calledback=1 WHERE id=${id}"
sql "UPDATE stamp SET calledback=true WHERE id=${id}"
trace_rc $?
fi
fi

View File

@@ -76,8 +76,10 @@ main() {
case "${cmd}" in
helloworld)
# GET http://192.168.111.152:8080/helloworld
response_to_client "Hello, world!" 0
break
response="Hello, world!"
returncode=0
# response_to_client "Hello, world!" 0
# break
;;
installation_info)
# GET http://192.168.111.152:8080/info
@@ -86,8 +88,7 @@ main() {
else
response='{ "error": "missing installation data" }'
fi
response_to_client "${response}" ${?}
break
returncode=$?
;;
watch)
# POST http://192.168.111.152:8080/watch
@@ -96,8 +97,7 @@ main() {
# BODY {"address":"2N8DcqzfkYi8CkYzvNNS5amoq3SbAcQNXKp","confirmedCallbackURL":"192.168.111.233:1111/callback1conf","eventMessage":"eyJib3VuY2VfYWRkcmVzcyI6IjJNdkEzeHIzOHIxNXRRZWhGblBKMVhBdXJDUFR2ZTZOamNGIiwibmJfY29uZiI6MH0K","label":"myLabel"}
response=$(watchrequest "${line}")
response_to_client "${response}" ${?}
break
returncode=$?
;;
unwatch)
# curl (GET) 192.168.111.152:8080/unwatch/2N8DcqzfkYi8CkYzvNNS5amoq3SbAcQNXKp
@@ -122,16 +122,15 @@ main() {
# Let's make it work even for a GET request (equivalent to a POST with empty json object body)
if [ "$http_method" = "POST" ]; then
address=$(echo "${line}" | jq -r ".address")
unconfirmedCallbackURL=$(echo "${line}" | jq ".unconfirmedCallbackURL")
confirmedCallbackURL=$(echo "${line}" | jq ".confirmedCallbackURL")
unconfirmedCallbackURL=$(echo "${line}" | jq -r ".unconfirmedCallbackURL")
confirmedCallbackURL=$(echo "${line}" | jq -r ".confirmedCallbackURL")
watchid=$(echo "${line}" | jq ".id")
else
address=$(echo "${line}" | cut -d ' ' -f2 | cut -d '/' -f3)
fi
response=$(unwatchrequest "${watchid}" "${address}" "${unconfirmedCallbackURL}" "${confirmedCallbackURL}")
response_to_client "${response}" ${?}
break
returncode=$?
;;
watchxpub)
# POST http://192.168.111.152:8080/watchxpub
@@ -139,43 +138,37 @@ main() {
# curl -H "Content-Type: application/json" -d '{"label":"2219","pub32":"upub5GtUcgGed1aGH4HKQ3vMYrsmLXwmHhS1AeX33ZvDgZiyvkGhNTvGd2TA5Lr4v239Fzjj4ZY48t6wTtXUy2yRgapf37QHgt6KWEZ6bgsCLpb","path":"0/1/n","nstart":55,"unconfirmedCallbackURL":"192.168.111.233:1111/callback0conf","confirmedCallbackURL":"192.168.111.233:1111/callback1conf"}' proxy:8888/watchxpub
response=$(watchpub32request "${line}")
response_to_client "${response}" ${?}
break
returncode=$?
;;
unwatchxpubbyxpub)
# GET http://192.168.111.152:8080/unwatchxpubbyxpub/tpubD6NzVbkrYhZ4YR3QK2tyfMMvBghAvqtNaNK1LTyDWcRHLcMUm3ZN2cGm5BS3MhCRCeCkXQkTXXjiJgqxpqXK7PeUSp86DTTgkLpcjMtpKWk
response=$(unwatchpub32request "${line}")
response_to_client "${response}" ${?}
break
returncode=$?
;;
unwatchxpubbylabel)
# GET http://192.168.111.152:8080/unwatchxpubbylabel/4421
response=$(unwatchpub32labelrequest "${line}")
response_to_client "${response}" ${?}
break
returncode=$?
;;
getactivewatchesbyxpub)
# GET http://192.168.111.152:8080/getactivewatchesbyxpub/tpubD6NzVbkrYhZ4YR3QK2tyfMMvBghAvqtNaNK1LTyDWcRHLcMUm3ZN2cGm5BS3MhCRCeCkXQkTXXjiJgqxpqXK7PeUSp86DTTgkLpcjMtpKWk
response=$(getactivewatchesbyxpub "$(echo "${line}" | cut -d ' ' -f2 | cut -d '/' -f3)")
response_to_client "${response}" ${?}
break
returncode=$?
;;
getactivewatchesbylabel)
# GET http://192.168.111.152:8080/getactivewatchesbylabel/4421
response=$(getactivewatchesbylabel "$(echo "${line}" | cut -d ' ' -f2 | cut -d '/' -f3)")
response_to_client "${response}" ${?}
break
returncode=$?
;;
getactivexpubwatches)
# GET http://192.168.111.152:8080/getactivexpubwatches
response=$(getactivexpubwatches)
response_to_client "${response}" ${?}
break
returncode=$?
;;
watchtxid)
# POST http://192.168.111.152:8080/watchtxid
@@ -183,8 +176,7 @@ main() {
# curl -H "Content-Type: application/json" -d '{"txid":"b081ca7724386f549cf0c16f71db6affeb52ff7a0d9b606fb2e5c43faffd3387","confirmedCallbackURL":"192.168.111.233:1111/callback1conf","xconfCallbackURL":"192.168.111.233:1111/callbackXconf","nbxconf":6}' proxy:8888/watchtxid
response=$(watchtxidrequest "${line}")
response_to_client "${response}" ${?}
break
returncode=$?
;;
unwatchtxid)
# POST http://192.168.111.152:8080/unwatchtxid
@@ -200,87 +192,76 @@ main() {
# - id: the id returned by watchtxid
local txid=$(echo "${line}" | jq -r ".txid")
local unconfirmedCallbackURL=$(echo "${line}" | jq ".unconfirmedCallbackURL")
local confirmedCallbackURL=$(echo "${line}" | jq ".confirmedCallbackURL")
local unconfirmedCallbackURL=$(echo "${line}" | jq -r ".unconfirmedCallbackURL")
local confirmedCallbackURL=$(echo "${line}" | jq -r ".confirmedCallbackURL")
local watchid=$(echo "${line}" | jq ".id")
response=$(unwatchtxidrequest "${watchid}" "${txid}" "${unconfirmedCallbackURL}" "${confirmedCallbackURL}")
response_to_client "${response}" ${?}
break
returncode=$?
;;
getactivewatches)
# curl (GET) 192.168.111.152:8080/getactivewatches
response=$(getactivewatches)
response_to_client "${response}" ${?}
break
returncode=$?
;;
get_txns_by_watchlabel)
# curl (GET) 192.168.111.152:8080/get_txns_by_watchlabel/<label>/<count>
response=$(get_txns_by_watchlabel "$(echo "${line}" | cut -d ' ' -f2 | cut -d '/' -f3)" "$(echo "${line}" | cut -d ' ' -f2 | cut -d '/' -f4)")
response_to_client "${response}" ${?}
break
returncode=$?
;;
get_unused_addresses_by_watchlabel)
# curl (GET) 192.168.111.152:8080/get_unused_addresses_by_watchlabel/<label>/<count>
response=$(get_unused_addresses_by_watchlabel "$(echo "${line}" | cut -d ' ' -f2 | cut -d '/' -f3)" "$(echo "${line}" | cut -d ' ' -f2 | cut -d '/' -f4)")
response_to_client "${response}" ${?}
break
returncode=$?
;;
conf)
# curl (GET) 192.168.111.152:8080/conf/b081ca7724386f549cf0c16f71db6affeb52ff7a0d9b606fb2e5c43faffd3387
response=$(confirmation_request "${line}")
response_to_client "${response}" ${?}
break
returncode=$?
;;
newblock)
# curl (GET) 192.168.111.152:8080/newblock/000000000000005c987120f3b6f995c95749977ef1a109c89aa74ce4bba97c1f
response=$(newblock "${line}")
response_to_client "${response}" ${?}
break
returncode=$?
;;
getbestblockhash)
# curl (GET) http://192.168.111.152:8080/getbestblockhash
response=$(get_best_block_hash)
response_to_client "${response}" ${?}
break
returncode=$?
;;
getblockhash)
# curl (GET) http://192.168.111.152:8080/getblockhash/522322
response=$(get_blockhash "$(echo "${line}" | cut -d ' ' -f2 | cut -d '/' -f3)")
response_to_client "${response}" ${?}
break
returncode=$?
;;
getblockinfo)
# curl (GET) http://192.168.111.152:8080/getblockinfo/000000006f82a384c208ecfa04d05beea02d420f3f398ddda5c7f900de5718ea
response=$(get_block_info "$(echo "${line}" | cut -d ' ' -f2 | cut -d '/' -f3)")
response_to_client "${response}" ${?}
break
returncode=$?
;;
getblockchaininfo)
# http://192.168.111.152:8080/getblockchaininfo
response=$(get_blockchain_info)
response_to_client "${response}" ${?}
returncode=$?
;;
gettransaction)
# curl (GET) http://192.168.111.152:8080/gettransaction/af867c86000da76df7ddb1054b273ca9e034e8c89d049b5b2795f9f590f67648
response=$(get_rawtransaction "$(echo "${line}" | cut -d ' ' -f2 | cut -d '/' -f3)")
response_to_client "${response}" ${?}
break
returncode=$?
;;
getbestblockinfo)
# curl (GET) http://192.168.111.152:8080/getbestblockinfo
response=$(get_best_block_info)
response_to_client "${response}" ${?}
break
returncode=$?
;;
executecallbacks)
# curl (GET) http://192.168.111.152:8080/executecallbacks
@@ -288,43 +269,37 @@ main() {
manage_not_imported
manage_missed_conf
response=$(do_callbacks)
response_to_client "${response}" ${?}
break
returncode=$?
;;
get_txns_spending)
# curl (GET) http://192.168.111.152:8080/get_txns_spending/20/10
response=$(get_txns_spending "$(echo "${line}" | cut -d ' ' -f2 | cut -d '/' -f3)" "$(echo "${line}" | cut -d ' ' -f2 | cut -d '/' -f4)")
response_to_client "${response}" ${?}
break
returncode=$?
;;
getbalance)
# curl (GET) http://192.168.111.152:8080/getbalance
response=$(getbalance)
response_to_client "${response}" ${?}
break
returncode=$?
;;
getbalances)
# curl (GET) http://192.168.111.152:8080/getbalances
response=$(getbalances)
response_to_client "${response}" ${?}
break
returncode=$?
;;
getbalancebyxpub)
# curl (GET) http://192.168.111.152:8080/getbalancebyxpub/upub5GtUcgGed1aGH4HKQ3vMYrsmLXwmHhS1AeX33ZvDgZiyvkGhNTvGd2TA5Lr4v239Fzjj4ZY48t6wTtXUy2yRgapf37QHgt6KWEZ6bgsCLpb
response=$(getbalancebyxpub "$(echo "${line}" | cut -d ' ' -f2 | cut -d '/' -f3)")
response_to_client "${response}" ${?}
break
returncode=$?
;;
getbalancebyxpublabel)
# curl (GET) http://192.168.111.152:8080/getbalancebyxpublabel/2219
response=$(getbalancebyxpublabel "$(echo "${line}" | cut -d ' ' -f2 | cut -d '/' -f3)")
response_to_client "${response}" ${?}
break
returncode=$?
;;
getnewaddress)
# curl (GET) http://192.168.111.152:8080/getnewaddress
@@ -346,8 +321,7 @@ main() {
fi
response=$(getnewaddress "${address_type}" "${label}")
response_to_client "${response}" ${?}
break
returncode=$?
;;
validateaddress)
# GET http://192.168.111.152:8080/validateaddress/tb1p5cyxnuxmeuwuvkwfem96lqzszd02n6xdcjrs20cac6yqjjwudpxqp3mvzv
@@ -361,8 +335,7 @@ main() {
# BODY {"address":"2N8DcqzfkYi8CkYzvNNS5amoq3SbAcQNXKp","amount":0.00233,"eventMessage":"eyJ3aGF0ZXZlciI6MTIzfQo=","confTarget":6,"replaceable":true,"subtractfeefromamount":false}
response=$(spend "${line}")
response_to_client "${response}" ${?}
break
returncode=$?
;;
bumpfee)
# POST http://192.168.111.152:8080/bumpfee
@@ -370,8 +343,7 @@ main() {
# BODY {"txid":"af867c86000da76df7ddb1054b273ca9e034e8c89d049b5b2795f9f590f67648"}
response=$(bumpfee "${line}")
response_to_client "${response}" ${?}
break
returncode=$?
;;
createbatcher)
# POST http://192.168.111.152:8080/createbatcher
@@ -388,8 +360,7 @@ main() {
# NOTYET BODY {"batcherLabel":"highfees","feeRate":231.8}
response=$(createbatcher "${line}")
response_to_client "${response}" ${?}
break
returncode=$?
;;
updatebatcher)
# POST http://192.168.111.152:8080/updatebatcher
@@ -412,8 +383,7 @@ main() {
# BODY {"batcherLabel":"fast","confTarget":2}
response=$(updatebatcher "${line}")
response_to_client "${response}" ${?}
break
returncode=$?
;;
addtobatch)
# POST http://192.168.111.152:8080/addtobatch
@@ -439,8 +409,7 @@ main() {
# BODY {"address":"2N8DcqzfkYi8CkYzvNNS5amoq3SbAcQNXKp","amount":0.00233,"batcherId":34,"webhookUrl":"https://myCypherApp:3000/batchExecuted"}
response=$(addtobatch "${line}")
response_to_client "${response}" ${?}
break
returncode=$?
;;
removefrombatch)
# POST http://192.168.111.152:8080/removefrombatch
@@ -458,8 +427,7 @@ main() {
# BODY {"outputId":72}
response=$(removefrombatch "${line}")
response_to_client "${response}" ${?}
break
returncode=$?
;;
batchspend)
# POST http://192.168.111.152:8080/batchspend
@@ -511,8 +479,7 @@ main() {
# BODY {"batcherId":411,"confTarget":6}
response=$(batchspend "${line}")
response_to_client "${response}" ${?}
break
returncode=$?
;;
getbatcher)
# POST (GET) http://192.168.111.152:8080/getbatcher
@@ -528,14 +495,13 @@ main() {
# BODY {"batcherId":34}
response=$(getbatcher "${line}")
response_to_client "${response}" ${?}
break
returncode=$?
;;
getbatchdetails)
# POST (GET) http://192.168.111.152:8080/getbatchdetails
#
# args:
# - batcherId, optional, id of the batcher, overrides batcherLabel, default batcher will be spent if not supplied
# - batcherId, optional, id of the batcher, overrides batcherLabel, default batcher will be used if not supplied
# - batcherLabel, optional, label of the batcher, default batcher will be used if not supplied
# - txid, optional, if you want the details of an executed batch, supply the batch txid, will return current pending batch
# if not supplied
@@ -570,8 +536,7 @@ main() {
# BODY {"batcherId":34}
response=$(getbatchdetails "${line}")
response_to_client "${response}" ${?}
break
returncode=$?
;;
listbatchers)
# curl (GET) http://192.168.111.152:8080/listbatchers
@@ -585,24 +550,21 @@ main() {
# "error":null}
response=$(listbatchers)
response_to_client "${response}" ${?}
break
returncode=$?
;;
bitcoin_estimatesmartfee)
# POST http://192.168.111.152:8080/bitcoin_estimatesmartfee
# BODY {"confTarget":2}
response=$(bitcoin_estimatesmartfee "$(echo "${line}" | jq -r ".confTarget")")
response_to_client "${response}" ${?}
break
returncode=$?
;;
deriveindex)
# curl GET http://192.168.111.152:8080/deriveindex/25-30
# curl GET http://192.168.111.152:8080/deriveindex/34
response=$(deriveindex "$(echo "${line}" | cut -d ' ' -f2 | cut -d '/' -f3)")
response_to_client "${response}" ${?}
break
returncode=$?
;;
derivepubpath)
# POST http://192.168.111.152:8080/derivepubpath
@@ -611,16 +573,14 @@ main() {
# BODY {"pub32":"vpub5SLqN2bLY4WeZF3kL4VqiWF1itbf3A6oRrq9aPf16AZMVWYCuN9TxpAZwCzVgW94TNzZPNc9XAHD4As6pdnExBtCDGYRmNJrcJ4eV9hNqcv","path":"0/25-30"}
response=$(derivepubpath "${line}")
response_to_client "${response}" ${?}
break
returncode=$?
;;
deriveindex_bitcoind)
# curl GET http://192.168.111.152:8080/deriveindex_bitcoind/25-30
# curl GET http://192.168.111.152:8080/deriveindex_bitcoind/34
response=$(deriveindex_bitcoind "$(echo "${line}" | cut -d ' ' -f2 | cut -d '/' -f3)")
response_to_client "${response}" ${?}
break
returncode=$?
;;
derivepubpath_bitcoind)
# POST http://192.168.111.152:8080/derivepubpath_bitcoind
@@ -629,45 +589,39 @@ main() {
# BODY {"pub32":"vpub5SLqN2bLY4WeZF3kL4VqiWF1itbf3A6oRrq9aPf16AZMVWYCuN9TxpAZwCzVgW94TNzZPNc9XAHD4As6pdnExBtCDGYRmNJrcJ4eV9hNqcv","path":"0/25-30"}
response=$(derivepubpath_bitcoind "${line}")
response_to_client "${response}" ${?}
break
returncode=$?
;;
getmempoolinfo)
# curl GET http://192.168.111.152:8080/getmempoolinfo
response=$(get_mempool_info)
response_to_client "${response}" ${?}
break
returncode=$?
;;
ln_getinfo)
# GET http://192.168.111.152:8080/ln_getinfo
response=$(ln_getinfo)
response_to_client "${response}" ${?}
break
returncode=$?
;;
ln_getconnectionstring)
# GET http://192.168.111.152:8080/ln_getconnectionstring
response=$(ln_get_connection_string)
response_to_client "${response}" ${?}
break
returncode=$?
;;
ln_create_invoice)
# POST http://192.168.111.152:8080/ln_create_invoice
# BODY {"msatoshi":"10000","label":"koNCcrSvhX3dmyFhW","description":"Bylls order #10649","expiry":"900","callback_url":"http://192.168.122.159"}
response=$(ln_create_invoice "${line}")
response_to_client "${response}" ${?}
break
returncode=$?
;;
ln_pay)
# POST http://192.168.111.152:8080/ln_pay
# BODY {"bolt11":"lntb1pdca82tpp5gv8mn5jqlj6xztpnt4r472zcyrwf3y2c3cvm4uzg2gqcnj90f83qdp2gf5hgcm0d9hzqnm4w3kx2apqdaexgetjyq3nwvpcxgcqp2g3d86wwdfvyxcz7kce7d3n26d2rw3wf5tzpm2m5fl2z3mm8msa3xk8nv2y32gmzlhwjved980mcmkgq83u9wafq9n4w28amnmwzujgqpmapcr3","expected_msatoshi":"10000","expected_description":"Bitcoin Outlet order #7082"}
response=$(ln_pay "${line}")
response_to_client "${response}" ${?}
break
returncode=$?
;;
ln_listpays)
# GET http://192.168.111.152:8080/ln_listpays
@@ -683,8 +637,7 @@ main() {
fi
response=$(ln_listpays "${bolt11}")
response_to_client "${response}" ${?}
break
returncode=$?
;;
ln_paystatus)
# GET http://192.168.111.152:8080/ln_paystatus
@@ -700,15 +653,13 @@ main() {
fi
response=$(ln_paystatus "${bolt11}")
response_to_client "${response}" ${?}
break
returncode=$?
;;
ln_newaddr)
# GET http://192.168.111.152:8080/ln_newaddr
response=$(ln_newaddr)
response_to_client "${response}" ${?}
break
returncode=$?
;;
ln_connectfund)
# POST http://192.168.111.152:8080/ln_connectfund
@@ -716,64 +667,50 @@ main() {
# curl -H "Content-Type: application/json" -d '{"peer":"nodeId@ip:port","msatoshi":"100000","callbackUrl":"https://callbackUrl/?channelReady=f3y2c3cvm4uzg2gq"}' proxy:8888/ln_connectfund
response=$(ln_connectfund "${line}")
response_to_client "${response}" ${?}
break
returncode=$?
;;
ln_getinvoice)
# GET http://192.168.111.152:8080/ln_getinvoice/label
# GET http://192.168.111.152:8080/ln_getinvoice/koNCcrSvhX3dmyFhW
response=$(ln_getinvoice "$(echo "${line}" | cut -d ' ' -f2 | cut -d '/' -f3)")
response_to_client "${response}" ${?}
break
returncode=$?
;;
ln_delinvoice)
# GET http://192.168.111.152:8080/ln_delinvoice/label
# GET http://192.168.111.152:8080/ln_delinvoice/koNCcrSvhX3dmyFhW
response=$(ln_delinvoice "$(echo "${line}" | cut -d ' ' -f2 | cut -d '/' -f3)")
response_to_client "${response}" ${?}
break
returncode=$?
;;
ln_decodebolt11)
# GET http://192.168.111.152:8080/ln_decodebolt11/bolt11
# GET http://192.168.111.152:8080/ln_decodebolt11/lntb1pdca82tpp5gv8mn5jqlj6xztpnt4r472zcyrwf3y2c3cvm4uzg2gqcnj90f83qdp2gf5hgcm0d9hzqnm4w3kx2apqdaexgetjyq3nwvpcxgcqp2g3d86wwdfvyxcz7kce7d3n26d2rw3wf5tzpm2m5fl2z3mm8msa3xk8nv2y32gmzlhwjved980mcmkgq83u9wafq9n4w28amnmwzujgqpmapcr3
response=$(ln_decodebolt11 "$(echo "${line}" | cut -d ' ' -f2 | cut -d '/' -f3)")
response_to_client "${response}" ${?}
break
returncode=$?
;;
ln_listpeers)
# GET http://192.168.111.152:8080/ln_listpeers
response=$(ln_listpeers)
response_to_client "${response}" ${?}
break
returncode=$?
;;
ln_listfunds)
# GET http://192.168.111.152:8080/ln_listfunds
response=$(ln_listfunds)
response_to_client "${response}" ${?}
break
returncode=$?
;;
# ln_listpays)
# # GET http://192.168.111.152:8080/ln_listpays
# response=$(ln_listpays)
# response_to_client "${response}" ${?}
# break
# ;;
ln_getroute)
# GET http://192.168.111.152:8080/ln_getroute/<node_id>/<msatoshi>/<riskfactor>
response=$(ln_getroute "$(echo "${line}" | cut -d ' ' -f2 | cut -d '/' -f3)" "$(echo "${line}" | cut -d ' ' -f2 | cut -d '/' -f4)" "$(echo "${line}" | cut -d ' ' -f2 | cut -d '/' -f5)")
response_to_client "${response}" ${?}
break
returncode=$?
;;
ln_withdraw)
# POST http://192.168.111.152:8080/ln_withdraw
# BODY {"destination":"segwitAddress","satoshi":"100000","feerate":0,all: false}
response=$(ln_withdraw "${line}")
response_to_client "${response}" ${?}
break
returncode=$?
;;
ots_stamp)
# POST http://192.168.111.152:8080/ots_stamp
@@ -782,15 +719,13 @@ main() {
# curl -v -d "{\"hash\":\"a6ea81a46fec3d02d40815b8667b388351edecedc1cc9f97aab55b566db7aac8\"}" localhost:8888/ots_stamp
response=$(serve_ots_stamp "${line}")
response_to_client "${response}" ${?}
break
returncode=$?
;;
ots_backoffice)
# curl (GET) http://192.168.111.152:8080/ots_upgradeandcallback
response=$(serve_ots_backoffice)
response_to_client "${response}" ${?}
break
returncode=$?
;;
ots_getfile)
# curl (GET) http://192.168.111.152:8080/ots_getfile/1ddfb769eb0b8876bc570e25580e6a53afcf973362ee1ee4b54a807da2e5eed7
@@ -807,8 +742,7 @@ main() {
# curl -v -d "{\"hash\":\"a6ea81a46fec3d02d40815b8667b388351edecedc1cc9f97aab55b566db7aac8\",\"base64otsfile\":\"$(cat a6ea81a46fec3d02d40815b8667b388351edecedc1cc9f97aab55b566db7aac8.ots | base64 | tr -d '\n')\"}" localhost:8888/ots_verify
response=$(serve_ots_verify "${line}")
response_to_client "${response}" ${?}
break
returncode=$?
;;
ots_info)
# POST http://192.168.111.152:8080/ots_info
@@ -821,10 +755,15 @@ main() {
# curl -v -d "{\"hash\":\"a6ea81a46fec3d02d40815b8667b388351edecedc1cc9f97aab55b566db7aac8\",\"base64otsfile\":\"$(cat a6ea81a46fec3d02d40815b8667b388351edecedc1cc9f97aab55b566db7aac8.ots | base64 | tr -d '\n')\"}" localhost:8888/ots_info
response=$(serve_ots_info "${line}")
response_to_client "${response}" ${?}
break
returncode=$?
;;
*)
response='{"error": {"code": -32601, "message": "Method not found"}, "id": "1"}'
returncode=1
;;
esac
response=$(echo "${response}" | jq -Mc)
response_to_client "${response}" ${returncode}
break
fi
done

View File

@@ -3,6 +3,35 @@
. ./trace.sh
sql() {
trace "Entering sql()..."
local select_id=${2}
local response
local inserted_id
trace "[sql] psql -qAtX -h postgres -U cyphernode -c \"${1}\""
response=$(psql -qAtX -h postgres -U cyphernode -c "${1}")
returncode=$?
trace_rc ${returncode}
if [ -n "${select_id}" ]; then
if [ "${returncode}" -eq "0" ]; then
inserted_id=$(echo "${response}" | cut -d ' ' -f1)
else
trace "[sql] psql -qAtX -h postgres -U cyphernode -c \"${select_id}\""
inserted_id=$(psql -qAtX -h postgres -U cyphernode -c "${select_id}")
returncode=$?
trace_rc ${returncode}
fi
echo -n "${inserted_id}"
else
echo -n "${response}"
fi
return ${returncode}
}
sql_sqlite() {
trace "sqlite3 -cmd \".timeout 40000\" ${DB_FILE} \"${1}\""
sqlite3 -cmd ".timeout 40000" ${DB_FILE} "${1}"
@@ -14,16 +43,3 @@ sql() {
return $?
}
sql_rawtx() {
trace "sqlite3 -cmd \".timeout 40000\" ${DB_FILE}_rawtx \"${1}\""
sqlite3 -cmd ".timeout 40000" ${DB_FILE}_rawtx "${1}"
if [ "$?" -ne 0 ]; then
# SQL didn't work, let's retry to be sure...
trace "SQL didn't work, let's retry..."
sqlite3 -cmd ".timeout 40000" ${DB_FILE}_rawtx "${1}"
fi
return $?
}

View File

@@ -33,7 +33,6 @@ createCurlConfig() {
if [ ! -e ${DB_FILE} ]; then
echo "DB not found, creating..."
cat cyphernode.sql | sqlite3 $DB_FILE
cat rawtx.sql | sqlite3 ${DB_FILE}_rawtx
else
echo "DB found, migrating..."
for script in sqlmigrate*.sh; do
@@ -42,7 +41,6 @@ else
fi
chmod 0600 $DB_FILE
chmod 0600 ${DB_FILE}_rawtx
createCurlConfig ${WATCHER_BTC_NODE_RPC_CFG} ${WATCHER_BTC_NODE_RPC_USER}
createCurlConfig ${SPENDER_BTC_NODE_RPC_CFG} ${SPENDER_BTC_NODE_RPC_USER}

View File

@@ -16,10 +16,10 @@ unwatchrequest() {
# Let's lowercase bech32 addresses
address=$(lowercase_if_bech32 "${address}")
trace "[unwatchrequest] Unwatch request id ${watchid} on address ${address} with url0conf ${unconfirmedCallbackURL} and url1conf ${confirmedCallbackURL}"
trace "[unwatchrequest] Unwatch request id ${watchid} on address \"${address}\" with url0conf \"${unconfirmedCallbackURL}\" and url1conf \"${confirmedCallbackURL}\""
if [ "${watchid}" != "null" ]; then
sql "UPDATE watching SET watching=0 WHERE id=${watchid}"
sql "UPDATE watching SET watching=false WHERE id=${watchid}"
returncode=$?
trace_rc ${returncode}
@@ -35,11 +35,11 @@ unwatchrequest() {
cb1_where=" AND callback1conf='${confirmedCallbackURL}'"
fi
sql "UPDATE watching SET watching=0 WHERE address='${address}'${cb0_where}${cb1_where}"
sql "UPDATE watching SET watching=false WHERE address='${address}'${cb0_where}${cb1_where}"
returncode=$?
trace_rc ${returncode}
data="{\"event\":\"unwatch\",\"address\":\"${address}\",\"unconfirmedCallbackURL\":${unconfirmedCallbackURL},\"confirmedCallbackURL\":${confirmedCallbackURL}}"
data="{\"event\":\"unwatch\",\"address\":\"${address}\",\"unconfirmedCallbackURL\":\"${unconfirmedCallbackURL}\",\"confirmedCallbackURL\":\"${confirmedCallbackURL}\"}"
fi
trace "[unwatchrequest] responding=${data}"
@@ -52,20 +52,19 @@ unwatchrequest() {
unwatchpub32request() {
trace "Entering unwatchpub32request()..."
# GET http://192.168.111.152:8080/unwatchxpubbyxpub/tpubD6NzVbkrYhZ4YR3QK2tyfMMvBghAvqtNaNK1LTyDWcRHLcMUm3ZN2cGm5BS3MhCRCeCkXQkTXXjiJgqxpqXK7PeUSp86DTTgkLpcjMtpKWk
local request=${1}
local pub32=$(echo "${request}" | cut -d ' ' -f2 | cut -d '/' -f3)
local id
local returncode
trace "[unwatchpub32request] Unwatch pub32 ${pub32}"
id=$(sql "SELECT id FROM watching_by_pub32 WHERE pub32='${pub32}'")
trace "[unwatchpub32request] id: ${id}"
sql "UPDATE watching_by_pub32 SET watching=0 WHERE id=${id}"
sql "UPDATE watching w SET watching=false FROM watching_by_pub32 w32 WHERE w.watching_by_pub32_id=w32.id AND pub32='${pub32}'"
returncode=$?
trace_rc ${returncode}
sql "UPDATE watching SET watching=0 WHERE watching_by_pub32_id=\"${id}\""
sql "UPDATE watching_by_pub32 SET watching=false WHERE pub32='${pub32}'"
returncode=$?
trace_rc ${returncode}
@@ -86,16 +85,11 @@ unwatchpub32labelrequest() {
local returncode
trace "[unwatchpub32labelrequest] Unwatch xpub label ${label}"
id=$(sql "SELECT id FROM watching_by_pub32 WHERE label='${label}'")
returncode=$?
trace_rc ${returncode}
trace "[unwatchpub32labelrequest] id: ${id}"
sql "UPDATE watching_by_pub32 SET watching=0 WHERE id=${id}"
sql "UPDATE watching w SET watching=false FROM watching_by_pub32 w32 WHERE w.watching_by_pub32_id=w32.id AND w32.label='${label}'"
returncode=$?
trace_rc ${returncode}
sql "UPDATE watching SET watching=0 WHERE watching_by_pub32_id=\"${id}\""
sql "UPDATE watching_by_pub32 SET watching=false WHERE label='${label}'"
returncode=$?
trace_rc ${returncode}
@@ -112,23 +106,30 @@ unwatchtxidrequest() {
local watchid=${1}
local txid=${2}
local unconfirmedCallbackURL=${3}
local uc_pg uc_json
[ "${unconfirmedCallbackURL}" = "null" ] && uc_pg=" IS NULL" && uc_json="null" || uc_pg="='${unconfirmedCallbackURL}'" && uc_json="\"${unconfirmedCallbackURL}\""
local confirmedCallbackURL=${4}
local c_pg c_json
[ "${confirmedCallbackURL}" = "null" ] && c_pg=" IS NULL" && c_json="null" || c_pg="='${confirmedCallbackURL}'" && c_json="\"${confirmedCallbackURL}\""
local returncode
trace "[unwatchtxidrequest] Unwatch request id ${watchid} on txid ${txid} with url0conf ${unconfirmedCallbackURL} and url1conf ${confirmedCallbackURL}"
trace "[unwatchtxidrequest] Unwatch request id ${watchid} on txid \"${txid}\" with url0conf \"${unconfirmedCallbackURL}\" and url1conf \"${confirmedCallbackURL}\""
if [ "${watchid}" != "null" ]; then
sql "UPDATE watching_by_txid SET watching=0 WHERE id=${watchid}"
sql "UPDATE watching_by_txid SET watching=false WHERE id=${watchid}"
returncode=$?
trace_rc ${returncode}
data="{\"event\":\"unwatchtxid\",\"id\":${watchid}}"
else
sql "UPDATE watching_by_txid SET watching=0 WHERE txid='${txid}' AND callback0conf=${unconfirmedCallbackURL} AND callback1conf=${confirmedCallbackURL}"
sql "UPDATE watching_by_txid SET watching=false WHERE txid='${txid}' AND callback0conf${uc_pg} AND callback1conf${c_pg}"
returncode=$?
trace_rc ${returncode}
data="{\"event\":\"unwatchtxid\",\"txid\":\"${txid}\",\"unconfirmedCallbackURL\":${unconfirmedCallbackURL},\"confirmedCallbackURL\":${confirmedCallbackURL}}"
data="{\"event\":\"unwatchtxid\",\"txid\":\"${txid}\",\"unconfirmedCallbackURL\":${uc_json},\"confirmedCallbackURL\":${c_json}}"
fi
trace "[unwatchtxidrequest] responding=${data}"

View File

@@ -42,14 +42,14 @@ ln_waitanyinvoice() {
status=$(echo "${result}" | jq -r ".status")
paid_at=$(echo "${result}" | jq -r ".paid_at")
sql "UPDATE ln_invoice SET status=\"${status}\", pay_index=${pay_index}, msatoshi_received=${msatoshi_received}, paid_at=${paid_at} WHERE bolt11=\"${bolt11}\""
row=$(sql "SELECT id, label, bolt11, callback_url, payment_hash, msatoshi, status, pay_index, msatoshi_received, paid_at, description, expires_at FROM ln_invoice WHERE callback_url<>\"\" AND NOT calledback AND bolt11=\"${bolt11}\"")
sql "UPDATE ln_invoice SET status='${status}', pay_index=${pay_index}, msatoshi_received=${msatoshi_received}, paid_at=${paid_at} WHERE bolt11='${bolt11}'"
row=$(sql "SELECT id, label, bolt11, callback_url, payment_hash, msatoshi, status, pay_index, msatoshi_received, paid_at, description, expires_at FROM ln_invoice WHERE callback_url<>'' AND NOT calledback AND bolt11='${bolt11}'")
if [ -n "${row}" ]; then
ln_manage_callback ${row}
fi
sql "UPDATE cyphernode_props SET value="${pay_index}" WHERE property=\"pay_index\""
sql "UPDATE cyphernode_props SET value='${pay_index}' WHERE property='pay_index'"
fi
}

View File

@@ -42,7 +42,7 @@ spend() {
tx_raw_details=$(get_rawtransaction ${txid} | tr -d '\n')
# Amounts and fees are negative when spending so we absolute those fields
local tx_hash=$(echo "${tx_raw_details}" | jq '.result.hash')
local tx_hash=$(echo "${tx_raw_details}" | jq -r '.result.hash')
local tx_ts_firstseen=$(echo "${tx_details}" | jq '.result.timereceived')
local tx_amount=$(echo "${tx_details}" | jq '.result.amount | fabs' | awk '{ printf "%.8f", $0 }')
local tx_size=$(echo "${tx_raw_details}" | jq '.result.size')
@@ -50,9 +50,6 @@ spend() {
local tx_replaceable=$(echo "${tx_details}" | jq -r '.result."bip125-replaceable"')
tx_replaceable=$([ ${tx_replaceable} = "yes" ] && echo "true" || echo "false")
local fees=$(echo "${tx_details}" | jq '.result.fee | fabs' | awk '{ printf "%.8f", $0 }')
# Sometimes raw tx are too long to be passed as paramater, so let's write
# it to a temp file for it to be read by sqlite3 and then delete the file
echo "${tx_raw_details}" > spend-rawtx-${txid}-$$.blob
########################################################################################################
# Let's publish the event if needed
@@ -73,20 +70,17 @@ spend() {
########################################################################################################
# Let's insert the txid in our little DB -- then we'll already have it when receiving confirmation
sql "INSERT OR IGNORE INTO tx (txid, hash, confirmations, timereceived, fee, size, vsize, is_replaceable, conf_target) VALUES (\"${txid}\", ${tx_hash}, 0, ${tx_ts_firstseen}, ${fees}, ${tx_size}, ${tx_vsize}, ${tx_replaceable}, ${conf_target})"
id_inserted=$(sql "INSERT INTO tx (txid, hash, confirmations, timereceived, fee, size, vsize, is_replaceable, conf_target)"\
" VALUES ('${txid}', '${tx_hash}', 0, ${tx_ts_firstseen}, ${fees}, ${tx_size}, ${tx_vsize}, ${tx_replaceable}, ${conf_target})"\
" RETURNING id" \
"SELECT id FROM tx WHERE txid='${txid}'")
trace_rc $?
sql_rawtx "INSERT OR IGNORE INTO rawtx (txid, hash, confirmations, timereceived, fee, size, vsize, is_replaceable, conf_target, raw_tx) VALUES (\"${txid}\", ${tx_hash}, 0, ${tx_ts_firstseen}, ${fees}, ${tx_size}, ${tx_vsize}, ${tx_replaceable}, ${conf_target}, readfile('spend-rawtx-${txid}-$$.blob'))"
trace_rc $?
id_inserted=$(sql "SELECT id FROM tx WHERE txid=\"${txid}\"")
trace_rc $?
sql "INSERT OR IGNORE INTO recipient (address, amount, tx_id) VALUES (\"${address}\", ${amount}, ${id_inserted})"
sql "INSERT INTO recipient (address, amount, tx_id) VALUES ('${address}', ${amount}, ${id_inserted})"\
" ON CONFLICT DO NOTHING"
trace_rc $?
data="{\"status\":\"accepted\""
data="${data},\"txid\":\"${txid}\",\"hash\":${tx_hash},\"details\":{\"address\":\"${address}\",\"amount\":${amount},\"firstseen\":${tx_ts_firstseen},\"size\":${tx_size},\"vsize\":${tx_vsize},\"replaceable\":${tx_replaceable},\"fee\":${fees},\"subtractfeefromamount\":${subtractfeefromamount}}}"
# Delete the temp file containing the raw tx (see above)
rm spend-rawtx-${txid}-$$.blob
data="${data},\"txid\":\"${txid}\",\"hash\":\"${tx_hash}\",\"details\":{\"address\":\"${address}\",\"amount\":${amount},\"firstseen\":${tx_ts_firstseen},\"size\":${tx_size},\"vsize\":${tx_vsize},\"replaceable\":${tx_replaceable},\"fee\":${fees},\"subtractfeefromamount\":${subtractfeefromamount}}}"
else
local message=$(echo "${response}" | jq -e ".error.message")
data="{\"message\":${message}}"
@@ -222,7 +216,7 @@ getbalancebyxpublabel() {
trace "[getbalancebyxpublabel] label=${label}"
local xpub
xpub=$(sql "SELECT pub32 FROM watching_by_pub32 WHERE label=\"${label}\"")
xpub=$(sql "SELECT pub32 FROM watching_by_pub32 WHERE label='${label}'")
trace "[getbalancebyxpublabel] xpub=${xpub}"
getbalancebyxpub ${xpub} "getbalancebyxpublabel"

View File

@@ -11,11 +11,72 @@ watchrequest() {
local returncode
local request=${1}
local address=$(echo "${request}" | jq -r ".address")
local cb0conf_url=$(echo "${request}" | jq ".unconfirmedCallbackURL")
local cb1conf_url=$(echo "${request}" | jq ".confirmedCallbackURL")
local event_message=$(echo "${request}" | jq ".eventMessage")
local label=$(echo "${request}" | jq ".label")
local address address_pg
address=$(echo "${request}" | jq -re ".address")
if [ "$?" -ne "0" ]; then
# address not found or null
result='{"result":null,'\
'"error":{'\
'"code":-5,'\
'"message":"address required"}}'
trace "[watchrequest] address required"
trace "[watchrequest] responding=${result}"
echo "${result}"
return 1
else
address_pg="'${address}'"
fi
local cb0conf_url cb0conf_url_pg cb0conf_url_pg_where cb0conf_url_json
cb0conf_url=$(echo "${request}" | jq -re ".unconfirmedCallbackURL")
if [ "$?" -ne "0" ]; then
# unconfirmedCallbackURL not found or null
cb0conf_url_json="null"
cb0conf_url_pg="null"
cb0conf_url_pg_where=" IS NULL"
else
cb0conf_url_json="\"${cb0conf_url}\""
cb0conf_url_pg="'${cb0conf_url}'"
cb0conf_url_pg_where="=${cb0conf_url_pg}"
fi
local cb1conf_url cb1conf_url_pg cb1conf_url_pg_where cb1conf_url_json
cb1conf_url=$(echo "${request}" | jq -re ".confirmedCallbackURL")
if [ "$?" -ne "0" ]; then
# confirmedCallbackURL not found or null
cb1conf_url_json="null"
cb1conf_url_pg="null"
cb1conf_url_pg_where=" IS NULL"
else
cb1conf_url_json="\"${cb1conf_url}\""
cb1conf_url_pg="'${cb1conf_url}'"
cb1conf_url_pg_where="=${cb1conf_url_pg}"
fi
local event_message event_message_pg event_message_json
event_message=$(echo "${request}" | jq -re ".eventMessage")
if [ "$?" -ne "0" ]; then
# eventMessage not found or null
event_message_json="null"
event_message_pg="null"
else
event_message_json="\"${event_message}\""
event_message_pg="'${event_message}'"
fi
local label label_pg label_json
label=$(echo "${request}" | jq -re ".label")
if [ "$?" -ne "0" ]; then
# label not found or null
label_json="null"
label_pg="null"
else
label_json="\"${label}\""
label_pg="'${label}'"
fi
local imported
local inserted
local id_inserted
@@ -24,23 +85,23 @@ watchrequest() {
# Let's lowercase bech32 addresses
address=$(lowercase_if_bech32 "${address}")
trace "[watchrequest] Watch request on address (\"${address}\"), cb 0-conf (${cb0conf_url}), cb 1-conf (${cb1conf_url}) with event_message=${event_message} and label=${label}"
trace "[watchrequest] Watch request on address (${address}), cb 0-conf (${cb0conf_url_json}), cb 1-conf (${cb1conf_url_json}) with event_message=${event_message_json} and label=${label_json}"
local isvalid
isvalid=$(validateaddress "${address}" | jq ".result.isvalid")
if [ "${isvalid}" != "true" ]; then
result="{
\"result\":null,
\"error\":{
\"code\":-5,
\"message\":\"Invalid address\",
\"data\":{
\"event\":\"watch\",
\"address\":\"${address}\",
\"unconfirmedCallbackURL\":${cb0conf_url},
\"confirmedCallbackURL\":${cb1conf_url},
\"label\":${label},
\"eventMessage\":${event_message}}}}"
result='{'\
'"result":null,'\
'"error":{'\
'"code":-5,'\
'"message":"Invalid address",'\
'"data":{'\
'"event":"watch",'\
'"address":'"${address}"','\
'"unconfirmedCallbackURL":'${cb0conf_url_json}','\
'"confirmedCallbackURL":'${cb1conf_url_json}','\
'"label":'${label_json}','\
'"eventMessage":'${event_message_json}'}}}'
trace "[watchrequest] Invalid address"
trace "[watchrequest] responding=${result}"
@@ -53,21 +114,26 @@ watchrequest() {
returncode=$?
trace_rc ${returncode}
if [ "${returncode}" -eq 0 ]; then
imported=1
imported=true
else
imported=0
imported=false
fi
sql "INSERT INTO watching (address, watching, callback0conf, callback1conf, imported, event_message, label) VALUES (\"${address}\", 1, ${cb0conf_url}, ${cb1conf_url}, ${imported}, ${event_message}, ${label}) ON CONFLICT(address,callback0conf,callback1conf) DO UPDATE SET watching=1, event_message=${event_message}, calledback0conf=0, calledback1conf=0, label=${label}"
id_inserted=$(sql "INSERT INTO watching (address, watching, callback0conf, callback1conf, imported, event_message, label)"\
" VALUES (${address_pg}, true, ${cb0conf_url_pg}, ${cb1conf_url_pg}, ${imported}, ${event_message_pg}, ${label_pg})"\
" ON CONFLICT (address, COALESCE(callback0conf, ''), COALESCE(callback1conf, '')) DO"\
" UPDATE SET watching=true, event_message=${event_message_pg}, calledback0conf=false, calledback1conf=false, label=${label_pg}"\
" RETURNING id" \
"SELECT id FROM watching WHERE address=${address_pg} AND callback0conf${cb0conf_url_pg_where} AND callback1conf${cb1conf_url_pg_where}")
returncode=$?
trace_rc ${returncode}
trace "[watchrequest] id_inserted=${id_inserted}"
if [ "${returncode}" -eq 0 ]; then
inserted=1
id_inserted=$(sql "SELECT id FROM watching WHERE address='${address}' AND callback0conf=${cb0conf_url} AND callback1conf=${cb1conf_url}")
inserted=true
trace "[watchrequest] id_inserted: ${id_inserted}"
else
inserted=0
inserted=false
fi
local fees2blocks
@@ -83,19 +149,19 @@ watchrequest() {
fees144blocks=$(getestimatesmartfee 144)
trace_rc $?
result="{\"id\":\"${id_inserted}\",
\"event\":\"watch\",
\"imported\":${imported},
\"inserted\":${inserted},
\"address\":\"${address}\",
\"unconfirmedCallbackURL\":${cb0conf_url},
\"confirmedCallbackURL\":${cb1conf_url},
\"label\":${label},
\"estimatesmartfee2blocks\":${fees2blocks},
\"estimatesmartfee6blocks\":${fees6blocks},
\"estimatesmartfee36blocks\":${fees36blocks},
\"estimatesmartfee144blocks\":${fees144blocks},
\"eventMessage\":${event_message}}"
result='{"id":'${id_inserted}','\
'"event":"watch",'\
'"imported":'${imported}','\
'"inserted":'${inserted}','\
'"address":"'${address}'",'\
'"unconfirmedCallbackURL":'${cb0conf_url_json}','\
'"confirmedCallbackURL":'${cb1conf_url_json}','\
'"label":'${label_json}','\
'"estimatesmartfee2blocks":'${fees2blocks}','\
'"estimatesmartfee6blocks":'${fees6blocks}','\
'"estimatesmartfee36blocks":'${fees36blocks}','\
'"estimatesmartfee144blocks":'${fees144blocks}','\
'"eventMessage":'${event_message_json}'}'
trace "[watchrequest] responding=${result}"
echo "${result}"
@@ -106,19 +172,56 @@ watchrequest() {
watchpub32request() {
trace "Entering watchpub32request()..."
# BODY {"label":"4421","pub32":"tpubD6NzVbkrYhZ4YR3QK2tyfMMvBghAvqtNaNK1LTyDWcRHLcMUm3ZN2cGm5BS3MhCRCeCkXQkTXXjiJgqxpqXK7PeUSp86DTTgkLpcjMtpKWk","path":"0/n","nstart":0,"unconfirmedCallbackURL":"192.168.111.233:1111/callback0conf","confirmedCallbackURL":"192.168.111.233:1111/callback1conf"}
# Required:
# - "label"
# - "pub32"
# - "path"
# - "nstart"
local returncode
local request=${1}
local label=$(echo "${request}" | jq ".label")
local label=$(echo "${request}" | jq -er ".label")
if [ "$?" -ne "0" ]; then
# label not found or null
trace "[watchpub32request] label required"
echo '{"error":"label required","event":"watchxpub"}'
return 1
fi
trace "[watchpub32request] label=${label}"
local pub32=$(echo "${request}" | jq ".pub32")
local pub32=$(echo "${request}" | jq -er ".pub32")
if [ "$?" -ne "0" ]; then
# pub32 not found or null
trace "[watchpub32request] pub32 required"
echo '{"error":"pub32 required","event":"watchxpub"}'
return 1
fi
trace "[watchpub32request] pub32=${pub32}"
local path=$(echo "${request}" | jq ".path")
local path=$(echo "${request}" | jq -er ".path")
if [ "$?" -ne "0" ]; then
# path not found or null
trace "[watchpub32request] path required"
echo '{"error":"path required","event":"watchxpub"}'
return 1
fi
trace "[watchpub32request] path=${path}"
local nstart=$(echo "${request}" | jq ".nstart")
local nstart=$(echo "${request}" | jq -er ".nstart")
if [ "$?" -ne "0" ]; then
# nstart not found or null
trace "[watchpub32request] nstart required"
echo '{"error":"nstart required","event":"watchxpub"}'
return 1
fi
trace "[watchpub32request] nstart=${nstart}"
local cb0conf_url=$(echo "${request}" | jq ".unconfirmedCallbackURL")
local cb0conf_url=$(echo "${request}" | jq -r ".unconfirmedCallbackURL // empty")
trace "[watchpub32request] cb0conf_url=${cb0conf_url}"
local cb1conf_url=$(echo "${request}" | jq ".confirmedCallbackURL")
local cb1conf_url=$(echo "${request}" | jq -r ".confirmedCallbackURL // empty")
trace "[watchpub32request] cb1conf_url=${cb1conf_url}"
watchpub32 "${label}" "${pub32}" "${path}" "${nstart}" "${cb0conf_url}" "${cb1conf_url}"
@@ -131,21 +234,46 @@ watchpub32request() {
watchpub32() {
trace "Entering watchpub32()..."
# Expecting args without quotes
# label, pub32, path and nstart are required
# When cb0conf_url and cb1conf_url are empty, means null
local returncode
local label=${1}
trace "[watchpub32] label=${label}"
local label_pg="'${label}'"
trace "[watchpub32] label=${label}, label_pg=${label_pg}"
local pub32=${2}
trace "[watchpub32] pub32=${pub32}"
local pub32_pg="'${pub32}'"
trace "[watchpub32] pub32=${pub32}, pub32_pg=${pub32_pg}"
local path=${3}
trace "[watchpub32] path=${path}"
local path_pg="'${path}'"
trace "[watchpub32] path=${path}, path_pg=${path_pg}"
local nstart=${4}
trace "[watchpub32] nstart=${nstart}"
local last_n=$((${nstart}+${XPUB_DERIVATION_GAP}))
trace "[watchpub32] last_n=${last_n}"
local cb0conf_url=${5}
trace "[watchpub32] cb0conf_url=${cb0conf_url}"
local cb0conf_url_pg cb0conf_url_json
if [ -z "${cb0conf_url}" ]; then
# Empty url
cb0conf_url_json="null"
cb0conf_url_pg="null"
else
cb0conf_url_json="\"${cb0conf_url}\""
cb0conf_url_pg="'${cb0conf_url}'"
fi
trace "[watchpub32] cb0conf_url=${cb0conf_url}, cb0conf_url_pg=${cb0conf_url_pg}"
local cb1conf_url=${6}
trace "[watchpub32] cb1conf_url=${cb1conf_url}"
local cb1conf_url_pg cb1conf_url_json
if [ -z "${cb1conf_url}" ]; then
# Empty url
cb1conf_url_json="null"
cb1conf_url_pg="null"
else
cb1conf_url_json="\"${cb1conf_url}\""
cb1conf_url_pg="'${cb1conf_url}'"
fi
trace "[watchpub32] cb1conf_url=${cb1conf_url}, cb1conf_url_pg=${cb1conf_url_pg}"
# upto_n is used when extending the watching window
local upto_n=${7}
@@ -156,7 +284,7 @@ watchpub32() {
local error_msg
local data
# Derive with pycoin...
# Derive with bitcoind...
# {"pub32":"tpubD6NzVbkrYhZ4YR3QK2tyfMMvBghAvqtNaNK1LTyDWcRHLcMUm3ZN2cGm5BS3MhCRCeCkXQkTXXjiJgqxpqXK7PeUSp86DTTgkLpcjMtpKWk","path":"0/25-30"}
if [ -n "${upto_n}" ]; then
# If upto_n provided, then we create from nstart to upto_n (instead of + GAP)
@@ -165,7 +293,7 @@ watchpub32() {
local subspath=$(echo -e $path | sed -En "s/n/${nstart}-${last_n}/p")
trace "[watchpub32] subspath=${subspath}"
local addresses
addresses=$(derivepubpath "{\"pub32\":${pub32},\"path\":${subspath}}")
addresses=$(derivepubpath '{"pub32":"'${pub32}'","path":"'${subspath}'"}')
returncode=$?
trace_rc ${returncode}
# trace "[watchpub32] addresses=${addresses}"
@@ -179,7 +307,7 @@ watchpub32() {
if [ "${returncode}" -eq 0 ]; then
# Importmulti in Bitcoin Core...
result=$(importmulti_rpc "${WATCHER_BTC_NODE_XPUB_WALLET}" ${pub32} "${addresses}")
result=$(importmulti_rpc "${WATCHER_BTC_NODE_XPUB_WALLET}" "${pub32}" "${addresses}")
returncode=$?
trace_rc ${returncode}
trace "[watchpub32] result=${result}"
@@ -187,29 +315,31 @@ watchpub32() {
if [ "${returncode}" -eq 0 ]; then
if [ -n "${upto_n}" ]; then
# Update existing row, we are extending the watching window
sql "UPDATE watching_by_pub32 set last_imported_n=${upto_n} WHERE pub32=${pub32}"
id_inserted=$(sql "UPDATE watching_by_pub32 set last_imported_n=${upto_n} WHERE pub32=${pub32_pg} RETURNING id")
returncode=$?
trace_rc ${returncode}
else
# Insert in our DB...
sql "INSERT INTO watching_by_pub32 (pub32, label, derivation_path, watching, callback0conf, callback1conf, last_imported_n) VALUES (${pub32}, ${label}, ${path}, 1, ${cb0conf_url}, ${cb1conf_url}, ${last_n})"
id_inserted=$(sql "INSERT INTO watching_by_pub32 (pub32, label, derivation_path, watching, callback0conf, callback1conf, last_imported_n)"\
" VALUES (${pub32_pg}, ${label_pg}, ${path_pg}, true, ${cb0conf_url_pg}, ${cb1conf_url_pg}, ${last_n})"\
" ON CONFLICT (pub32) DO"\
" UPDATE SET watching=true, label=${label_pg}, callback0conf=${cb0conf_url_pg}, callback1conf=${cb1conf_url_pg}, derivation_path=${path_pg}, last_imported_n=${last_n}"\
" RETURNING id" \
"SELECT id FROM watching_by_pub32 WHERE pub32=${pub32_pg}")
returncode=$?
trace_rc ${returncode}
if [ "${returncode}" -ne "0" ]; then
trace "[watchpub32] xpub or label already being watched, updating with new values based on supplied xpub..."
sql "UPDATE watching_by_pub32 SET watching=1, label=${label}, callback0conf=${cb0conf_url}, callback1conf=${cb1conf_url} WHERE pub32=${pub32}"
returncode=$?
trace_rc ${returncode}
fi
fi
if [ "${returncode}" -eq 0 ]; then
id_inserted=$(sql "SELECT id FROM watching_by_pub32 WHERE pub32=${pub32}")
trace "[watchpub32] id_inserted: ${id_inserted}"
addresses=$(echo ${addresses} | jq ".addresses[].address")
insert_watches "${addresses}" "${cb0conf_url}" "${cb1conf_url}" "${id_inserted}" "${nstart}"
addresses=$(echo ${addresses} | jq -r ".addresses[].address")
insert_watches "${addresses}" "${label}" "${cb0conf_url}" "${cb1conf_url}" "${id_inserted}" "${nstart}"
returncode=$?
trace_rc ${returncode}
if [ "${returncode}" -ne 0 ]; then
error_msg="Can't insert xpub watches in DB"
fi
else
error_msg="Can't insert xpub watcher in DB"
fi
@@ -224,25 +354,25 @@ watchpub32() {
fi
if [ -z "${error_msg}" ]; then
data="{\"id\":${id_inserted},
\"event\":\"watchxpub\",
\"pub32\":${pub32},
\"label\":${label},
\"path\":${path},
\"nstart\":${nstart},
\"unconfirmedCallbackURL\":${cb0conf_url},
\"confirmedCallbackURL\":${cb1conf_url}}"
data='{"id":'${id_inserted}','\
'"event":"watchxpub",'\
'"pub32":"'${pub32}'",'\
'"label":"'${label}'",'\
'"path":"'${path}'",'\
'"nstart":'${nstart}','\
'"unconfirmedCallbackURL":'${cb0conf_url_json}','\
'"confirmedCallbackURL":'${cb1conf_url_json}'}'
returncode=0
else
data="{\"error\":\"${error_msg}\",
\"event\":\"watchxpub\",
\"pub32\":${pub32},
\"label\":${label},
\"path\":${path},
\"nstart\":${nstart},
\"unconfirmedCallbackURL\":${cb0conf_url},
\"confirmedCallbackURL\":${cb1conf_url}}"
data='{"error":"'${error_msg}'",'\
'"event":"watchxpub",'\
'"pub32":"'${pub32}'",'
'"label":"'${label}'",'\
'"path":"'${path}'",'\
'"nstart":${nstart},'\
'"unconfirmedCallbackURL":'${cb0conf_url_json}','\
'"confirmedCallbackURL":'${cb1conf_url_json}'}'
returncode=1
fi
@@ -256,29 +386,54 @@ watchpub32() {
insert_watches() {
trace "Entering insert_watches()..."
# Expecting args without quotes
# When callback0conf and callback1conf are empty, means null
local addresses=${1}
local callback0conf=${2}
local callback1conf=${3}
local xpub_id=${4}
local nstart=${5}
local inserted_values=""
local label=${2}
local label_pg
if [ -z "${label}" ]; then
# Empty url
label_pg="null"
else
label_pg="'${label}'"
fi
local callback0conf=${3}
local callback0conf_pg
if [ -z "${callback0conf}" ]; then
# Empty url
callback0conf_pg="null"
else
callback0conf_pg="'${callback0conf}'"
fi
local callback1conf=${4}
local callback1conf_pg
if [ -z "${callback1conf}" ]; then
# Empty url
callback1conf_pg="null"
else
callback1conf_pg="'${callback1conf}'"
fi
local xpub_id=${5}
local nstart=${6}
local inserted_values
local IFS=$'\n'
for address in ${addresses}
do
# (address, watching, callback0conf, callback1conf, imported, watching_by_pub32_id)
# (address, label, watching, callback0conf, callback1conf, imported, watching_by_pub32_id)
if [ -n "${inserted_values}" ]; then
inserted_values="${inserted_values},"
fi
inserted_values="${inserted_values}(${address}, 1, ${callback0conf}, ${callback1conf}, 1"
if [ -n "${xpub_id}" ]; then
inserted_values="${inserted_values}, ${xpub_id}, ${nstart}"
nstart=$((${nstart} + 1))
fi
inserted_values="${inserted_values})"
inserted_values="${inserted_values}('${address}', ${label_pg}, true, ${callback0conf_pg}, ${callback1conf_pg}, true, ${xpub_id}, ${nstart})"
nstart=$((${nstart} + 1))
done
sql "INSERT INTO watching (address, watching, callback0conf, callback1conf, imported, watching_by_pub32_id, pub32_index) VALUES ${inserted_values} ON CONFLICT(address,callback0conf,callback1conf) DO UPDATE SET watching=1, event_message=${event_message}, calledback0conf=0, calledback1conf=0"
sql "INSERT INTO watching (address, label, watching, callback0conf, callback1conf, imported, watching_by_pub32_id, pub32_index)"\
" VALUES ${inserted_values}"\
" ON CONFLICT (address, COALESCE(callback0conf, ''), COALESCE(callback1conf, '')) DO"\
" UPDATE SET watching=true, calledback0conf=false, calledback1conf=false, label=${label_pg}"
returncode=$?
trace_rc ${returncode}
@@ -288,6 +443,8 @@ insert_watches() {
extend_watchers() {
trace "Entering extend_watchers()..."
# Expecting args without quotes
local watching_by_pub32_id=${1}
trace "[extend_watchers] watching_by_pub32_id=${watching_by_pub32_id}"
local pub32_index=${2}
@@ -297,7 +454,8 @@ extend_watchers() {
local last_imported_n
local row
row=$(sql "SELECT COALESCE('\"'||pub32||'\"', 'null'), COALESCE('\"'||label||'\"', 'null'), COALESCE('\"'||derivation_path||'\"', 'null'), COALESCE('\"'||callback0conf||'\"', 'null'), COALESCE('\"'||callback1conf||'\"', 'null'), last_imported_n FROM watching_by_pub32 WHERE id=${watching_by_pub32_id} AND watching")
# row=$(sql "SELECT COALESCE('\"'||pub32||'\"', 'null'), COALESCE('\"'||label||'\"', 'null'), COALESCE('\"'||derivation_path||'\"', 'null'), COALESCE('\"'||callback0conf||'\"', 'null'), COALESCE('\"'||callback1conf||'\"', 'null'), last_imported_n FROM watching_by_pub32 WHERE id=${watching_by_pub32_id} AND watching")
row=$(sql "SELECT pub32, label, derivation_path, callback0conf, callback1conf, last_imported_n FROM watching_by_pub32 WHERE id=${watching_by_pub32_id} AND watching")
returncode=$?
trace_rc ${returncode}
@@ -335,52 +493,88 @@ watchtxidrequest() {
trace "Entering watchtxidrequest()..."
local returncode
local result
local request=${1}
trace "[watchtxidrequest] request=${request}"
local txid=$(echo "${request}" | jq ".txid")
trace "[watchtxidrequest] txid=${txid}"
local cb1conf_url=$(echo "${request}" | jq ".confirmedCallbackURL")
trace "[watchtxidrequest] cb1conf_url=${cb1conf_url}"
local cbxconf_url=$(echo "${request}" | jq ".xconfCallbackURL")
trace "[watchtxidrequest] cbxconf_url=${cbxconf_url}"
local txid txid_pg txid_pg_where
txid=$(echo "${request}" | jq -re ".txid")
if [ "$?" -ne "0" ]; then
# txid not found or null
result='{"result":null,'\
'"error":{'\
'"code":-5,'\
'"message":"txid required"}}'
trace "[watchrequest] txid required"
trace "[watchrequest] responding=${result}"
echo "${result}"
return 1
else
txid_pg="'${address}'"
fi
trace "[watchtxidrequest] txid=${txid}, txid_pg=${txid_pg}"
local cb1conf_url cb1conf_url_pg cb1conf_url_pg_where cb1conf_url_json
cb1conf_url=$(echo "${request}" | jq -re ".confirmedCallbackURL")
if [ "$?" -ne "0" ]; then
# cb1conf_url not found or null
cb1conf_url_json="null"
cb1conf_url_pg="null"
cb1conf_url_pg_where=" IS NULL"
else
cb1conf_url_json="\"${cb1conf_url}\""
cb1conf_url_pg="'${cb1conf_url}'"
cb1conf_url_pg_where="=${cb1conf_url_pg}"
fi
trace "[watchtxidrequest] cb1conf_url=${cb1conf_url}, cb1conf_url_pg=${cb1conf_url_pg}, cb1conf_url_pg_where=${cb1conf_url_pg_where}, cb1conf_url_json=${cb1conf_url_json}"
local cbxconf_url cbxconf_url_pg cbxconf_url_pg_where
cbxconf_url=$(echo "${request}" | jq -e ".xconfCallbackURL")
if [ "$?" -ne "0" ]; then
# cbxconf_url not found or null
cbxconf_url_json="null"
cbxconf_url_pg="null"
cbxconf_url_pg_where=" IS NULL"
else
cbxconf_url_json="\"${cbxconf_url}\""
cbxconf_url_pg="'${cbxconf_url}'"
cbxconf_url_pg_where="=${cbxconf_url_pg}"
fi
trace "[watchtxidrequest] cbxconf_url=${cbxconf_url}, cbxconf_url_pg=${cbxconf_url_pg}, cbxconf_url_pg_where=${cbxconf_url_pg_where}, cbxconf_url_json=${cbxconf_url_json}"
local nbxconf=$(echo "${request}" | jq ".nbxconf")
trace "[watchtxidrequest] nbxconf=${nbxconf}"
local cb1cond
local cbxcond
local inserted
local id_inserted
local result
trace "[watchtxidrequest] Watch request on txid (${txid}), cb 1-conf (${cb1conf_url}) and cb x-conf (${cbxconf_url}) on ${nbxconf} confirmations."
sql "INSERT INTO watching_by_txid (txid, watching, callback1conf, callbackxconf, nbxconf) VALUES (${txid}, 1, ${cb1conf_url}, ${cbxconf_url}, ${nbxconf}) ON CONFLICT(txid, callback1conf, callbackxconf) DO UPDATE SET watching=1, nbxconf=${nbxconf}, calledback1conf=0, calledbackxconf=0"
id_inserted=$(sql "INSERT INTO watching_by_txid (txid, watching, callback1conf, callbackxconf, nbxconf)"\
" VALUES (${txid_pg}, true, ${cb1conf_url_pg}, ${cbxconf_url_pg}, ${nbxconf})"\
" ON CONFLICT (txid, COALESCE(callback1conf, ''), COALESCE(callbackxconf, '')) DO"\
" UPDATE SET watching=true, nbxconf=${nbxconf}, calledback1conf=false, calledbackxconf=false"\
" RETURNING id" \
"SELECT id FROM watching_by_txid WHERE txid=${txid_pg} AND callback1conf${cb1conf_url_pg_where} AND callbackxconf${cbxconf_url_pg_where}")
returncode=$?
trace_rc ${returncode}
if [ "${returncode}" -eq 0 ]; then
inserted=1
if [ "${cb1conf_url}" = "null" ]; then
cb1cond=" IS NULL"
else
cb1cond="=${cb1conf_url}"
fi
if [ "${cbxconf_url}" = "null" ]; then
cbxcond=" IS NULL"
else
cbxcond="=${cbxconf_url}"
fi
id_inserted=$(sql "SELECT id FROM watching_by_txid WHERE txid=${txid} AND callback1conf${cb1cond} AND callbackxconf${cbxcond}")
inserted=true
trace "[watchtxidrequest] id_inserted: ${id_inserted}"
else
inserted=0
inserted=false
id_inserted=null
fi
local data="{\"id\":${id_inserted},
\"event\":\"watchtxid\",
\"inserted\":${inserted},
\"txid\":${txid},
\"confirmedCallbackURL\":${cb1conf_url},
\"xconfCallbackURL\":${cbxconf_url},
\"nbxconf\":${nbxconf}}"
local data='{"id":'${id_inserted}','\
'"event":"watchtxid",'\
'"inserted":'${inserted}','\
'"txid":"'${txid}'",'\
'"confirmedCallbackURL":'${cb1conf_url_json}','\
'"xconfCallbackURL":'${cbxconf_url_json}','\
'"nbxconf":'${nbxconf}'}'
trace "[watchtxidrequest] responding=${data}"
echo "${data}"