diff --git a/docker-compose/flyover-ui/Dockerfile b/docker-compose/flyover-ui/Dockerfile new file mode 100644 index 00000000..31bce102 --- /dev/null +++ b/docker-compose/flyover-ui/Dockerfile @@ -0,0 +1,33 @@ +FROM node:18.20.3@sha256:70ae166dcb03837ebe1abbb78919a1a4bdc79cc970344d56f33b6c753f4b46cc AS builder + +WORKDIR /code/flyover-ui + +ARG VERSION="custom-lbc" +ARG LBC_ADDRESS + + +RUN --mount=type=secret,id=gh_token,required=true,uid=1000 gitrev="${VERSION}" && REPO_URL="https://$(cat /run/secrets/gh_token)@github.com/rsksmart/flyover-ui.git" &&\ + git init && \ + git remote add origin "$REPO_URL" && \ + git fetch --depth 1 origin tag "$gitrev" && \ + git checkout "$gitrev" + +RUN --mount=type=secret,id=gh_token,required=true,uid=1000 npm config set //npm.pkg.github.com/:_authToken $(cat /run/secrets/gh_token) +RUN npm ci + +RUN echo "REACT_APP_ENV=Regtest" > .env +RUN echo "REACT_APP_RPC_URL=http://localhost:4444" >> .env +RUN echo "REACT_APP_CUSTOM_LBC=$LBC_ADDRESS" >> .env + + +RUN npm run build + + +FROM nginx:1.27.1@sha256:135fbc7ed19c8f644ddf678e68292e678696908451dad7ee2fd4e0cf861f4b6f +COPY --from=builder /code/flyover-ui/build /usr/share/nginx/html + +EXPOSE 80 + +STOPSIGNAL SIGTERM + +CMD ["nginx", "-g", "daemon off;"] diff --git a/internal/adapters/entrypoints/rest/handlers/management.go b/internal/adapters/entrypoints/rest/handlers/management.go index 9e4cc2f5..14586bd0 100644 --- a/internal/adapters/entrypoints/rest/handlers/management.go +++ b/internal/adapters/entrypoints/rest/handlers/management.go @@ -27,16 +27,19 @@ const ( // @Route /management [get] func NewManagementInterfaceHandler(store sessions.Store, useCase *liquidity_provider.GetManagementUiDataUseCase) http.HandlerFunc { return func(w http.ResponseWriter, req *http.Request) { + const errorGeneratingTemplate = "Error generating template: %v" session, err := store.Get(req, cookies.ManagementSessionCookieName) loggedIn := err == nil && !session.IsNew result, err := useCase.Run(req.Context(), loggedIn) if err != nil { + log.Errorf(errorGeneratingTemplate, err) sendErrorTemplate(w) return } bytes, err := utils.GetRandomBytes(nonceBytes) if err != nil { + log.Errorf(errorGeneratingTemplate, err) sendErrorTemplate(w) return } diff --git a/sample-config.env b/sample-config.env old mode 100755 new mode 100644 index b309096b..123608f6 --- a/sample-config.env +++ b/sample-config.env @@ -47,8 +47,9 @@ PROVIDER_TYPE=both PEGOUT_DEPOSIT_CACHE_START_BLOCK=0 # Captcha env -CAPTCHA_SECRET_KEY= -CAPTCHA_SITE_KEY= +# Suggestion: use public test keys -> https://developers.google.com/recaptcha/docs/faq#id-like-to-run-automated-tests-with-recaptcha.-what-should-i-do +CAPTCHA_SECRET_KEY=some-key +CAPTCHA_SITE_KEY=some-key CAPTCHA_THRESHOLD=0.8 DISABLE_CAPTCHA=true CAPTCHA_URL="https://www.google.com/recaptcha/api/siteverify" @@ -67,4 +68,4 @@ AWS_REGION=us-east-1 # Used by local scripts LIQUIDITY_PROVIDER_RSK_ADDR=0x9D93929A9099be4355fC2389FbF253982F9dF47c -GITHUB_TOKEN= \ No newline at end of file +GITHUB_TOKEN= diff --git a/test/integration/integration-test.config.example.json b/test/integration/integration-test.config.example.json index 6e1a5391..736612af 100644 --- a/test/integration/integration-test.config.example.json +++ b/test/integration/integration-test.config.example.json @@ -8,11 +8,11 @@ "rpcEndpoint": "localhost:5555", "user": "test", "password": "test", - "password": "test-password" + "walletPassword": "test-password" }, "rsk": { "rpcUrl": "ws://localhost:4445/websocket", "lbcAddress": "", "userPrivateKey": "" } -} \ No newline at end of file +} diff --git a/test/integration/integration_suite_test.go b/test/integration/integration_suite_test.go index 6d7364f6..0ea6a7af 100644 --- a/test/integration/integration_suite_test.go +++ b/test/integration/integration_suite_test.go @@ -10,11 +10,9 @@ import ( "github.com/ethereum/go-ethereum/ethclient" "github.com/rsksmart/liquidity-provider-server/cmd/application/lps" "github.com/rsksmart/liquidity-provider-server/internal/adapters/dataproviders/rootstock/bindings" - "github.com/rsksmart/liquidity-provider-server/pkg" log "github.com/sirupsen/logrus" "github.com/stretchr/testify/suite" "io" - "net/http" "os" "testing" "time" @@ -55,7 +53,7 @@ func (s *IntegrationTestSuite) SetupSuite() { var configFile *os.File log.Debug("Setting up integration tests...") - if configFile, err = os.Open("test/integration/integration-test.config.json"); err != nil { + if configFile, err = os.Open("./integration-test.config.json"); err != nil { s.FailNow("Error reading configuration file", err) } defer func(configFile *os.File) { @@ -85,13 +83,6 @@ func (s *IntegrationTestSuite) SetupSuite() { time.Sleep(3 * time.Second) } - if s.config.Network == "regtest" { - log.Warn("Setting limits for regtest operations. This requires the management API enabled.") - if err = s.configureRegtestLimits(); err != nil { - s.FailNow("Error setting regtest limits", err) - } - } - log.Debug("Set up completed") } @@ -155,50 +146,6 @@ func (s *IntegrationTestSuite) setupRsk() error { return nil } -func (s *IntegrationTestSuite) configureRegtestLimits() error { - url := s.config.Lps.Url - result, err := execute[any](Execution{ - Method: http.MethodPost, - URL: url + "/pegin/configuration", - Body: pkg.PeginConfigurationRequest{ - Configuration: pkg.PeginConfigurationDTO{ - TimeForDeposit: 3600, - CallTime: 7200, - PenaltyFee: "1000000000000000", - CallFee: "10000000000000000", - MaxValue: "10000000000000000000", - MinValue: "600000000000000000", - }, - }, - }) - if err != nil { - return err - } else if result.StatusCode != 204 { - return fmt.Errorf("unexpected status code: %v", result.StatusCode) - } - result, err = execute[any](Execution{ - Method: http.MethodPost, - URL: url + "/pegout/configuration", - Body: pkg.PegoutConfigurationRequest{ - Configuration: pkg.PegoutConfigurationDTO{ - TimeForDeposit: 3600, - ExpireTime: 7200, - PenaltyFee: "1000000000000000", - CallFee: "10000000000000000", - MaxValue: "10000000000000000000", - MinValue: "600000000000000000", - ExpireBlocks: 500, - }, - }, - }) - if err != nil { - return err - } else if result.StatusCode != 204 { - return fmt.Errorf("unexpected status code: %v", result.StatusCode) - } - return nil -} - func (s *IntegrationTestSuite) AssertFields(expectedFields []string, object map[string]any) { for _, field := range expectedFields { _, exists := object[field] diff --git a/test/integration/pegin_overpay_test.go b/test/integration/pegin_overpay_test.go index 6033de56..b1adbd84 100644 --- a/test/integration/pegin_overpay_test.go +++ b/test/integration/pegin_overpay_test.go @@ -7,6 +7,7 @@ import ( "math/big" "os" "os/signal" + "strings" "syscall" ) @@ -51,7 +52,7 @@ func (s *IntegrationTestSuite) TestPegInOverPayFlow() { case balanceIncreaseEvent := <-balanceIncreaseChannel: balanceIncreaseSubscription.Unsubscribe() refundedAmount := new(entities.Wei).Add(value, new(entities.Wei).Add(callFee, gasFee)) - s.Require().Equal(quote.Quote.LPRSKAddr, balanceIncreaseEvent.Dest.String()) + s.Require().Equal(strings.ToLower(quote.Quote.LPRSKAddr), strings.ToLower(balanceIncreaseEvent.Dest.String())) s.Require().Equal(refundedAmount.AsBigInt().Int64(), balanceIncreaseEvent.Amount.Int64()) registered = true case err = <-balanceIncreaseSubscription.Err(): diff --git a/test/integration/pegout_test.go b/test/integration/pegout_test.go index c21c5f61..1b869369 100644 --- a/test/integration/pegout_test.go +++ b/test/integration/pegout_test.go @@ -148,7 +148,7 @@ func (s *IntegrationTestSuite) TestSuccessfulPegOutFlow() { txHash := waitForBtcTransactionToAddress(s, address) txParsedHash, _ := chainhash.NewHashFromStr(txHash) - tx, err := s.btc.GetTransaction(txParsedHash) + tx, err := s.btc.GetRawTransaction(txParsedHash) s.NoError(err) s.NotNil(tx) }) diff --git a/test/lp-swap/.gitignore b/test/lp-swap/.gitignore new file mode 100644 index 00000000..eb96848d --- /dev/null +++ b/test/lp-swap/.gitignore @@ -0,0 +1,5 @@ +*.env +*-key.json +config.json +cookie_jar.txt +gh_token.txt diff --git a/test/lp-swap/README.md b/test/lp-swap/README.md new file mode 100644 index 00000000..5422c4b8 --- /dev/null +++ b/test/lp-swap/README.md @@ -0,0 +1,29 @@ +# Liquidity Provider Swap environment +This is a simple environment for simulating a liquidity provider swap. +This is the process where one provider is added to the Liquidity Bridge Contract to coexist with the existing provider for some time. +After that time, the old provider is removed and the new provider is the only one providing liquidity. +This environment can be used to perform all the required validations over this process. + +## How to run +1. Complete the missing variables in [sample-config.env](../../sample-config.env) since this file will be used as a template for the LPs env files. +Most likely the changes that you will need to do are setting the captcha keys (you can use the test ones) and setting the GITHUB_TOKEN in case the +environment is using any internal version. +2. Create a `config.json` with the same structure as `config.example.json` in the lp-swap folder (the same one where this file is located). +3. Run the following command: +```bash +./setup.sh +``` +This script will set up the whole environment for you and will stop when both LPs are running. The user will be able to use both providers until he decides +to sunset one of them, at that point he just need to specify the ID in the console (the script will be waiting for that ID). After that, the script will +proceed to resign the LP and withdraw its collateral from the contract. + +### Miners +Most of the operations that the LP needs to perform require a miner to be running so the transactions can achieve certain number of confirmations. +There is one script for each network; [btc-miner.sh](btc-miner.sh) and [rsk-miner.sh](rsk-miner.sh). These scripts will start a miner for the specified local network. +They only require one argument which is the number of seconds between blocks. E.g.: +```bash +./btc-miner.sh 60 +``` + +## Clarifications +- This environment doesn't include the powpeg nodes so the LPs won't be refunded for the peins or pegouts done in it. diff --git a/test/lp-swap/btc-miner.sh b/test/lp-swap/btc-miner.sh new file mode 100755 index 00000000..3e56ea6e --- /dev/null +++ b/test/lp-swap/btc-miner.sh @@ -0,0 +1,33 @@ +#!/bin/bash + +if ! [[ "$1" =~ ^[0-9]+$ ]]; then + echo "Argument must be a number" + exit 1 +fi + +RPC_IP=127.0.0.1 +RPC_USER="test" +RPC_PASSWORD="test" +RPC_PORT=5555 + +WALLETS=$(bitcoin-cli -rpcuser=$RPC_USER -rpcpassword=$RPC_PASSWORD -rpcport=$RPC_PORT -rpcconnect=$RPC_IP listwallets) +if ! [[ $WALLETS == *"main"* ]]; then + bitcoin-cli -rpcuser=$RPC_USER -rpcpassword=$RPC_PASSWORD -rpcport=$RPC_PORT -rpcconnect=$RPC_IP \ + createwallet "main" false false "test-password" true false true + ADDRESS=$(bitcoin-cli -rpcuser=$RPC_USER -rpcpassword=$RPC_PASSWORD -rpcport=$RPC_PORT -rpcconnect=$RPC_IP \ + -rpcwallet=main getnewaddress) + bitcoin-cli -rpcuser=$RPC_USER -rpcpassword=$RPC_PASSWORD -rpcport=$RPC_PORT -rpcconnect=$RPC_IP \ + generatetoaddress 100 "$ADDRESS" +fi + +while true; do + bitcoin-cli -rpcuser=$RPC_USER -rpcpassword=$RPC_PASSWORD -rpcport=$RPC_PORT -rpcconnect=$RPC_IP \ + -rpcwallet=main walletpassphrase "test-password" "$1" + ADDRESS=$(bitcoin-cli -rpcuser=$RPC_USER -rpcpassword=$RPC_PASSWORD -rpcport=$RPC_PORT -rpcconnect=$RPC_IP \ + -rpcwallet=main getnewaddress) + bitcoin-cli -rpcuser=$RPC_USER -rpcpassword=$RPC_PASSWORD -rpcport=$RPC_PORT -rpcconnect=$RPC_IP \ + -rpcwallet=main -named sendtoaddress address="$ADDRESS" fee_rate=25 amount=0.00001 + bitcoin-cli -rpcuser=$RPC_USER -rpcpassword=$RPC_PASSWORD -rpcport=$RPC_PORT -rpcconnect=$RPC_IP \ + -rpcwallet=main -generate 1 + sleep "$1" +done diff --git a/test/lp-swap/config.example.json b/test/lp-swap/config.example.json new file mode 100644 index 00000000..fbfba353 --- /dev/null +++ b/test/lp-swap/config.example.json @@ -0,0 +1,11 @@ +{ + "ghToken": "", + "lp1": { + "key": {"address":"b4cbc80da6586615da4ac51416e0fac15d435750","crypto":{"cipher":"aes-128-ctr","ciphertext":"666596e67e2d952bb4278245f3bf8b6259d1c591939625fb3d03109d7d5e3f22","cipherparams":{"iv":"7fbc0ffe4103b311826344d370ef3912"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"d87b8fd0c391533502644dda48f9ff059e1151e0c64f37954af20f7e17c6fbfa"},"mac":"fecef2821c7fea325d1050b35fedd7e15b7051baa95ab8f7aaf48eee43ae8b7d"},"id":"bec11a9d-db99-44cb-924a-5c3b61dd0334","version":3}, + "password": "test" + }, + "lp2": { + "key": {"address":"f6af42d4f3487799fc48537775b3908a89ca7cb3","crypto":{"cipher":"aes-128-ctr","ciphertext":"c23a4ec21133141202012075497e6e82c2241fa06cdff4da07eef64d0c668d17","cipherparams":{"iv":"b7671d8e8811ab8de6d9511301d412d9"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"f2291e0af522984420d04ad4a1d073333b87fca41159c21cd2cea588888101fe"},"mac":"205006c4cbd477e60d2b3a45735136c43c114ad84972eeae2a40d56f4bd856eb"},"id":"1f97470e-e352-4dd1-bbcb-120aca9321d0","version":3}, + "password": "test" + } +} diff --git a/test/lp-swap/docker-compose.lps.yml b/test/lp-swap/docker-compose.lps.yml new file mode 100644 index 00000000..d86bb03a --- /dev/null +++ b/test/lp-swap/docker-compose.lps.yml @@ -0,0 +1,94 @@ +services: + lps: + build: + context: ../../ + dockerfile: docker-compose/lps/Dockerfile + image: lps:latest + depends_on: + - mongodb + volumes: + - ./:/mnt + environment: + - LPS_STAGE + - SERVER_PORT + - LOG_LEVEL + - LOG_FILE + - ENABLE_MANAGEMENT_API + - MONGODB_USER + - MONGODB_PASSWORD + - MONGODB_HOST + - MONGODB_PORT + - RSK_ENDPOINT + - CHAIN_ID + - LBC_ADDR + - RSK_BRIDGE_ADDR + - RSK_REQUIRED_BRIDGE_CONFIRMATIONS + - IRIS_ACTIVATION_HEIGHT + - ERP_KEYS + - ACCOUNT_NUM + - DAO_FEE_COLLECTOR_ADDRESS + - KEY_SECRET + - PASSWORD_SECRET + - RSK_CONFIRMATIONS + - BTC_NETWORK + - BTC_USERNAME + - BTC_PASSWORD + - BTC_ENDPOINT + - BTC_CONFIRMATIONS + - ALERT_SENDER_EMAIL + - ALERT_RECIPIENT_EMAIL + - PROVIDER_NAME + - BASE_URL + - PROVIDER_TYPE + - PEGIN_TIME_FOR_DEPOSIT + - PEGIN_CALL_TIME + - PEGIN_PENALTY_FEE + - PEGIN_FEE + - PEGIN_MIN_TRANSACTION_VALUE + - PEGIN_MAX_TRANSACTION_VALUE + - PEGOUT_TIME_FOR_DEPOSIT + - PEGOUT_CALL_TIME + - PEGOUT_PENALTY_FEE + - PEGOUT_FEE + - PEGOUT_MIN_TRANSACTION_VALUE + - PEGOUT_MAX_TRANSACTION_VALUE + - PEGOUT_EXPIRE_BLOCKS + - PEGOUT_DEPOSIT_CACHE_START_BLOCK + - CAPTCHA_SECRET_KEY + - CAPTCHA_SITE_KEY + - CAPTCHA_THRESHOLD + - DISABLE_CAPTCHA + - CAPTCHA_URL + - AWS_ACCESS_KEY_ID + - AWS_SECRET_ACCESS_KEY + - AWS_REGION + - AWS_LOCAL_ENDPOINT + - MANAGEMENT_AUTH_KEY + - MANAGEMENT_ENCRYPTION_KEY + - MANAGEMENT_TOKEN_AUTH_KEY + - MANAGEMENT_USE_HTTPS + - WALLET + - SECRET_SRC + - KEYSTORE_FILE + - KEYSTORE_PWD + ports: + - "8080-8081:8080" + networks: + - lp-swap-network + command: ["liquidity-provider-server"] + mongodb: + image: mongo:4 + restart: on-failure + environment: + - MONGO_INITDB_ROOT_USERNAME=flyover-user + - MONGO_INITDB_ROOT_PASSWORD=flyover-password + - MONGO_INITDB_DATABASE=flyover + ports: + - "27017-27018:27017" + expose: + - 27017 + networks: + - lp-swap-network +networks: + lp-swap-network: + driver: "bridge" diff --git a/test/lp-swap/docker-compose.yml b/test/lp-swap/docker-compose.yml new file mode 100644 index 00000000..3a8ef7f7 --- /dev/null +++ b/test/lp-swap/docker-compose.yml @@ -0,0 +1,113 @@ +services: + btc01: + build: + context: ../../docker-compose/bitcoind + image: bitcond:latest + container_name: btc01 + environment: + - BTC_USERNAME + - BTC_PASSWORD + ports: + - "5555:5555" + networks: + - lp-swap-network + command: + [ + "bitcoind", + "-rpcuser=test", + "-rpcpassword=test", + "-addresstype=legacy", + "-regtest", + "-printtoconsole", + "-server", + "-txindex", + "-deprecatedrpc=signrawtransaction", + "-deprecatedrpc=accounts", + "-rpcbind=0.0.0.0", + "-rpcallowip=0.0.0.0/0", + "-rpcport=5555", + ] + btc02: + build: + context: ../../docker-compose/bitcoind + image: bitcond:latest + container_name: btc02 + environment: + - BTC_USERNAME + - BTC_PASSWORD + ports: + - "5556:5555" + networks: + - lp-swap-network + command: + [ + "bitcoind", + "-rpcuser=test", + "-rpcpassword=test", + "-addresstype=legacy", + "-regtest", + "-printtoconsole", + "-server", + "-txindex", + "-deprecatedrpc=signrawtransaction", + "-deprecatedrpc=accounts", + "-rpcbind=0.0.0.0", + "-rpcallowip=0.0.0.0/0", + "-rpcport=5555", + ] + rskj: + build: + context: ../../docker-compose/rskj + image: rskj:latest + container_name: rskj01 + ports: + - "4444:4444" + networks: + - lp-swap-network + command: + [ + "java", + "-Drpc.providers.web.ws.bind_address=0.0.0.0", + "-Drpc.providers.web.http.bind_address=0.0.0.0", + "-Drpc.providers.web.cors=*", + "-Drpc.providers.web.ws.enabled=true", + "-Drpc.providers.web.http.hosts.0=localhost", + "-Drpc.providers.web.http.hosts.1=rskj", + "-cp", + "rskj-core.jar", + "-Drsk.conf.file=rsk.conf", + "co.rsk.Start", + "--regtest", + ] + lbc-deployer: + build: + context: ../../docker-compose/lbc-deployer + secrets: + - gh_token + args: + LBC_GIT_BRANCH: "${LBC_GIT_BRANCH:-QA-Test}" + image: lbc-deployer:latest + container_name: lbc-deployer01 + environment: + - LPS_STAGE=regtest + networks: + - lp-swap-network + ui: + build: + context: ../../docker-compose/flyover-ui + secrets: + - gh_token + args: + - LBC_ADDRESS + image: flyover-ui:latest + container_name: flyover-ui + ports: + - "3000:80" + networks: + - lp-swap-network +networks: + lp-swap-network: + driver: "bridge" +secrets: + gh_token: + file: ./gh_token.txt diff --git a/test/lp-swap/rsk-miner.sh b/test/lp-swap/rsk-miner.sh new file mode 100755 index 00000000..4fab9561 --- /dev/null +++ b/test/lp-swap/rsk-miner.sh @@ -0,0 +1,18 @@ +#!/bin/bash + +if ! [[ "$1" =~ ^[0-9]+$ ]]; then + echo "Argument must be a number" + exit 1 +fi + +while true; do + curl --location 'http://localhost:4444' \ + --header 'Content-Type: application/json' \ + --data '{ + "method": "evm_mine", + "params": [], + "id": 1, + "jsonrpc": "2.0" + }' + sleep "$1" +done diff --git a/test/lp-swap/setup.sh b/test/lp-swap/setup.sh new file mode 100755 index 00000000..02e1e077 --- /dev/null +++ b/test/lp-swap/setup.sh @@ -0,0 +1,141 @@ +#!/bin/bash + +function cleanup() { + docker compose --project-name lp-swap down -v + exit 1 +} + +if [ "$1" == "-clean" ]; then + cleanup +fi + +trap cleanup INT + +LP1="0x"$(jq -r ".lp1.key.address" config.json) +LP2="0x"$(jq -r ".lp2.key.address" config.json) + +jq -r .ghToken config.json > gh_token.txt + +docker compose build btc01 btc02 rskj +docker compose -f docker-compose.lps.yml build + +docker compose up -d btc01 btc02 rskj + +echo "Waiting for RskJ to be up and running..." +while true +do + sleep 3 + curl -s "http://127.0.0.1:4444" -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","method":"eth_chainId","params": [],"id":1}' && echo "RskJ is up and running" && break +done + +echo "Transferring 10 RBTC to $LP1..." +TX_HASH=$(curl -s -X POST "http://127.0.0.1:4444" -H "Content-Type: application/json" -d "{\"jsonrpc\":\"2.0\",\"method\":\"eth_sendTransaction\",\"params\": [{\"from\": \"0xcd2a3d9f938e13cd947ec05abc7fe734df8dd826\", \"to\": \"$LP1\", \"value\": \"0x8AC7230489E80000\"}],\"id\":1}" | jq -r ".result") +echo "Result: $TX_HASH" + +echo "Transferring 10 RBTC to $LP2..." +TX_HASH=$(curl -s -X POST "http://127.0.0.1:4444" -H "Content-Type: application/json" -d "{\"jsonrpc\":\"2.0\",\"method\":\"eth_sendTransaction\",\"params\": [{\"from\": \"0xcd2a3d9f938e13cd947ec05abc7fe734df8dd826\", \"to\": \"$LP2\", \"value\": \"0x8AC7230489E80000\"}],\"id\":1}" | jq -r ".result") +echo "Result: $TX_HASH" + +LBC_ADDR_LINE=$(docker compose run --rm lbc-deployer bash deploy-lbc.sh) +echo "LBC_ADDR_LINE: $LBC_ADDR_LINE" +docker exec btc01 bitcoin-cli -rpcuser=test -rpcpassword=test -rpcport=5555 -rpcconnect=127.0.0.1 addnode btc02:18444 add + +jq -r ".lp1.key" config.json > lp1-key.json +jq -r ".lp2.key" config.json > lp2-key.json + +LBC_ADDRESS=$(echo "$LBC_ADDR_LINE" | grep "LBC_ADDR=") + +sed -e 's/SECRET_SRC=aws/SECRET_SRC=env/g' \ + -e 's/PROVIDER_NAME=\"Default Provider\"/PROVIDER_NAME=\"Provider 1\"/g' \ + -e 's/LOG_FILE=\/home\/lps\/logs\/lps.log/LOG_FILE=/g' \ + -e 's/MONGODB_HOST=mongodb/MONGODB_HOST=lp-swap-mongodb-1/g' \ + -e 's/MONGODB_USER=root/MONGODB_USER=flyover-user/g' \ + -e 's/MONGODB_PASSWORD=root/MONGODB_PASSWORD=flyover-password/g' \ + -e "s/LBC_ADDR=/$LBC_ADDRESS/g" \ + -e "s/BTC_ENDPOINT=bitcoind:5555/BTC_ENDPOINT=btc01:5555/g" \ + -e "s/ENABLE_MANAGEMENT_API=false/ENABLE_MANAGEMENT_API=true/g" \ + -e 's/KEYSTORE_FILE=geth_keystore\/UTC--2024-01-29T16-36-09.688642000Z--9d93929a9099be4355fc2389fbf253982f9df47c/KEYSTORE_FILE=\/mnt\/lp1-key.json/g' \ + ../../sample-config.env > lp1.env + +sed -e 's/SECRET_SRC=aws/SECRET_SRC=env/g' \ + -e 's/PROVIDER_NAME=\"Default Provider\"/PROVIDER_NAME=\"Provider 2\"/g' \ + -e 's/LOG_FILE=\/home\/lps\/logs\/lps.log/LOG_FILE=/g' \ + -e 's/MONGODB_HOST=mongodb/MONGODB_HOST=lp-swap-mongodb-2/g' \ + -e 's/MONGODB_USER=root/MONGODB_USER=flyover-user/g' \ + -e 's/MONGODB_PASSWORD=root/MONGODB_PASSWORD=flyover-password/g' \ + -e "s/LBC_ADDR=/$LBC_ADDRESS/g" \ + -e "s/BASE_URL=\"http:\/\/localhost:8080\"/BASE_URL=\"http:\/\/localhost:8081\"/g" \ + -e "s/BTC_ENDPOINT=bitcoind:5555/BTC_ENDPOINT=btc02:5555/g" \ + -e "s/ENABLE_MANAGEMENT_API=false/ENABLE_MANAGEMENT_API=true/g" \ + -e 's/KEYSTORE_FILE=geth_keystore\/UTC--2024-01-29T16-36-09.688642000Z--9d93929a9099be4355fc2389fbf253982f9df47c/KEYSTORE_FILE=\/mnt\/lp2-key.json/g' \ + ../../sample-config.env > lp2.env + +docker compose --project-name lp-swap -f docker-compose.lps.yml --env-file=lp1.env up -d +docker compose --project-name lp-swap -f docker-compose.lps.yml --env-file=lp2.env up -d --scale lps=2 --scale mongodb=2 --no-recreate + +while [[ $(docker container inspect -f '{{.State.Status}}' lp-swap-lps-1) != "exited" ]]; do + sleep 1 +done +docker start lp-swap-lps-1 + +while [[ $(docker container inspect -f '{{.State.Status}}' lp-swap-lps-2) != "exited" ]]; do + sleep 1 +done +docker start lp-swap-lps-2 + +docker compose build --build-arg LBC_ADDRESS="${LBC_ADDRESS//LBC_ADDR=/}" --build-arg GH_TOKEN="$(jq -r .ghToken config.json)" ui +docker compose --project-name lp-swap up -d ui + +echo "Both providers are up and running." + +while true; do + echo "Insert the ID of LP to sunset" + read -r -p "-> " choice + + if [ "$choice" -eq 1 ] || [ "$choice" -eq 2 ]; then + SUNSET_ID=$choice + break + else + echo "Invalid choice. The only LPs are 1 and 2" + fi +done + +echo "Sunsetting LP $SUNSET_ID..." +rm -f cookie_jar.txt + +echo "Insert LP $SUNSET_ID management user" +read -r -p "-> " MANAGEMENT_USER + +echo "Insert LP $SUNSET_ID management password" +read -r -p "-> " MANAGEMENT_PWD + +if [ "$choice" -eq 1 ]; then + SUNSET_URL="http://localhost:8080" +else + SUNSET_URL="http://localhost:8081" +fi + +CSRF_TOKEN=$(curl -s -c cookie_jar.txt -H 'Content-Type: application/json' \ + "$SUNSET_URL/management" | sed -n 's/.*name="csrf"[^>]*value="\([^"]*\)".*/\1/p') + +CSRF_TOKEN=${CSRF_TOKEN//+/+} +echo "CSRF_TOKEN -> $CSRF_TOKEN" +curl -s -b cookie_jar.txt -c cookie_jar.txt "$SUNSET_URL/management/login" \ + -H "X-CSRF-Token: $CSRF_TOKEN" \ + -H 'Content-Type: application/json' \ + --data "{ + \"username\": \"$MANAGEMENT_USER\", + \"password\": \"$MANAGEMENT_PWD\" + }" + +curl -s -b cookie_jar.txt "$SUNSET_URL/providers/resignation" \ + -H "X-CSRF-Token: $CSRF_TOKEN" \ + -H 'Content-Type: application/json' -X POST && \ + echo "LP $SUNSET_ID resigned successfully" || echo "Error resigning LP $SUNSET_ID" + +read -r -p "Press enter to withdraw funds from LP $SUNSET_ID. Remember before withdrawing you need to wait the resign blocks!" choice + +curl -s -b cookie_jar.txt "$SUNSET_URL/providers/withdrawCollateral" \ + -H "X-CSRF-Token: $CSRF_TOKEN" \ + -H 'Content-Type: application/json' -X POST && \ + echo "LP $SUNSET_ID withdrew the collateral successfully" || echo "Error withdrawing LP $SUNSET_ID collateral"