First pass of LN payment callbacks

This commit is contained in:
kexkey
2019-01-08 16:01:49 -05:00
committed by kexkey
parent ef504bb27a
commit b719992a0c
10 changed files with 228 additions and 65 deletions

View File

@@ -30,7 +30,7 @@ COPY app/data/* ./
COPY app/script/* ./
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 . \
&& mkdir db

View File

@@ -26,7 +26,7 @@ COPY app/data/* ./
COPY app/script/* ./
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 . \
&& mkdir db

View File

@@ -87,3 +87,16 @@ CREATE TABLE cyphernode_props (
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 ("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);

View 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

View 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);

View File

@@ -17,12 +17,27 @@ ln_create_invoice()
trace "[ln_create_invoice] description=${description}"
local expiry=$(echo "${request}" | jq ".expiry" | tr -d '"')
trace "[ln_create_invoice] expiry=${expiry}"
local callback_url=$(echo "${request}" | jq ".callback_url" | tr -d '"')
trace "[ln_create_invoice] callback_url=${callback_url}"
#/proxy $ ./lightning-cli invoice 10000 "t1" "t1d" 60
#{
# "payment_hash": "a74e6cccb06e26bcddc32c43674f9c3cf6b018a4cb9e9ff7f835cc59b091ae06",
# "expires_at": 1546648644,
# "bolt11": "lnbc100n1pwzllqgpp55a8xen9sdcntehwr93pkwnuu8nmtqx9yew0flalcxhx9nvy34crqdq9wsckgxqzpucqp2rzjqt04ll5ft3mcuy8hws4xcku2pnhma9r9mavtjtadawyrw5kgzp7g7zr745qq3mcqqyqqqqlgqqqqqzsqpcr85k33shzaxscpj29fadmjmfej6y2p380x9w4kxydqpxq87l6lshy69fry9q2yrtu037nt44x77uhzkdyn8043n5yj8tqgluvmcl69cquaxr68"
#}
result=$(./lightning-cli invoice ${msatoshi} "${label}" "${description}" ${expiry})
returncode=$?
trace_rc ${returncode}
trace "[ln_create_invoice] result=${result}"
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}

View File

@@ -16,6 +16,7 @@ do_callbacks()
local returncode
local address
local url
local IFS=$'\n'
for row in ${callbacks}
do
@@ -42,6 +43,27 @@ do_callbacks()
trace_rc $?
fi
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
}

View File

@@ -260,7 +260,7 @@ main()
;;
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_to_client "${response}" ${?}

View File

@@ -45,4 +45,6 @@ chmod 0600 $DB_FILE
createCurlConfig ${WATCHER_BTC_NODE_RPC_CFG} ${WATCHER_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

View 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