mirror of
https://github.com/aljazceru/cyphernode.git
synced 2025-12-18 21:25:06 +01:00
First pass of LN payment callbacks
This commit is contained in:
@@ -30,7 +30,7 @@ COPY app/data/* ./
|
|||||||
COPY app/script/* ./
|
COPY app/script/* ./
|
||||||
COPY --from=cyphernode/clightning:v0.6.2 /usr/bin/lightning-cli ./
|
COPY --from=cyphernode/clightning:v0.6.2 /usr/bin/lightning-cli ./
|
||||||
|
|
||||||
RUN chmod +x startproxy.sh requesthandler.sh lightning-cli sqlmigrate*.sh \
|
RUN chmod +x startproxy.sh requesthandler.sh lightning-cli sqlmigrate*.sh waitanyinvoice.sh \
|
||||||
&& chmod o+w . \
|
&& chmod o+w . \
|
||||||
&& mkdir db
|
&& mkdir db
|
||||||
|
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ COPY app/data/* ./
|
|||||||
COPY app/script/* ./
|
COPY app/script/* ./
|
||||||
COPY --from=cyphernode/clightning:v0.6.2 /usr/bin/lightning-cli ./
|
COPY --from=cyphernode/clightning:v0.6.2 /usr/bin/lightning-cli ./
|
||||||
|
|
||||||
RUN chmod +x startproxy.sh requesthandler.sh lightning-cli sqlmigrate*.sh \
|
RUN chmod +x startproxy.sh requesthandler.sh lightning-cli sqlmigrate*.sh waitanyinvoice.sh \
|
||||||
&& chmod o+w . \
|
&& chmod o+w . \
|
||||||
&& mkdir db
|
&& mkdir db
|
||||||
|
|
||||||
|
|||||||
@@ -87,3 +87,16 @@ CREATE TABLE cyphernode_props (
|
|||||||
CREATE INDEX idx_cp_property ON cyphernode_props (property);
|
CREATE INDEX idx_cp_property ON cyphernode_props (property);
|
||||||
|
|
||||||
INSERT INTO cyphernode_props (property, value) VALUES ("version", "0.1");
|
INSERT INTO cyphernode_props (property, value) VALUES ("version", "0.1");
|
||||||
|
INSERT INTO cyphernode_props (property, value) VALUES ("pay_index", "0");
|
||||||
|
|
||||||
|
CREATE TABLE ln_invoice (
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
bolt11 TEXT UNIQUE,
|
||||||
|
status TEXT,
|
||||||
|
callback_url TEXT,
|
||||||
|
calledback INTEGER DEFAULT FALSE,
|
||||||
|
callback_failed INTEGER DEFAULT FALSE,
|
||||||
|
inserted_ts INTEGER DEFAULT CURRENT_TIMESTAMP
|
||||||
|
)
|
||||||
|
CREATE INDEX idx_lninvoice_bolt11 ON ln_invoice (bolt11);
|
||||||
|
CREATE INDEX idx_lninvoice_status ON ln_invoice (status);
|
||||||
|
|||||||
10
proxy_docker/app/data/sqlmigrate20190104_0.1-0.2.sh
Normal file
10
proxy_docker/app/data/sqlmigrate20190104_0.1-0.2.sh
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
exists=$(sqlite3 db/proxydb "SELECT value FROM cyphernode_props WHERE property='pay_index'")
|
||||||
|
if [ -z "${exists}" ]; then
|
||||||
|
# pay_index not found, let's migrate
|
||||||
|
echo "Migrating database from v0.1 to v0.2..."
|
||||||
|
cat sqlmigrate20190104_0.1-0.2.sql | sqlite3 $DB_FILE
|
||||||
|
else
|
||||||
|
echo "Database v0.1 to v0.2 migration already done, skipping!"
|
||||||
|
fi
|
||||||
15
proxy_docker/app/data/sqlmigrate20190104_0.1-0.2.sql
Normal file
15
proxy_docker/app/data/sqlmigrate20190104_0.1-0.2.sql
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
PRAGMA foreign_keys = ON;
|
||||||
|
|
||||||
|
INSERT INTO cyphernode_props (property, value) VALUES ("pay_index", "0");
|
||||||
|
|
||||||
|
CREATE TABLE ln_invoice (
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
bolt11 TEXT UNIQUE,
|
||||||
|
status TEXT,
|
||||||
|
callback_url TEXT,
|
||||||
|
calledback INTEGER DEFAULT FALSE,
|
||||||
|
callback_failed INTEGER DEFAULT FALSE,
|
||||||
|
inserted_ts INTEGER DEFAULT CURRENT_TIMESTAMP
|
||||||
|
);
|
||||||
|
CREATE INDEX idx_lninvoice_bolt11 ON ln_invoice (bolt11);
|
||||||
|
CREATE INDEX idx_lninvoice_status ON ln_invoice (status);
|
||||||
@@ -4,99 +4,114 @@
|
|||||||
|
|
||||||
ln_create_invoice()
|
ln_create_invoice()
|
||||||
{
|
{
|
||||||
trace "Entering ln_create_invoice()..."
|
trace "Entering ln_create_invoice()..."
|
||||||
|
|
||||||
local result
|
local result
|
||||||
|
|
||||||
local request=${1}
|
local request=${1}
|
||||||
local msatoshi=$(echo "${request}" | jq ".msatoshi" | tr -d '"')
|
local msatoshi=$(echo "${request}" | jq ".msatoshi" | tr -d '"')
|
||||||
trace "[ln_create_invoice] msatoshi=${msatoshi}"
|
trace "[ln_create_invoice] msatoshi=${msatoshi}"
|
||||||
local label=$(echo "${request}" | jq ".label")
|
local label=$(echo "${request}" | jq ".label")
|
||||||
trace "[ln_create_invoice] label=${label}"
|
trace "[ln_create_invoice] label=${label}"
|
||||||
local description=$(echo "${request}" | jq ".description")
|
local description=$(echo "${request}" | jq ".description")
|
||||||
trace "[ln_create_invoice] description=${description}"
|
trace "[ln_create_invoice] description=${description}"
|
||||||
local expiry=$(echo "${request}" | jq ".expiry" | tr -d '"')
|
local expiry=$(echo "${request}" | jq ".expiry" | tr -d '"')
|
||||||
trace "[ln_create_invoice] expiry=${expiry}"
|
trace "[ln_create_invoice] expiry=${expiry}"
|
||||||
|
local callback_url=$(echo "${request}" | jq ".callback_url" | tr -d '"')
|
||||||
|
trace "[ln_create_invoice] callback_url=${callback_url}"
|
||||||
|
|
||||||
result=$(./lightning-cli invoice ${msatoshi} "${label}" "${description}" ${expiry})
|
#/proxy $ ./lightning-cli invoice 10000 "t1" "t1d" 60
|
||||||
returncode=$?
|
#{
|
||||||
trace_rc ${returncode}
|
# "payment_hash": "a74e6cccb06e26bcddc32c43674f9c3cf6b018a4cb9e9ff7f835cc59b091ae06",
|
||||||
trace "[ln_create_invoice] result=${result}"
|
# "expires_at": 1546648644,
|
||||||
|
# "bolt11": "lnbc100n1pwzllqgpp55a8xen9sdcntehwr93pkwnuu8nmtqx9yew0flalcxhx9nvy34crqdq9wsckgxqzpucqp2rzjqt04ll5ft3mcuy8hws4xcku2pnhma9r9mavtjtadawyrw5kgzp7g7zr745qq3mcqqyqqqqlgqqqqqzsqpcr85k33shzaxscpj29fadmjmfej6y2p380x9w4kxydqpxq87l6lshy69fry9q2yrtu037nt44x77uhzkdyn8043n5yj8tqgluvmcl69cquaxr68"
|
||||||
|
#}
|
||||||
|
|
||||||
echo "${result}"
|
result=$(./lightning-cli invoice ${msatoshi} "${label}" "${description}" ${expiry})
|
||||||
|
returncode=$?
|
||||||
|
trace_rc ${returncode}
|
||||||
|
trace "[ln_create_invoice] result=${result}"
|
||||||
|
|
||||||
return ${returncode}
|
local bolt11
|
||||||
|
bolt11=$(echo ${result} | jq ".bolt11" | tr -d '"')
|
||||||
|
trace "[ln_create_invoice] bolt11=${bolt11}"
|
||||||
|
sql "INSERT OR IGNORE INTO ln_invoice (bolt11, callback_url) VALUES (\"${bolt11}\", \"${callback_url}\")"
|
||||||
|
trace_rc $?
|
||||||
|
|
||||||
|
echo "${result}"
|
||||||
|
|
||||||
|
return ${returncode}
|
||||||
}
|
}
|
||||||
|
|
||||||
ln_getinfo()
|
ln_getinfo()
|
||||||
{
|
{
|
||||||
trace "Entering ln_get_info()..."
|
trace "Entering ln_get_info()..."
|
||||||
|
|
||||||
local result
|
local result
|
||||||
|
|
||||||
result=$(./lightning-cli getinfo)
|
result=$(./lightning-cli getinfo)
|
||||||
returncode=$?
|
returncode=$?
|
||||||
trace_rc ${returncode}
|
trace_rc ${returncode}
|
||||||
trace "[ln_getinfo] result=${result}"
|
trace "[ln_getinfo] result=${result}"
|
||||||
|
|
||||||
echo "${result}"
|
echo "${result}"
|
||||||
|
|
||||||
return ${returncode}
|
return ${returncode}
|
||||||
}
|
}
|
||||||
|
|
||||||
ln_pay() {
|
ln_pay() {
|
||||||
trace "Entering ln_pay()..."
|
trace "Entering ln_pay()..."
|
||||||
|
|
||||||
local result
|
local result
|
||||||
|
|
||||||
local request=${1}
|
local request=${1}
|
||||||
local bolt11=$(echo "${request}" | jq ".bolt11" | tr -d '"')
|
local bolt11=$(echo "${request}" | jq ".bolt11" | tr -d '"')
|
||||||
trace "[ln_pay] bolt11=${bolt11}"
|
trace "[ln_pay] bolt11=${bolt11}"
|
||||||
local expected_msatoshi=$(echo "${request}" | jq ".expected_msatoshi")
|
local expected_msatoshi=$(echo "${request}" | jq ".expected_msatoshi")
|
||||||
trace "[ln_pay] expected_msatoshi=${expected_msatoshi}"
|
trace "[ln_pay] expected_msatoshi=${expected_msatoshi}"
|
||||||
local expected_description=$(echo "${request}" | jq ".expected_description")
|
local expected_description=$(echo "${request}" | jq ".expected_description")
|
||||||
trace "[ln_pay] expected_description=${expected_description}"
|
trace "[ln_pay] expected_description=${expected_description}"
|
||||||
|
|
||||||
result=$(./lightning-cli decodepay ${bolt11})
|
result=$(./lightning-cli decodepay ${bolt11})
|
||||||
|
|
||||||
local invoice_msatoshi=$(echo "${result}" | jq ".msatoshi")
|
local invoice_msatoshi=$(echo "${result}" | jq ".msatoshi")
|
||||||
trace "[ln_pay] invoice_msatoshi=${invoice_msatoshi}"
|
trace "[ln_pay] invoice_msatoshi=${invoice_msatoshi}"
|
||||||
local invoice_description=$(echo "${result}" | jq ".description")
|
local invoice_description=$(echo "${result}" | jq ".description")
|
||||||
trace "[ln_pay] invoice_description=${invoice_description}"
|
trace "[ln_pay] invoice_description=${invoice_description}"
|
||||||
|
|
||||||
if [ "${expected_msatoshi}" != "${invoice_msatoshi}" ]; then
|
if [ "${expected_msatoshi}" != "${invoice_msatoshi}" ]; then
|
||||||
result="{\"result\":\"error\",\"expected_msatoshi\":${expected_msatoshi},\"invoice_msatoshi\":${invoice_msatoshi}}"
|
result="{\"result\":\"error\",\"expected_msatoshi\":${expected_msatoshi},\"invoice_msatoshi\":${invoice_msatoshi}}"
|
||||||
returncode=1
|
returncode=1
|
||||||
elif [ "${expected_description}" != "${invoice_description}" ]; then
|
elif [ "${expected_description}" != "${invoice_description}" ]; then
|
||||||
result="{\"result\":\"error\",\"expected_description\":${expected_description},\"invoice_description\":${invoice_description}}"
|
result="{\"result\":\"error\",\"expected_description\":${expected_description},\"invoice_description\":${invoice_description}}"
|
||||||
returncode=1
|
returncode=1
|
||||||
else
|
else
|
||||||
result=$(./lightning-cli pay ${bolt11})
|
result=$(./lightning-cli pay ${bolt11})
|
||||||
returncode=$?
|
returncode=$?
|
||||||
trace_rc ${returncode}
|
trace_rc ${returncode}
|
||||||
fi
|
fi
|
||||||
trace "[ln_pay] result=${result}"
|
trace "[ln_pay] result=${result}"
|
||||||
|
|
||||||
echo "${result}"
|
echo "${result}"
|
||||||
|
|
||||||
return ${returncode}
|
return ${returncode}
|
||||||
}
|
}
|
||||||
|
|
||||||
ln_newaddr()
|
ln_newaddr()
|
||||||
{
|
{
|
||||||
trace "Entering ln_newaddr()..."
|
trace "Entering ln_newaddr()..."
|
||||||
|
|
||||||
local result
|
local result
|
||||||
|
|
||||||
call_lightningd newaddr
|
call_lightningd newaddr
|
||||||
result=$(./lightning-cli newaddr)
|
result=$(./lightning-cli newaddr)
|
||||||
returncode=$?
|
returncode=$?
|
||||||
trace_rc ${returncode}
|
trace_rc ${returncode}
|
||||||
trace "[ln_newaddr] result=${result}"
|
trace "[ln_newaddr] result=${result}"
|
||||||
|
|
||||||
echo "${result}"
|
echo "${result}"
|
||||||
|
|
||||||
return ${returncode}
|
return ${returncode}
|
||||||
}
|
}
|
||||||
|
|
||||||
case "${0}" in *call_lightningd.sh) call_lightningd $@;; esac
|
case "${0}" in *call_lightningd.sh) call_lightningd $@;; esac
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ do_callbacks()
|
|||||||
|
|
||||||
local returncode
|
local returncode
|
||||||
local address
|
local address
|
||||||
|
local url
|
||||||
local IFS=$'\n'
|
local IFS=$'\n'
|
||||||
for row in ${callbacks}
|
for row in ${callbacks}
|
||||||
do
|
do
|
||||||
@@ -42,6 +43,27 @@ do_callbacks()
|
|||||||
trace_rc $?
|
trace_rc $?
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
|
callbacks=$(sql 'SELECT id, callback_url FROM ln_invoice WHERE NOT calledback AND callback_failed')
|
||||||
|
trace "[do_callbacks] ln_callbacks=${callbacks}"
|
||||||
|
|
||||||
|
for row in ${callbacks}
|
||||||
|
do
|
||||||
|
url=$(echo "${row}" | cut -d '|' -f2)
|
||||||
|
trace "[do_callbacks LN] url=${url}"
|
||||||
|
|
||||||
|
trace "[do_callbacks LN] curl -H \"X-Forwarded-Proto: https\" ${url}"
|
||||||
|
curl -H "X-Forwarded-Proto: https" ${url}
|
||||||
|
returncode=$?
|
||||||
|
if [ "${returncode}" -eq 0 ]; then
|
||||||
|
id=$(echo "${row}" | cut -d '|' -f1)
|
||||||
|
sql "UPDATE ln_invoice SET calledback=1,callback_failed=0 WHERE id=\"${id}\""
|
||||||
|
trace_rc $?
|
||||||
|
else
|
||||||
|
trace "[do_callbacks LN] callback failed: ${callback_url}"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
) 200>./.callbacks.lock
|
) 200>./.callbacks.lock
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -260,7 +260,7 @@ main()
|
|||||||
;;
|
;;
|
||||||
ln_create_invoice)
|
ln_create_invoice)
|
||||||
# POST http://192.168.111.152:8080/ln_create_invoice
|
# POST http://192.168.111.152:8080/ln_create_invoice
|
||||||
# BODY {"msatoshi":"10000","label":"koNCcrSvhX3dmyFhW","description":"Bylls order #10649","expiry":"900"}
|
# BODY {"msatoshi":"10000","label":"koNCcrSvhX3dmyFhW","description":"Bylls order #10649","expiry":"900","callback_url":"http://192.168.122.159"}
|
||||||
|
|
||||||
response=$(ln_create_invoice "${line}")
|
response=$(ln_create_invoice "${line}")
|
||||||
response_to_client "${response}" ${?}
|
response_to_client "${response}" ${?}
|
||||||
|
|||||||
@@ -45,4 +45,6 @@ chmod 0600 $DB_FILE
|
|||||||
createCurlConfig ${WATCHER_BTC_NODE_RPC_CFG} ${WATCHER_BTC_NODE_RPC_USER}
|
createCurlConfig ${WATCHER_BTC_NODE_RPC_CFG} ${WATCHER_BTC_NODE_RPC_USER}
|
||||||
createCurlConfig ${SPENDER_BTC_NODE_RPC_CFG} ${SPENDER_BTC_NODE_RPC_USER}
|
createCurlConfig ${SPENDER_BTC_NODE_RPC_CFG} ${SPENDER_BTC_NODE_RPC_USER}
|
||||||
|
|
||||||
|
./waitanyinvoice.sh &
|
||||||
|
|
||||||
nc -vlkp${PROXY_LISTENING_PORT} -e ./requesthandler.sh
|
nc -vlkp${PROXY_LISTENING_PORT} -e ./requesthandler.sh
|
||||||
|
|||||||
86
proxy_docker/app/script/waitanyinvoice.sh
Normal file
86
proxy_docker/app/script/waitanyinvoice.sh
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
. ./trace.sh
|
||||||
|
. ./sql.sh
|
||||||
|
|
||||||
|
ln_waitanyinvoice() {
|
||||||
|
trace "Entering ln_waitanyinvoice()..."
|
||||||
|
|
||||||
|
local lastpay_index=${1}
|
||||||
|
trace "[ln_waitanyinvoice] lastpay_index=${lastpay_index}"
|
||||||
|
local returncode
|
||||||
|
local result
|
||||||
|
local bolt11
|
||||||
|
local pay_index
|
||||||
|
local row
|
||||||
|
local id
|
||||||
|
local callback_url
|
||||||
|
|
||||||
|
#{
|
||||||
|
# "label": "Duvapk2OWvlmL3kf5GyDF",
|
||||||
|
# "bolt11": "lnbc1546230n1pwzanfspp5t5jr3rsjkh37986nzkta8kk0yyzam833l5e4an5nu6cyhjcjluwqdq9u2d2zxqr3jscqp2rzjqt04ll5ft3mcuy8hws4xcku2pnhma9r9mavtjtadawyrw5kgzp7g7zr745qq3mcqqyqqqqlgqqqqqzsqpclrjg6vtg4cmqj46przdgwp6rk0xmzfa7ga3wnm4h4evzxy3z32aqw77av65cz2mgcf02dak3vl25epq90dw289zz9x87dyjy6nqvchsq6p8nmj",
|
||||||
|
# "payment_hash": "5d24388e12b5e3e29f531597d3dacf2105dd9e31fd335ece93e6b04bcb12ff1c",
|
||||||
|
# "msatoshi": 154623000,
|
||||||
|
# "status": "paid",
|
||||||
|
# "pay_index": 12,
|
||||||
|
# "msatoshi_received": 154623000,
|
||||||
|
# "paid_at": 1546571113,
|
||||||
|
# "description": "...",
|
||||||
|
# "expires_at": 1546589056
|
||||||
|
#},
|
||||||
|
|
||||||
|
result=$(./lightning-cli waitanyinvoice ${lastpay_index})
|
||||||
|
returncode=$?
|
||||||
|
trace_rc ${returncode}
|
||||||
|
trace "[ln_waitanyinvoice] result=${result}"
|
||||||
|
|
||||||
|
bolt11=$(echo ${result} | jq ".bolt11" | tr -d '"')
|
||||||
|
pay_index=$(echo ${result} | jq ".pay_index" | tr -d '"')
|
||||||
|
|
||||||
|
row=$(sql "SELECT id, callback_url FROM ln_invoice WHERE NOT calledback AND bolt11=\"${bolt11}\"")
|
||||||
|
|
||||||
|
id=$(echo ${row} | cut -d '|' -f1)
|
||||||
|
callback_url=$(echo ${row} | cut -d '|' -f2)
|
||||||
|
if [ -z "${callback_url}" ]; then
|
||||||
|
# No callback url provided for that invoice
|
||||||
|
sql "UPDATE ln_invoice SET calledback=1 WHERE id=\"${id}\""
|
||||||
|
trace_rc $?
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
ln_payment_callback ${callback_url}
|
||||||
|
returncode=$?
|
||||||
|
trace_rc ${returncode}
|
||||||
|
if [ "${returncode}" -eq 0 ]; then
|
||||||
|
sql "UPDATE ln_invoice SET calledback=1 WHERE id=\"${id}\""
|
||||||
|
trace_rc $?
|
||||||
|
else
|
||||||
|
trace "[ln_waitanyinvoice] callback failed: ${callback_url}"
|
||||||
|
sql "UPDATE ln_invoice SET callback_failed=1 WHERE id=\"${id}\""
|
||||||
|
trace_rc $?
|
||||||
|
fi
|
||||||
|
|
||||||
|
sql "UPDATE cyphernode_props SET value="${pay_index}" WHERE property=\"pay_index\""
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ln_payment_callback() {
|
||||||
|
trace "Entering ln_payment_callback()..."
|
||||||
|
|
||||||
|
local url=${1}
|
||||||
|
|
||||||
|
trace "[ln_payment_callback] curl ${url}"
|
||||||
|
curl -H "X-Forwarded-Proto: https" ${url}
|
||||||
|
local returncode=$?
|
||||||
|
trace_rc ${returncode}
|
||||||
|
|
||||||
|
return ${returncode}
|
||||||
|
}
|
||||||
|
|
||||||
|
while :
|
||||||
|
do
|
||||||
|
pay_index=$(sql "SELECT value FROM cyphernode_props WHERE property='pay_index'")
|
||||||
|
trace "[waitanyinvoice] pay_index=${pay_index}"
|
||||||
|
ln_waitanyinvoice ${pay_index}
|
||||||
|
sleep 1
|
||||||
|
done
|
||||||
Reference in New Issue
Block a user