Skip to content

Commit ae4bb33

Browse files
committed
Adding BtcPayServer related files and resources
1 parent d72a3aa commit ae4bb33

File tree

9 files changed

+596
-0
lines changed

9 files changed

+596
-0
lines changed

.circleci/config.yml

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
version: 2
2+
jobs:
3+
# publish jobs require $DOCKERHUB_REPO, $DOCKERHUB_USER, $DOCKERHUB_PASS defined
4+
amd64:
5+
machine:
6+
enabled: true
7+
steps:
8+
- checkout
9+
- run:
10+
command: |
11+
LATEST_TAG=${CIRCLE_TAG:8} #trim "basedon-" from tag
12+
#
13+
sudo docker build --pull -t $DOCKERHUB_REPO:$LATEST_TAG-amd64 -f linuxamd64.Dockerfile .
14+
sudo docker login --username=$DOCKERHUB_USER --password=$DOCKERHUB_PASS
15+
sudo docker push $DOCKERHUB_REPO:$LATEST_TAG-amd64
16+
17+
arm32:
18+
machine:
19+
enabled: true
20+
steps:
21+
- checkout
22+
- run:
23+
command: |
24+
LATEST_TAG=${CIRCLE_TAG:8} #trim "basedon-" from tag
25+
#
26+
# Make sure the builder is copy the arm emulator
27+
sudo docker run --rm --privileged multiarch/qemu-user-static:register --reset
28+
sudo apt update
29+
sudo apt install -y qemu qemu-user-static qemu-user binfmt-support
30+
31+
sudo cp /usr/bin/qemu-arm-static "qemu-arm-static"
32+
sed -i -e 's/#EnableQEMU //g' "linuxarm32v7.Dockerfile"
33+
sudo docker build --pull -t $DOCKERHUB_REPO:$LATEST_TAG-arm32v7 -f linuxarm32v7.Dockerfile .
34+
sudo docker login --username=$DOCKERHUB_USER --password=$DOCKERHUB_PASS
35+
sudo docker push $DOCKERHUB_REPO:$LATEST_TAG-arm32v7
36+
37+
arm64:
38+
machine:
39+
enabled: true
40+
steps:
41+
- checkout
42+
- run:
43+
command: |
44+
LATEST_TAG=${CIRCLE_TAG:8} #trim "basedon-" from tag
45+
#
46+
# Make sure the builder is copy the arm emulator
47+
sudo docker run --rm --privileged multiarch/qemu-user-static:register --reset
48+
sudo apt update
49+
sudo apt install -y qemu qemu-user-static qemu-user binfmt-support
50+
51+
sudo cp /usr/bin/qemu-aarch64-static "qemu-aarch64-static"
52+
sed -i -e 's/#EnableQEMU //g' "linuxarm64v8.Dockerfile"
53+
sudo docker build --pull -t $DOCKERHUB_REPO:$LATEST_TAG-arm64v8 -f linuxarm64v8.Dockerfile .
54+
sudo docker login --username=$DOCKERHUB_USER --password=$DOCKERHUB_PASS
55+
sudo docker push $DOCKERHUB_REPO:$LATEST_TAG-arm64v8
56+
57+
multiarch:
58+
machine:
59+
enabled: true
60+
image: default
61+
steps:
62+
- run:
63+
command: |
64+
#
65+
sudo docker login --username=$DOCKERHUB_USER --password=$DOCKERHUB_PASS
66+
#
67+
LATEST_TAG=${CIRCLE_TAG:8} #trim "basedon-" from tag
68+
sudo docker manifest create --amend $DOCKERHUB_REPO:$LATEST_TAG $DOCKERHUB_REPO:$LATEST_TAG-amd64 $DOCKERHUB_REPO:$LATEST_TAG-arm32v7 $DOCKERHUB_REPO:$LATEST_TAG-arm64v8
69+
sudo docker manifest annotate $DOCKERHUB_REPO:$LATEST_TAG $DOCKERHUB_REPO:$LATEST_TAG-amd64 --os linux --arch amd64
70+
sudo docker manifest annotate $DOCKERHUB_REPO:$LATEST_TAG $DOCKERHUB_REPO:$LATEST_TAG-arm32v7 --os linux --arch arm --variant v7
71+
sudo docker manifest annotate $DOCKERHUB_REPO:$LATEST_TAG $DOCKERHUB_REPO:$LATEST_TAG-arm64v8 --os linux --arch arm64 --variant v8
72+
sudo docker manifest push $DOCKERHUB_REPO:$LATEST_TAG -p
73+
74+
workflows:
75+
version: 2
76+
publish:
77+
jobs:
78+
- amd64:
79+
filters:
80+
# ignore any commit on any branch by default
81+
branches:
82+
ignore: /.*/
83+
# only act on version tags
84+
tags:
85+
only: /basedon-.+/
86+
- arm32:
87+
filters:
88+
branches:
89+
ignore: /.*/
90+
tags:
91+
only: /basedon-.+/
92+
- arm64:
93+
filters:
94+
branches:
95+
ignore: /.*/
96+
tags:
97+
only: /basedon-.+/
98+
- multiarch:
99+
requires:
100+
- amd64
101+
- arm32
102+
- arm64
103+
filters:
104+
branches:
105+
ignore: /.*/
106+
tags:
107+
only: /basedon-.+/

.dockerignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Dockerfile
2+
linuxamd64.Dockerfile
3+
linuxarm32v7.Dockerfile
4+
.circleci/

.gitattributes

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Declare files that will always have CRLF line endings on checkout.
2+
*.sh text eol=lf
3+
*.go text eol=lf
4+
Makefile text eol=lf

Makefile

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ ANDROID_BUILD := $(ANDROID_BUILD_DIR)/Lndmobile.aar
2323

2424
COMMIT := $(shell git describe --tags --dirty)
2525

26+
COMMIT := $(subst -dirty,-fresh-btcpay,$(COMMIT))
27+
LDFLAGS := -ldflags "-X $(PKG)/build.Commit=$(COMMIT)"
28+
2629
# Determine the minor version of the active Go installation.
2730
ACTIVE_GO_VERSION := $(shell go version | sed -nre 's/^[^0-9]*(([0-9]+\.)*[0-9]+).*/\1/p')
2831
ACTIVE_GO_VERSION_MINOR := $(shell echo $(ACTIVE_GO_VERSION) | cut -d. -f2)
@@ -32,6 +35,11 @@ ifeq ($(shell expr $(ACTIVE_GO_VERSION_MINOR) \>= 21), 1)
3235
LOOPVARFIX := GOEXPERIMENT=loopvar
3336
endif
3437

38+
LOOPVARFIX :=
39+
ifeq ($(shell expr $(GO_VERSION_MINOR) \>= 21), 1)
40+
LOOPVARFIX := GOEXPERIMENT=loopvar
41+
endif
42+
3543
# GO_VERSION is the Go version used for the release build, docker files, and
3644
# GitHub Actions. This is the reference version for the project. All other Go
3745
# versions are checked against this version.

docker-entrypoint.sh

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
#!/bin/bash
2+
set -e
3+
4+
if [[ "$1" == "lnd" || "$1" == "lncli" ]]; then
5+
mkdir -p "$LND_DATA"
6+
7+
# removing noseedbackup=1 flag, adding it below if needed for legacy
8+
LND_EXTRA_ARGS=${LND_EXTRA_ARGS/noseedbackup=1/}
9+
10+
cat <<-EOF > "$LND_DATA/lnd.conf"
11+
${LND_EXTRA_ARGS}
12+
listen=0.0.0.0:${LND_PORT}
13+
EOF
14+
15+
if [[ "${LND_EXTERNALIP}" ]]; then
16+
echo "externalip=$LND_EXTERNALIP:${LND_PORT}" >> "$LND_DATA/lnd.conf"
17+
fi
18+
19+
if [[ "${LND_ALIAS}" ]]; then
20+
# This allow to strip this parameter if LND_ALIAS is empty or null, and truncate it
21+
LND_ALIAS="$(echo "$LND_ALIAS" | cut -c -32)"
22+
echo "alias=$LND_ALIAS" >> "$LND_DATA/lnd.conf"
23+
echo "alias=$LND_ALIAS added to $LND_DATA/lnd.conf"
24+
fi
25+
26+
if [[ $LND_CHAIN && $LND_ENVIRONMENT ]]; then
27+
echo "LND_CHAIN=$LND_CHAIN"
28+
echo "LND_ENVIRONMENT=$LND_ENVIRONMENT"
29+
30+
NETWORK=""
31+
32+
shopt -s nocasematch
33+
if [[ $LND_CHAIN == "btc" ]]; then
34+
NETWORK="bitcoin"
35+
elif [[ $LND_CHAIN == "ltc" ]]; then
36+
NETWORK="litecoin"
37+
else
38+
echo "Unknown value for LND_CHAIN, expected btc or ltc"
39+
fi
40+
41+
ENV=""
42+
# Make sure we use correct casing for LND_Environment
43+
if [[ $LND_ENVIRONMENT == "mainnet" ]]; then
44+
ENV="mainnet"
45+
elif [[ $LND_ENVIRONMENT == "testnet" ]]; then
46+
ENV="testnet"
47+
elif [[ $LND_ENVIRONMENT == "signet" ]]; then
48+
ENV="signet"
49+
elif [[ $LND_ENVIRONMENT == "regtest" ]]; then
50+
ENV="regtest"
51+
else
52+
echo "Unknown value for LND_ENVIRONMENT, expected mainnet, testnet, signet or regtest"
53+
fi
54+
shopt -u nocasematch
55+
56+
if [[ $ENV && $NETWORK ]]; then
57+
echo "
58+
$NETWORK.active=1
59+
$NETWORK.$ENV=1
60+
" >> "$LND_DATA/lnd.conf"
61+
echo "Added $NETWORK.active and $NETWORK.$ENV to config file $LND_DATA/lnd.conf"
62+
else
63+
echo "LND_CHAIN or LND_ENVIRONMENT is not set correctly"
64+
fi
65+
fi
66+
67+
if [[ "${LND_READY_FILE}" ]]; then
68+
echo "Waiting $LND_READY_FILE to be created..."
69+
while [ ! -f "$LND_READY_FILE" ]; do sleep 1; done
70+
echo "The chain is fully synched"
71+
fi
72+
73+
if [[ "${LND_HIDDENSERVICE_HOSTNAME_FILE}" ]]; then
74+
echo "Waiting $LND_HIDDENSERVICE_HOSTNAME_FILE to be created by tor..."
75+
while [ ! -f "$LND_HIDDENSERVICE_HOSTNAME_FILE" ]; do sleep 1; done
76+
HIDDENSERVICE_ONION="$(head -n 1 "$LND_HIDDENSERVICE_HOSTNAME_FILE"):${LND_PORT}"
77+
echo "externalip=$HIDDENSERVICE_ONION" >> "$LND_DATA/lnd.conf"
78+
echo "externalip=$HIDDENSERVICE_ONION added to $LND_DATA/lnd.conf"
79+
fi
80+
81+
# if it is legacy installation, then trigger warning and add noseedbackup=1 to config if needed
82+
WALLET_FILE="$LND_DATA/data/chain/$NETWORK/$ENV/wallet.db"
83+
LNDUNLOCK_FILE=${WALLET_FILE/wallet.db/walletunlock.json}
84+
if [ -f "$WALLET_FILE" -a ! -f "$LNDUNLOCK_FILE" ]; then
85+
echo "[lnd_unlock_entrypoint] WARNING: UNLOCK FILE DOESN'T EXIST! MIGRATE LEGACY INSTALLATION TO NEW VERSION ASAP"
86+
echo "noseedbackup=1" >> "$LND_DATA/lnd.conf"
87+
fi
88+
89+
# hit up the auto initializer and unlocker on separate process to do it's work
90+
./docker-initunlocklnd.sh $NETWORK $ENV &
91+
92+
ln -sfn "$LND_DATA" /root/.lnd
93+
ln -sfn "$LND_BITCOIND" /root/.bitcoin
94+
ln -sfn "$LND_LITECOIND" /root/.litecoin
95+
ln -sfn "$LND_BTCD" /root/.btcd
96+
97+
exec "$@"
98+
else
99+
exec "$@"
100+
fi

docker-initunlocklnd.sh

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
#!/bin/bash
2+
set -e
3+
4+
echo "[initunlocklnd] Waiting 2 seconds for lnd..."
5+
sleep 2
6+
7+
# ensure that lnd is up and running before proceeding
8+
while
9+
CA_CERT="$LND_DATA/tls.cert"
10+
LND_WALLET_DIR="$LND_DATA/data/chain/$1/$2/"
11+
MACAROON_FILE="$LND_DATA/admin.macaroon"
12+
MACAROON_HEADER="r0ckstar:dev"
13+
if [ -f "$MACAROON_FILE" ]; then
14+
MACAROON_HEADER="Grpc-Metadata-macaroon:$(xxd -p -c 10000 "$MACAROON_FILE" | tr -d ' ')"
15+
fi
16+
17+
STATUS_CODE=$(curl -s --cacert "$CA_CERT" -H $MACAROON_HEADER -o /dev/null -w "%{http_code}" $LND_REST_LISTEN_HOST/v1/getinfo)
18+
# if lnd is running it'll either return 200 if unlocked (noseedbackup=1) or 404 if it needs initialization/unlock
19+
if [ "$STATUS_CODE" == "200" ] || [ "$STATUS_CODE" == "404" ] ; then
20+
break
21+
# or 500 from version 0.13.1 onwards because it breaks with `wallet not created, create one to enable full RPC access` error
22+
elif [ "$STATUS_CODE" == "500" ] ; then
23+
STATUS_CODE=$(curl -s --cacert "$CA_CERT" -H $MACAROON_HEADER $LND_REST_LISTEN_HOST/v1/state)
24+
if [ "$STATUS_CODE" == "{\"state\":\"NON_EXISTING\"}" ] || [ "$STATUS_CODE" == "{\"state\":\"LOCKED\"}" ] ; then
25+
break # wallet ready to be either created or unlocked
26+
fi
27+
# for {\"state\":\"UNLOCKED\"}" we will depend on that previous condition with STATUS_CODE 200 or 404
28+
# because even though wallet is unlocked, /v1/getinfo will still keep returning 500 until it's ready
29+
30+
echo "[initunlocklnd] Still waiting on LND, got response for wallet status: $STATUS_CODE ... waiting another 2 seconds..."
31+
sleep 2
32+
else
33+
echo "[initunlocklnd] LND still didn't start, got $STATUS_CODE status code back... waiting another 2 seconds..."
34+
sleep 2
35+
fi
36+
do true; done
37+
38+
# read variables after we ensured that lnd is up
39+
CA_CERT="$LND_DATA/tls.cert"
40+
LND_WALLET_DIR="$LND_DATA/data/chain/$1/$2/"
41+
MACAROON_FILE="$LND_DATA/admin.macaroon"
42+
MACAROON_HEADER="r0ckstar:dev"
43+
if [ -f "$MACAROON_FILE" ]; then
44+
MACAROON_HEADER="Grpc-Metadata-macaroon:$(xxd -p -c 10000 "$MACAROON_FILE" | tr -d ' ')"
45+
fi
46+
47+
WALLET_FILE="$LND_WALLET_DIR/wallet.db"
48+
LNDUNLOCK_FILE=${WALLET_FILE/wallet.db/walletunlock.json}
49+
if [ -f "$WALLET_FILE" ]; then
50+
if [ ! -f "$LNDUNLOCK_FILE" ]; then
51+
echo "[initunlocklnd] WARNING: UNLOCK FILE DOESN'T EXIST! MIGRATE LEGACY INSTALLATION TO NEW VERSION ASAP"
52+
else
53+
echo "[initunlocklnd] Wallet and Unlock files are present... parsing wallet password and unlocking lnd"
54+
55+
# parse wallet password from unlock file
56+
WALLETPASS=$(jq -c -r '.wallet_password' $LNDUNLOCK_FILE)
57+
# Nicolas deleted default password in some wallet unlock files, so we initializing default if password is empty
58+
[ "$WALLETPASS" == "" ] && WALLETPASS="hellorockstar"
59+
# Corrected password (removing newlines before encoding).
60+
# previous versions will have a default wallet password including a line feed at the end "hellorockstar\n"
61+
# line feed hex code 0x0A. So we first try the password without the line feed if it fails we try it with
62+
# the older version.
63+
WALLETPASS_BASE64=$(echo $WALLETPASS | tr -d '\n\r' | base64)
64+
65+
response=$(curl -s --cacert "$CA_CERT" -X POST -H "$MACAROON_HEADER" \
66+
-d '{ "wallet_password":"'$WALLETPASS_BASE64'" }' $LND_REST_LISTEN_HOST/v1/unlockwallet)
67+
68+
# Check for failure (e.g., incorrect password)
69+
if [[ "$response" == *"invalid"* ]]; then
70+
# If it fails, try the original password with linefeed
71+
WALLETPASS_BASE64_CURRENT=$(echo $WALLETPASS | base64)
72+
73+
# Now we change the password so that the line feed is removed.
74+
# The correct password is already written to the unlock file so we don't need
75+
# to change that. Moreover the changepassword call will change + unlock the wallet
76+
# there is no need to call unlockwallet after this call.
77+
change_password_response=$(curl -s --cacert "$CA_CERT" -X POST -H "$MACAROON_HEADER" \
78+
-d '{ "current_password":"'$WALLETPASS_BASE64_CURRENT'", "new_password":"'$WALLETPASS_BASE64'" }' \
79+
$LND_REST_LISTEN_HOST/v1/changepassword)
80+
81+
# make sure the log end with a newline.
82+
echo $change_password_response
83+
84+
echo -n "[initunlocklnd] Changed wallet password removing the \"line feed\" character at the end. "
85+
echo "The password can be found in $LNDUNLOCK_FILE"
86+
else
87+
echo "[initunlocklnd] Wallet unlocking failed, lnd returned: $response"
88+
exit 1
89+
fi
90+
fi
91+
else
92+
echo "[initunlocklnd] Wallet file doesn't exist. Initializing LND instance with new autogenerated password and seed"
93+
94+
# generate seed mnemonic
95+
GENSEED_RESP=$(curl -s --cacert "$CA_CERT" -X GET -H $MACAROON_HEADER $LND_REST_LISTEN_HOST/v1/genseed)
96+
CIPHER_ARRAY_EXTRACTED=$(echo $GENSEED_RESP | jq -c -r '.cipher_seed_mnemonic')
97+
98+
# using static default password per feedback, randomly generated password would still be stored in cleartext
99+
WALLETPASS="hellorockstar"
100+
101+
# save all the the data to unlock file we'll use for future unlocks
102+
RESULTJSON='{"wallet_password":"'$WALLETPASS'", "cipher_seed_mnemonic":'$CIPHER_ARRAY_EXTRACTED'}'
103+
mkdir -p $LND_WALLET_DIR
104+
echo $RESULTJSON > $LNDUNLOCK_FILE
105+
106+
# previous versions will have a default wallet password including a line feed at the end "hellorockstar\n"
107+
# line feed hex code 0x0A.
108+
WALLETPASS_BASE64=$(echo $WALLETPASS | tr -d '\n\r' | base64)
109+
INITWALLET_REQ='{"wallet_password":"'$WALLETPASS_BASE64'", "cipher_seed_mnemonic":'$CIPHER_ARRAY_EXTRACTED'}'
110+
111+
# execute initwallet call
112+
curl -s --cacert "$CA_CERT" -X POST -H "$MACAROON_HEADER" -d "$INITWALLET_REQ" $LND_REST_LISTEN_HOST/v1/initwallet
113+
fi
114+
115+
# LND unlocked, now run Loop
116+
117+
if [ ! -z "$LND_HOST_FOR_LOOP" ]; then
118+
echo "[initunlocklnd] Preparing to start Loop"
119+
120+
if [ $LND_ENVIRONMENT == "regtest" ] || [ $LND_ENVIRONMENT == "signet" ]; then
121+
echo "[initunlocklnd] Loop can't be started for regtest and signet"
122+
elif [ -f "$MACAROON_FILE" ]; then
123+
sleep 10
124+
125+
echo "[initunlocklnd] Starting Loop"
126+
./bin/loopd --network=$2 --lnd.macaroonpath=$MACAROON_FILE --lnd.host=$LND_HOST_FOR_LOOP --restlisten=0.0.0.0:8081 &
127+
else
128+
echo "[initunlocklnd] Loop can't be started without MACAROON"
129+
fi
130+
fi

0 commit comments

Comments
 (0)