From cc886fb86ca3ee15016ce8119e3e37ee939fa87a Mon Sep 17 00:00:00 2001 From: Sandipan Dey Date: Thu, 23 Nov 2023 14:29:57 +0530 Subject: [PATCH 1/6] test: move ln tests to top level bats --- bats/core/api/ln-send.bats | 734 +++++++++++++++++ bats/gql/ln-no-amount-invoice-create.gql | 11 + bats/helpers/cli.bash | 53 +- bats/helpers/ln.bash | 159 ++++ core/api/test/bats/ln-send.bats | 741 ------------------ dev/Tiltfile | 3 + .../lnd/regtest/lnd-outside-1.admin.macaroon | Bin 0 -> 293 bytes .../lnd-outside-1.admin.macaroon.base64 | 1 + .../lnd/regtest/lnd-outside-1.macaroons.db | Bin 0 -> 20480 bytes dev/config/lnd/regtest/lnd-outside-1.pubkey | 1 + .../lnd/regtest/lnd-outside-1.wallet.db | Bin 0 -> 303104 bytes .../lnd/regtest/lnd-outside-2.admin.macaroon | Bin 0 -> 293 bytes .../lnd-outside-2.admin.macaroon.base64 | 1 + .../lnd/regtest/lnd-outside-2.macaroons.db | Bin 0 -> 20480 bytes dev/config/lnd/regtest/lnd-outside-2.pubkey | 1 + .../lnd/regtest/lnd-outside-2.wallet.db | Bin 0 -> 303104 bytes dev/config/lnd/regtest/lnd2.admin.macaroon | Bin 0 -> 293 bytes .../lnd/regtest/lnd2.admin.macaroon.base64 | 1 + dev/config/lnd/regtest/lnd2.macaroons.db | Bin 0 -> 20480 bytes dev/config/lnd/regtest/lnd2.pubkey | 1 + dev/config/lnd/regtest/lnd2.wallet.db | Bin 0 -> 303104 bytes dev/docker-compose.deps.yml | 112 ++- 22 files changed, 1046 insertions(+), 773 deletions(-) create mode 100644 bats/core/api/ln-send.bats create mode 100644 bats/gql/ln-no-amount-invoice-create.gql delete mode 100644 core/api/test/bats/ln-send.bats create mode 100644 dev/config/lnd/regtest/lnd-outside-1.admin.macaroon create mode 100644 dev/config/lnd/regtest/lnd-outside-1.admin.macaroon.base64 create mode 100644 dev/config/lnd/regtest/lnd-outside-1.macaroons.db create mode 100644 dev/config/lnd/regtest/lnd-outside-1.pubkey create mode 100644 dev/config/lnd/regtest/lnd-outside-1.wallet.db create mode 100644 dev/config/lnd/regtest/lnd-outside-2.admin.macaroon create mode 100644 dev/config/lnd/regtest/lnd-outside-2.admin.macaroon.base64 create mode 100644 dev/config/lnd/regtest/lnd-outside-2.macaroons.db create mode 100644 dev/config/lnd/regtest/lnd-outside-2.pubkey create mode 100644 dev/config/lnd/regtest/lnd-outside-2.wallet.db create mode 100644 dev/config/lnd/regtest/lnd2.admin.macaroon create mode 100644 dev/config/lnd/regtest/lnd2.admin.macaroon.base64 create mode 100644 dev/config/lnd/regtest/lnd2.macaroons.db create mode 100644 dev/config/lnd/regtest/lnd2.pubkey create mode 100644 dev/config/lnd/regtest/lnd2.wallet.db diff --git a/bats/core/api/ln-send.bats b/bats/core/api/ln-send.bats new file mode 100644 index 0000000000..66393af6df --- /dev/null +++ b/bats/core/api/ln-send.bats @@ -0,0 +1,734 @@ +#!/usr/bin/env bats + +load "../../helpers/cli.bash" +load "../../helpers/user.bash" +load "../../helpers/onchain.bash" +load "../../helpers/ln.bash" +load "../../helpers/wallet.bash" + +setup_file() { + lnds_init + + create_user 'alice' + user_update_username 'alice' + fund_user_onchain 'alice' 'btc_wallet' + fund_user_onchain 'alice' 'usd_wallet' + + create_user 'bob' + user_update_username 'bob' + fund_user_onchain 'bob' 'btc_wallet' + fund_user_onchain 'bob' 'usd_wallet' + + fund_user_lightning 'alice' 'btc_wallet' '5000000' +} + +@test "h1" { + exit 1 +} + +# amount_sent_for_ln_txn_by_hash() { +# token_name="$1" +# payment_hash="$2" + +# first=20 +# txn_variables=$( +# jq -n \ +# --argjson first "$first" \ +# '{"first": $first}' +# ) +# exec_graphql "$token_name" 'transactions' "$txn_variables" > /dev/null + +# jq_query=' +# [ +# .data.me.defaultAccount.transactions.edges[] +# | select(.node.initiationVia.paymentHash == $payment_hash) +# | select(.node.direction == "SEND") +# ] +# | first .node.settlementAmount +# ' +# local amount=$(echo $output \ +# | jq -r \ +# --arg payment_hash "$payment_hash" \ +# "$jq_query" +# ) +# abs $amount +# } + +# btc_amount=1000 +# usd_amount=50 + +# @test "ln-send: lightning settled - lnInvoicePaymentSend from btc" { +# token_name="$ALICE_TOKEN_NAME" +# btc_wallet_name="$token_name.btc_wallet_id" + +# initial_lnd1_balance=$(lnd_cli channelbalance | jq -r '.balance') + +# invoice_response="$(lnd_outside_cli addinvoice --amt $btc_amount)" +# payment_request="$(echo $invoice_response | jq -r '.payment_request')" +# payment_hash=$(echo $invoice_response | jq -r '.r_hash') +# [[ "${payment_request}" != "null" ]] || exit 1 + +# variables=$( +# jq -n \ +# --arg wallet_id "$(read_value $btc_wallet_name)" \ +# --arg payment_request "$payment_request" \ +# '{input: {walletId: $wallet_id, paymentRequest: $payment_request}}' +# ) + +# exec_graphql "$token_name" 'ln-invoice-fee-probe' "$variables" +# fee_amount="$(graphql_output '.data.lnInvoiceFeeProbe.amount')" +# [[ "${fee_amount}" = "0" ]] || exit 1 + +# exec_graphql "$token_name" 'ln-invoice-payment-send' "$variables" +# send_status="$(graphql_output '.data.lnInvoicePaymentSend.status')" +# [[ "${send_status}" = "SUCCESS" ]] || exit 1 + +# # Check for settled +# retry 15 1 check_for_ln_initiated_settled "$token_name" "$payment_hash" + +# final_lnd1_balance=$(lnd_cli channelbalance | jq -r '.balance') +# lnd1_diff="$(( $initial_lnd1_balance - $final_lnd1_balance ))" +# [[ "$lnd1_diff" == "$btc_amount" ]] || exit 1 +# } + +# @test "ln-send: lightning settled - lnInvoicePaymentSend from btc, no fee probe" { +# token_name="$ALICE_TOKEN_NAME" +# btc_wallet_name="$token_name.btc_wallet_id" + +# initial_lnd1_balance=$(lnd_cli channelbalance | jq -r '.balance') + +# invoice_response="$(lnd_outside_cli addinvoice --amt $btc_amount)" +# payment_request="$(echo $invoice_response | jq -r '.payment_request')" +# payment_hash=$(echo $invoice_response | jq -r '.r_hash') +# [[ "${payment_request}" != "null" ]] || exit 1 + +# variables=$( +# jq -n \ +# --arg wallet_id "$(read_value $btc_wallet_name)" \ +# --arg payment_request "$payment_request" \ +# '{input: {walletId: $wallet_id, paymentRequest: $payment_request}}' +# ) + +# exec_graphql "$token_name" 'ln-invoice-payment-send' "$variables" +# send_status="$(graphql_output '.data.lnInvoicePaymentSend.status')" +# [[ "${send_status}" = "SUCCESS" ]] || exit 1 + +# # Check for settled +# retry 15 1 check_for_ln_initiated_settled "$token_name" "$payment_hash" + +# final_lnd1_balance=$(lnd_cli channelbalance | jq -r '.balance') +# lnd1_diff="$(( $initial_lnd1_balance - $final_lnd1_balance ))" +# [[ "$lnd1_diff" == "$btc_amount" ]] || exit 1 +# } + +# @test "ln-send: lightning settled - lnInvoicePaymentSend from usd" { +# token_name="$ALICE_TOKEN_NAME" +# usd_wallet_name="$token_name.usd_wallet_id" + +# initial_lnd1_balance=$(lnd_cli channelbalance | jq -r '.balance') + +# invoice_response="$(lnd_outside_cli addinvoice --amt $btc_amount)" +# payment_request="$(echo $invoice_response | jq -r '.payment_request')" +# payment_hash=$(echo $invoice_response | jq -r '.r_hash') +# [[ "${payment_request}" != "null" ]] || exit 1 + +# variables=$( +# jq -n \ +# --arg wallet_id "$(read_value $usd_wallet_name)" \ +# --arg payment_request "$payment_request" \ +# '{input: {walletId: $wallet_id, paymentRequest: $payment_request}}' +# ) + +# exec_graphql "$token_name" 'ln-usd-invoice-fee-probe' "$variables" +# fee_amount="$(graphql_output '.data.lnUsdInvoiceFeeProbe.amount')" +# [[ "${fee_amount}" = "0" ]] || exit 1 + +# exec_graphql "$token_name" 'ln-invoice-payment-send' "$variables" +# send_status="$(graphql_output '.data.lnInvoicePaymentSend.status')" +# [[ "${send_status}" = "SUCCESS" ]] || exit 1 + +# # Check for settled +# retry 15 1 check_for_ln_initiated_settled "$token_name" "$payment_hash" + +# final_lnd1_balance=$(lnd_cli channelbalance | jq -r '.balance') +# lnd1_diff="$(( $initial_lnd1_balance - $final_lnd1_balance ))" +# [[ "$lnd1_diff" == "$btc_amount" ]] || exit 1 +# } + +# @test "ln-send: lightning settled - lnInvoicePaymentSend from usd, no fee probe" { +# token_name="$ALICE_TOKEN_NAME" +# usd_wallet_name="$token_name.usd_wallet_id" + +# initial_lnd1_balance=$(lnd_cli channelbalance | jq -r '.balance') + +# invoice_response="$(lnd_outside_cli addinvoice --amt $btc_amount)" +# payment_request="$(echo $invoice_response | jq -r '.payment_request')" +# payment_hash=$(echo $invoice_response | jq -r '.r_hash') +# [[ "${payment_request}" != "null" ]] || exit 1 + +# variables=$( +# jq -n \ +# --arg wallet_id "$(read_value $usd_wallet_name)" \ +# --arg payment_request "$payment_request" \ +# '{input: {walletId: $wallet_id, paymentRequest: $payment_request}}' +# ) + +# exec_graphql "$token_name" 'ln-invoice-payment-send' "$variables" +# send_status="$(graphql_output '.data.lnInvoicePaymentSend.status')" +# [[ "${send_status}" = "SUCCESS" ]] || exit 1 + +# # Check for settled +# retry 15 1 check_for_ln_initiated_settled "$token_name" "$payment_hash" + +# final_lnd1_balance=$(lnd_cli channelbalance | jq -r '.balance') +# lnd1_diff="$(( $initial_lnd1_balance - $final_lnd1_balance ))" +# [[ "$lnd1_diff" == "$btc_amount" ]] || exit 1 +# } + +# @test "ln-send: lightning settled - lnNoAmountInvoicePaymentSend" { +# token_name="$ALICE_TOKEN_NAME" +# btc_wallet_name="$token_name.btc_wallet_id" + +# initial_lnd1_balance=$(lnd_cli channelbalance | jq -r '.balance') + +# invoice_response="$(lnd_outside_cli addinvoice)" +# payment_request="$(echo $invoice_response | jq -r '.payment_request')" +# payment_hash=$(echo $invoice_response | jq -r '.r_hash') +# [[ "${payment_request}" != "null" ]] || exit 1 + +# variables=$( +# jq -n \ +# --arg wallet_id "$(read_value $btc_wallet_name)" \ +# --arg payment_request "$payment_request" \ +# --arg amount $btc_amount \ +# '{input: {walletId: $wallet_id, paymentRequest: $payment_request, amount: $amount}}' +# ) + +# exec_graphql "$token_name" 'ln-no-amount-invoice-fee-probe' "$variables" +# fee_amount="$(graphql_output '.data.lnNoAmountInvoiceFeeProbe.amount')" +# [[ "${fee_amount}" = "0" ]] || exit 1 + +# exec_graphql "$token_name" 'ln-no-amount-invoice-payment-send' "$variables" +# send_status="$(graphql_output '.data.lnNoAmountInvoicePaymentSend.status')" +# [[ "${send_status}" = "SUCCESS" ]] || exit 1 + +# # Check for settled +# retry 15 1 check_for_ln_initiated_settled "$token_name" "$payment_hash" + +# final_lnd1_balance=$(lnd_cli channelbalance | jq -r '.balance') +# lnd1_diff="$(( $initial_lnd1_balance - $final_lnd1_balance ))" +# [[ "$lnd1_diff" == "$btc_amount" ]] || exit 1 +# } + +# @test "ln-send: lightning settled - lnNoAmountInvoicePaymentSend, no fee probe" { +# token_name="$ALICE_TOKEN_NAME" +# btc_wallet_name="$token_name.btc_wallet_id" + +# initial_lnd1_balance=$(lnd_cli channelbalance | jq -r '.balance') + +# invoice_response="$(lnd_outside_cli addinvoice)" +# payment_request="$(echo $invoice_response | jq -r '.payment_request')" +# payment_hash=$(echo $invoice_response | jq -r '.r_hash') +# [[ "${payment_request}" != "null" ]] || exit 1 + +# variables=$( +# jq -n \ +# --arg wallet_id "$(read_value $btc_wallet_name)" \ +# --arg payment_request "$payment_request" \ +# --arg amount $btc_amount \ +# '{input: {walletId: $wallet_id, paymentRequest: $payment_request, amount: $amount}}' +# ) + +# exec_graphql "$token_name" 'ln-no-amount-invoice-payment-send' "$variables" +# send_status="$(graphql_output '.data.lnNoAmountInvoicePaymentSend.status')" +# [[ "${send_status}" = "SUCCESS" ]] || exit 1 + +# # Check for settled +# retry 15 1 check_for_ln_initiated_settled "$token_name" "$payment_hash" + +# final_lnd1_balance=$(lnd_cli channelbalance | jq -r '.balance') +# lnd1_diff="$(( $initial_lnd1_balance - $final_lnd1_balance ))" +# [[ "$lnd1_diff" == "$btc_amount" ]] || exit 1 +# } + +# @test "ln-send: lightning settled - lnNoAmountUsdInvoicePaymentSend" { +# token_name="$ALICE_TOKEN_NAME" +# usd_wallet_name="$token_name.usd_wallet_id" + +# initial_balance="$(balance_for_wallet $token_name 'USD')" +# initial_lnd1_balance=$(lnd_cli channelbalance | jq -r '.balance') + +# invoice_response="$(lnd_outside_cli addinvoice)" +# payment_request="$(echo $invoice_response | jq -r '.payment_request')" +# payment_hash=$(echo $invoice_response | jq -r '.r_hash') +# [[ "${payment_request}" != "null" ]] || exit 1 + +# variables=$( +# jq -n \ +# --arg wallet_id "$(read_value $usd_wallet_name)" \ +# --arg payment_request "$payment_request" \ +# --arg amount $usd_amount \ +# '{input: {walletId: $wallet_id, paymentRequest: $payment_request, amount: $amount}}' +# ) + +# exec_graphql "$token_name" 'ln-no-amount-usd-invoice-fee-probe' "$variables" +# fee_amount="$(graphql_output '.data.lnNoAmountUsdInvoiceFeeProbe.amount')" +# [[ "${fee_amount}" = "0" ]] || exit 1 + +# exec_graphql "$token_name" 'ln-no-amount-usd-invoice-payment-send' "$variables" +# send_status="$(graphql_output '.data.lnNoAmountUsdInvoicePaymentSend.status')" +# [[ "${send_status}" = "SUCCESS" ]] || exit 1 + +# # Check for settled +# retry 15 1 check_for_ln_initiated_settled "$token_name" "$payment_hash" + +# final_balance="$(balance_for_wallet $token_name 'USD')" +# wallet_diff="$(( $initial_balance - $final_balance ))" +# [[ "$wallet_diff" == "$usd_amount" ]] || exit 1 + +# final_lnd1_balance=$(lnd_cli channelbalance | jq -r '.balance') +# lnd1_diff="$(( $initial_lnd1_balance - $final_lnd1_balance ))" +# [[ "$lnd1_diff" -gt "0" ]] || exit 1 +# } + +# @test "ln-send: lightning settled - lnNoAmountUsdInvoicePaymentSend, no fee probe" { +# token_name="$ALICE_TOKEN_NAME" +# usd_wallet_name="$token_name.usd_wallet_id" + +# initial_balance="$(balance_for_wallet $token_name 'USD')" +# initial_lnd1_balance=$(lnd_cli channelbalance | jq -r '.balance') + +# invoice_response="$(lnd_outside_cli addinvoice)" +# payment_request="$(echo $invoice_response | jq -r '.payment_request')" +# payment_hash=$(echo $invoice_response | jq -r '.r_hash') +# [[ "${payment_request}" != "null" ]] || exit 1 + +# variables=$( +# jq -n \ +# --arg wallet_id "$(read_value $usd_wallet_name)" \ +# --arg payment_request "$payment_request" \ +# --arg amount $usd_amount \ +# '{input: {walletId: $wallet_id, paymentRequest: $payment_request, amount: $amount}}' +# ) + +# exec_graphql "$token_name" 'ln-no-amount-usd-invoice-payment-send' "$variables" +# send_status="$(graphql_output '.data.lnNoAmountUsdInvoicePaymentSend.status')" +# [[ "${send_status}" = "SUCCESS" ]] || exit 1 + +# # Check for settled +# retry 15 1 check_for_ln_initiated_settled "$token_name" "$payment_hash" + +# final_balance="$(balance_for_wallet $token_name 'USD')" +# wallet_diff="$(( $initial_balance - $final_balance ))" +# [[ "$wallet_diff" == "$usd_amount" ]] || exit 1 + +# final_lnd1_balance=$(lnd_cli channelbalance | jq -r '.balance') +# lnd1_diff="$(( $initial_lnd1_balance - $final_lnd1_balance ))" +# [[ "$lnd1_diff" -gt "0" ]] || exit 1 +# } + +# @test "ln-send: intraledger settled - lnInvoicePaymentSend from btc to btc, with contacts check" { +# token_name="$ALICE_TOKEN_NAME" +# btc_wallet_name="$token_name.btc_wallet_id" + +# recipient_token_name="user_$RANDOM" +# recipient_phone="$(random_phone)" +# login_user \ +# "$recipient_token_name" \ +# "$recipient_phone" \ +# "$CODE" +# user_update_username "$recipient_token_name" +# btc_recipient_wallet_name="$recipient_token_name.btc_wallet_id" + +# initial_balance="$(balance_for_wallet $token_name 'BTC')" +# initial_lnd1_balance=$(lnd_cli channelbalance | jq -r '.balance') + +# # Check is not contact before send +# run is_contact "$token_name" "$recipient_token_name" +# [[ "$status" -ne "0" ]] || exit 1 +# run is_contact "$recipient_token_name" "$token_name" +# [[ "$status" -ne "0" ]] || exit 1 + +# variables=$( +# jq -n \ +# --arg wallet_id "$(read_value $btc_recipient_wallet_name)" \ +# --arg amount "$btc_amount" \ +# '{input: {walletId: $wallet_id, amount: $amount}}' +# ) +# exec_graphql "$recipient_token_name" 'ln-invoice-create' "$variables" +# invoice="$(graphql_output '.data.lnInvoiceCreate.invoice')" + +# payment_request="$(echo $invoice | jq -r '.paymentRequest')" +# [[ "${payment_request}" != "null" ]] || exit 1 +# payment_hash="$(echo $invoice | jq -r '.paymentHash')" +# [[ "${payment_hash}" != "null" ]] || exit 1 + +# variables=$( +# jq -n \ +# --arg wallet_id "$(read_value $btc_wallet_name)" \ +# --arg payment_request "$payment_request" \ +# '{input: {walletId: $wallet_id, paymentRequest: $payment_request}}' +# ) + +# exec_graphql "$token_name" 'ln-invoice-payment-send' "$variables" +# send_status="$(graphql_output '.data.lnInvoicePaymentSend.status')" +# [[ "${send_status}" = "SUCCESS" ]] || exit 1 + +# # Check for settled +# retry 15 1 check_for_ln_initiated_settled "$token_name" "$payment_hash" +# check_for_ln_initiated_settled "$recipient_token_name" "$payment_hash" + +# final_balance="$(balance_for_wallet $token_name 'BTC')" +# wallet_diff="$(( $initial_balance - $final_balance ))" +# [[ "$wallet_diff" == "$btc_amount" ]] || exit 1 + +# final_lnd1_balance=$(lnd_cli channelbalance | jq -r '.balance') +# lnd1_diff="$(( $initial_lnd1_balance - $final_lnd1_balance ))" +# [[ "$lnd1_diff" == "0" ]] || exit 1 + +# # Check is contact after send +# run is_contact "$token_name" "$recipient_token_name" +# [[ "$status" == "0" ]] || exit 1 +# run is_contact "$recipient_token_name" "$token_name" +# [[ "$status" == "0" ]] || exit 1 +# } + +# @test "ln-send: intraledger settled - lnInvoicePaymentSend from usd to btc" { +# token_name="$ALICE_TOKEN_NAME" +# usd_wallet_name="$token_name.usd_wallet_id" + +# recipient_token_name="$BOB_TOKEN_NAME" +# btc_recipient_wallet_name="$recipient_token_name.btc_wallet_id" + +# initial_recipient_balance="$(balance_for_wallet $recipient_token_name 'BTC')" +# initial_lnd1_balance=$(lnd_cli channelbalance | jq -r '.balance') + +# variables=$( +# jq -n \ +# --arg wallet_id "$(read_value $btc_recipient_wallet_name)" \ +# --arg amount "$btc_amount" \ +# '{input: {walletId: $wallet_id, amount: $amount}}' +# ) +# exec_graphql "$recipient_token_name" 'ln-invoice-create' "$variables" +# invoice="$(graphql_output '.data.lnInvoiceCreate.invoice')" + +# payment_request="$(echo $invoice | jq -r '.paymentRequest')" +# [[ "${payment_request}" != "null" ]] || exit 1 +# payment_hash="$(echo $invoice | jq -r '.paymentHash')" +# [[ "${payment_hash}" != "null" ]] || exit 1 + +# variables=$( +# jq -n \ +# --arg wallet_id "$(read_value $usd_wallet_name)" \ +# --arg payment_request "$payment_request" \ +# '{input: {walletId: $wallet_id, paymentRequest: $payment_request}}' +# ) + +# exec_graphql "$token_name" 'ln-usd-invoice-fee-probe' "$variables" +# fee_amount="$(graphql_output '.data.lnUsdInvoiceFeeProbe.amount')" +# [[ "${fee_amount}" = "0" ]] || exit 1 + +# exec_graphql "$token_name" 'ln-invoice-payment-send' "$variables" +# send_status="$(graphql_output '.data.lnInvoicePaymentSend.status')" +# [[ "${send_status}" = "SUCCESS" ]] || exit 1 + +# # Check for settled +# retry 15 1 check_for_ln_initiated_settled "$token_name" "$payment_hash" +# check_for_ln_initiated_settled "$recipient_token_name" "$payment_hash" + +# final_recipient_balance="$(balance_for_wallet $recipient_token_name 'BTC')" +# recipient_wallet_diff="$(( $final_recipient_balance - $initial_recipient_balance ))" +# [[ "$recipient_wallet_diff" == "$btc_amount" ]] || exit 1 + +# final_lnd1_balance=$(lnd_cli channelbalance | jq -r '.balance') +# lnd1_diff="$(( $initial_lnd1_balance - $final_lnd1_balance ))" +# [[ "$lnd1_diff" == "0" ]] || exit 1 +# } + +# @test "ln-send: intraledger settled - lnNoAmountInvoicePaymentSend from btc to usd" { +# token_name="$ALICE_TOKEN_NAME" +# btc_wallet_name="$token_name.btc_wallet_id" + +# recipient_token_name="$BOB_TOKEN_NAME" +# usd_recipient_wallet_name="$recipient_token_name.usd_wallet_id" + +# initial_balance="$(balance_for_wallet $token_name 'BTC')" +# initial_lnd1_balance=$(lnd_cli channelbalance | jq -r '.balance') + +# variables=$( +# jq -n \ +# --arg wallet_id "$(read_value $usd_recipient_wallet_name)" \ +# '{input: {walletId: $wallet_id}}' +# ) +# exec_graphql "$recipient_token_name" 'ln-no-amount-invoice-create' "$variables" +# invoice="$(graphql_output '.data.lnNoAmountInvoiceCreate.invoice')" + +# payment_request="$(echo $invoice | jq -r '.paymentRequest')" +# [[ "${payment_request}" != "null" ]] || exit 1 +# payment_hash="$(echo $invoice | jq -r '.paymentHash')" +# [[ "${payment_hash}" != "null" ]] || exit 1 + +# variables=$( +# jq -n \ +# --arg wallet_id "$(read_value $btc_wallet_name)" \ +# --arg payment_request "$payment_request" \ +# --arg amount $btc_amount \ +# '{input: {walletId: $wallet_id, paymentRequest: $payment_request, amount: $amount}}' +# ) + +# exec_graphql "$token_name" 'ln-no-amount-invoice-payment-send' "$variables" +# send_status="$(graphql_output '.data.lnNoAmountInvoicePaymentSend.status')" +# [[ "${send_status}" = "SUCCESS" ]] || exit 1 + +# # Check for settled +# retry 15 1 check_for_ln_initiated_settled "$token_name" "$payment_hash" +# check_for_ln_initiated_settled "$recipient_token_name" "$payment_hash" + +# final_balance="$(balance_for_wallet $token_name 'BTC')" +# wallet_diff="$(( $initial_balance - $final_balance ))" +# [[ "$wallet_diff" == "$btc_amount" ]] || exit 1 + +# final_lnd1_balance=$(lnd_cli channelbalance | jq -r '.balance') +# lnd1_diff="$(( $initial_lnd1_balance - $final_lnd1_balance ))" +# [[ "$lnd1_diff" == "0" ]] || exit 1 +# } + +# @test "ln-send: intraledger settled - lnNoAmountUsdInvoicePaymentSend from usd to usd" { +# token_name="$ALICE_TOKEN_NAME" +# usd_wallet_name="$token_name.usd_wallet_id" + +# recipient_token_name="$BOB_TOKEN_NAME" +# usd_recipient_wallet_name="$recipient_token_name.usd_wallet_id" + +# initial_balance="$(balance_for_wallet $token_name 'USD')" +# initial_lnd1_balance=$(lnd_cli channelbalance | jq -r '.balance') + +# variables=$( +# jq -n \ +# --arg wallet_id "$(read_value $usd_recipient_wallet_name)" \ +# '{input: {walletId: $wallet_id}}' +# ) +# exec_graphql "$recipient_token_name" 'ln-no-amount-invoice-create' "$variables" +# invoice="$(graphql_output '.data.lnNoAmountInvoiceCreate.invoice')" + +# payment_request="$(echo $invoice | jq -r '.paymentRequest')" +# [[ "${payment_request}" != "null" ]] || exit 1 +# payment_hash="$(echo $invoice | jq -r '.paymentHash')" +# [[ "${payment_hash}" != "null" ]] || exit 1 + +# variables=$( +# jq -n \ +# --arg wallet_id "$(read_value $usd_wallet_name)" \ +# --arg payment_request "$payment_request" \ +# --arg amount $usd_amount \ +# '{input: {walletId: $wallet_id, paymentRequest: $payment_request, amount: $amount}}' +# ) + +# exec_graphql "$token_name" 'ln-no-amount-usd-invoice-payment-send' "$variables" +# send_status="$(graphql_output '.data.lnNoAmountUsdInvoicePaymentSend.status')" +# [[ "${send_status}" = "SUCCESS" ]] || exit 1 + +# # Check for settled +# retry 15 1 check_for_ln_initiated_settled "$token_name" "$payment_hash" +# check_for_ln_initiated_settled "$recipient_token_name" "$payment_hash" + +# final_balance="$(balance_for_wallet $token_name 'USD')" +# wallet_diff="$(( $initial_balance - $final_balance ))" +# [[ "$wallet_diff" == "$usd_amount" ]] || exit 1 + +# final_lnd1_balance=$(lnd_cli channelbalance | jq -r '.balance') +# lnd1_diff="$(( $initial_lnd1_balance - $final_lnd1_balance ))" +# [[ "$lnd1_diff" == "0" ]] || exit 1 +# } + +# @test "ln-send: ln settled - settle failed and then successful payment" { +# token_name="$ALICE_TOKEN_NAME" +# btc_wallet_name="$token_name.btc_wallet_id" + +# threshold_amount=150000 +# invoice_response="$(lnd_outside_2_cli addinvoice --amt $threshold_amount)" +# payment_request="$(echo $invoice_response | jq -r '.payment_request')" +# payment_hash=$(echo $invoice_response | jq -r '.r_hash') +# [[ "${payment_request}" != "null" ]] || exit 1 + +# check_num_txns() { +# expected_num="$1" + +# num_txns="$(num_txns_for_hash "$token_name" "$payment_hash")" +# [[ "$num_txns" == "$expected_num" ]] || exit 1 +# } + +# # Rebalance last hop so payment will fail +# rebalance_channel lnd_outside_cli lnd_outside_2_cli "$(( $threshold_amount - 1 ))" + +# # Try payment and check for fail +# initial_balance="$(balance_for_wallet $token_name 'BTC')" + +# variables=$( +# jq -n \ +# --arg wallet_id "$(read_value $btc_wallet_name)" \ +# --arg payment_request "$payment_request" \ +# '{input: {walletId: $wallet_id, paymentRequest: $payment_request}}' +# ) +# exec_graphql "$token_name" 'ln-invoice-payment-send' "$variables" +# send_status="$(graphql_output '.data.lnInvoicePaymentSend.status')" +# error_msg="$(graphql_output '.data.lnInvoicePaymentSend.errors[0].message')" +# [[ "${send_status}" = "FAILURE" ]] || exit 1 +# [[ "${error_msg}" == "Unable to find a route for payment." ]] || exit 1 + +# # Check for txns +# retry 15 1 check_num_txns "2" +# balance_after_fail="$(balance_for_wallet $token_name 'BTC')" +# [[ "$initial_balance" == "$balance_after_fail" ]] || exit 1 + +# # Rebalance last hop so same payment will succeed +# rebalance_channel lnd_outside_cli lnd_outside_2_cli "$(( $threshold_amount * 2 ))" +# lnd_cli resetmc + +# # Retry payment and check for success +# exec_graphql "$token_name" 'ln-invoice-fee-probe' "$variables" +# num_errors="$(graphql_output '.data.lnInvoiceFeeProbe.errors | length')" +# fee_amount="$(graphql_output '.data.lnInvoiceFeeProbe.amount')" +# [[ "$num_errors" == "0" ]] || exit 1 +# [[ "${fee_amount}" -gt "0" ]] || exit 1 + +# exec_graphql "$token_name" 'ln-invoice-payment-send' "$variables" +# send_status="$(graphql_output '.data.lnInvoicePaymentSend.status')" +# [[ "${send_status}" = "SUCCESS" ]] || exit 1 + +# # Check for txns +# retry 15 1 check_num_txns "3" +# balance_after_success="$(balance_for_wallet $token_name 'BTC')" +# [[ "$balance_after_success" -lt "$initial_balance" ]] || exit 1 +# } + +# @test "ln-send: ln settled - settle failed and then pending-to-failed payment" { +# skip "missing xxd dep, failing on concourse" + +# token_name="$ALICE_TOKEN_NAME" +# btc_wallet_name="$token_name.btc_wallet_id" + +# threshold_amount=150000 +# secret=$(xxd -l 32 -p /dev/urandom) +# payment_hash=$(echo -n $secret | xxd -r -p | sha256sum | cut -d ' ' -f1) +# invoice_response="$(lnd_outside_2_cli addholdinvoice $payment_hash --amt $threshold_amount)" +# payment_request="$(echo $invoice_response | jq -r '.payment_request')" +# [[ "${payment_request}" != "null" ]] || exit 1 + +# check_num_txns() { +# expected_num="$1" + +# num_txns="$(num_txns_for_hash "$token_name" "$payment_hash")" +# [[ "$num_txns" == "$expected_num" ]] || exit 1 +# } + +# # Rebalance last hop so payment will fail +# rebalance_channel lnd_outside_cli lnd_outside_2_cli "$(( $threshold_amount - 1 ))" + +# # Try payment and check for fail +# initial_balance="$(balance_for_wallet $token_name 'BTC')" + +# variables=$( +# jq -n \ +# --arg wallet_id "$(read_value $btc_wallet_name)" \ +# --arg payment_request "$payment_request" \ +# '{input: {walletId: $wallet_id, paymentRequest: $payment_request}}' +# ) +# exec_graphql "$token_name" 'ln-invoice-payment-send' "$variables" +# send_status="$(graphql_output '.data.lnInvoicePaymentSend.status')" +# error_msg="$(graphql_output '.data.lnInvoicePaymentSend.errors[0].message')" +# [[ "${send_status}" = "FAILURE" ]] || exit 1 +# [[ "${error_msg}" == "Unable to find a route for payment." ]] || exit 1 + +# # Check for txns +# retry 15 1 check_num_txns "2" +# balance_after_fail="$(balance_for_wallet $token_name 'BTC')" +# [[ "$initial_balance" == "$balance_after_fail" ]] || exit 1 + +# # Rebalance last hop so same payment will succeed +# rebalance_channel lnd_outside_cli lnd_outside_2_cli "$(( $threshold_amount * 2 ))" +# lnd_cli resetmc + +# # Retry payment and check for pending +# exec_graphql "$token_name" 'ln-invoice-payment-send' "$variables" +# send_status="$(graphql_output '.data.lnInvoicePaymentSend.status')" +# [[ "${send_status}" = "PENDING" ]] || exit 1 + +# # Check for txns +# retry 15 1 check_num_txns "3" +# check_for_ln_initiated_pending "$token_name" "$payment_hash" "10" \ +# || exit 1 +# balance_while_pending="$(balance_for_wallet $token_name 'BTC')" +# [[ "$balance_while_pending" -lt "$initial_balance" ]] || exit 1 + +# # Cancel hodl invoice +# lnd_outside_2_cli cancelinvoice "$payment_hash" + +# retry 15 1 check_num_txns "4" +# balance_after_pending_failed="$(balance_for_wallet $token_name 'BTC')" +# [[ "$balance_after_pending_failed" == "$initial_balance" ]] || exit 1 + +# run check_for_ln_initiated_pending "$token_name" "$payment_hash" "10" +# [[ "$status" -ne 0 ]] || exit 1 +# } + +# @test "ln-send: ln settled - pending-to-failed usd payment" { +# skip "missing xxd dep, failing on concourse" + +# token_name="$ALICE_TOKEN_NAME" +# btc_wallet_name="$token_name.btc_wallet_id" +# usd_wallet_name="$token_name.usd_wallet_id" + +# threshold_amount=150000 +# secret=$(xxd -l 32 -p /dev/urandom) +# payment_hash=$(echo -n $secret | xxd -r -p | sha256sum | cut -d ' ' -f1) +# invoice_response="$(lnd_outside_2_cli addholdinvoice $payment_hash --amt $threshold_amount)" +# payment_request="$(echo $invoice_response | jq -r '.payment_request')" +# [[ "${payment_request}" != "null" ]] || exit 1 + +# check_num_txns() { +# expected_num="$1" + +# num_txns="$(num_txns_for_hash "$token_name" "$payment_hash")" +# [[ "$num_txns" == "$expected_num" ]] || exit 1 +# } + +# initial_btc_balance="$(balance_for_wallet $token_name 'BTC')" +# initial_usd_balance="$(balance_for_wallet $token_name 'USD')" + +# # Rebalance last hop so payment will succeed +# rebalance_channel lnd_outside_cli lnd_outside_2_cli "$(( $threshold_amount * 2 ))" +# lnd_cli resetmc + +# # Try payment and check for pending +# variables=$( +# jq -n \ +# --arg wallet_id "$(read_value $usd_wallet_name)" \ +# --arg payment_request "$payment_request" \ +# '{input: {walletId: $wallet_id, paymentRequest: $payment_request}}' +# ) +# exec_graphql "$token_name" 'ln-invoice-payment-send' "$variables" +# send_status="$(graphql_output '.data.lnInvoicePaymentSend.status')" +# [[ "${send_status}" = "PENDING" ]] || exit 1 + +# # Check for txns +# retry 15 1 check_num_txns "1" +# check_for_ln_initiated_pending "$token_name" "$payment_hash" "10" \ +# || exit 1 +# btc_balance_while_pending="$(balance_for_wallet $token_name 'BTC')" +# usd_balance_while_pending="$(balance_for_wallet $token_name 'USD')" +# [[ "$btc_balance_while_pending" == "$initial_btc_balance" ]] || exit 1 +# [[ "$usd_balance_while_pending" -lt "$initial_usd_balance" ]] || exit 1 + +# # Cancel hodl invoice +# lnd_outside_2_cli cancelinvoice "$payment_hash" + +# retry 15 1 check_num_txns "2" +# btc_balance_after_pending_failed="$(balance_for_wallet $token_name 'BTC')" +# usd_balance_after_pending_failed="$(balance_for_wallet $token_name 'USD')" +# [[ "$btc_balance_after_pending_failed" -gt "$btc_balance_while_pending" ]] || exit 1 +# [[ "$usd_balance_after_pending_failed" == "$usd_balance_while_pending" ]] || exit 1 + +# run check_for_ln_initiated_pending "$token_name" "$payment_hash" "10" +# [[ "$status" -ne 0 ]] || exit 1 +# } diff --git a/bats/gql/ln-no-amount-invoice-create.gql b/bats/gql/ln-no-amount-invoice-create.gql new file mode 100644 index 0000000000..ac03667394 --- /dev/null +++ b/bats/gql/ln-no-amount-invoice-create.gql @@ -0,0 +1,11 @@ +mutation lnNoAmountInvoiceCreate($input: LnNoAmountInvoiceCreateInput!) { + lnNoAmountInvoiceCreate(input: $input) { + invoice { + paymentRequest + paymentHash + } + errors { + message + } + } +} diff --git a/bats/helpers/cli.bash b/bats/helpers/cli.bash index fecdc9fec7..32169544d6 100644 --- a/bats/helpers/cli.bash +++ b/bats/helpers/cli.bash @@ -1,3 +1,15 @@ +tilt_cli() { + tilt $@ +} + +bria_cli() { + docker exec "${COMPOSE_PROJECT_NAME}-bria-1" bria $@ +} + +mongo_cli() { + docker exec "${COMPOSE_PROJECT_NAME}-mongodb-1" mongosh --quiet mongodb://localhost:27017/galoy --eval $@ +} + bitcoin_cli() { docker exec "${COMPOSE_PROJECT_NAME}-bitcoind-1" bitcoin-cli $@ } @@ -10,14 +22,43 @@ lnd_cli() { $@ } -bria_cli() { - docker exec "${COMPOSE_PROJECT_NAME}-bria-1" bria $@ +lnd2_cli() { + docker exec "${COMPOSE_PROJECT_NAME}-lnd2-1" \ + lncli \ + --macaroonpath /root/.lnd/admin.macaroon \ + --tlscertpath /root/.lnd/tls.cert \ + $@ } -tilt_cli() { - tilt $@ +lnd_outside_cli() { + docker exec "${COMPOSE_PROJECT_NAME}-lnd-outside-1-1" \ + lncli \ + --macaroonpath /root/.lnd/admin.macaroon \ + --tlscertpath /root/.lnd/tls.cert \ + $@ } -mongo_cli() { - docker exec "${COMPOSE_PROJECT_NAME}-mongodb-1" mongosh --quiet mongodb://localhost:27017/galoy --eval $@ +lnd_outside_2_cli() { + docker exec "${COMPOSE_PROJECT_NAME}-lnd-outside-2-1" \ + lncli \ + --macaroonpath /root/.lnd/admin.macaroon \ + --tlscertpath /root/.lnd/tls.cert \ + $@ +} + +run_with_lnd() { + local lnd_name="$1" + shift # This will shift away the function name, so $1 becomes the next argument + + if [[ "$lnd_name" == "lnd_cli" ]]; then + lnd_cli "$@" + elif [[ "$lnd_name" == "lnd2_cli" ]]; then + lnd2_cli "$@" + elif [[ "$lnd_name" == "lnd_outside_cli" ]]; then + lnd_outside_cli "$@" + elif [[ "$lnd_name" == "lnd_outside_2_cli" ]]; then + lnd_outside_2_cli "$@" + else + echo "Invalid function name passed!" && return 1 + fi } diff --git a/bats/helpers/ln.bash b/bats/helpers/ln.bash index e068c3859c..e54033bdfc 100644 --- a/bats/helpers/ln.bash +++ b/bats/helpers/ln.bash @@ -2,6 +2,119 @@ CURRENT_FILE=${BASH_SOURCE:-bats/helpers/.} source "$(dirname "$CURRENT_FILE")/_common.bash" source "$(dirname "$CURRENT_FILE")/cli.bash" +fund_user_lightning() { + local token_name=$1 + local wallet_id_name="$token_name.${2}_id" # btc_wallet or usd_wallet + local amount=$3 + + variables=$( + jq -n \ + --arg wallet_id "$(read_value $wallet_id_name)" \ + '{input: {walletId: $wallet_id}}' + ) + exec_graphql "$token_name" 'ln-no-amount-invoice-create' "$variables" + invoice="$(graphql_output '.data.lnNoAmountInvoiceCreate.invoice')" + + payment_request="$(echo $invoice | jq -r '.paymentRequest')" + [[ "${payment_request}" != "null" ]] + payment_hash="$(echo $invoice | jq -r '.paymentHash')" + [[ "${payment_hash}" != "null" ]] + + lnd_outside_cli payinvoice -f \ + --pay_req "$payment_request" \ + --amt "$amount" + + retry 15 1 check_for_ln_initiated_settled "$token_name" "$payment_hash" +} + +lnds_init() { + # Clean up any existing channels + close_partner_initiated_channels_with_external || true + + # Mine onchain balance + local amount="1" + local address="$(lnd_outside_cli newaddress p2wkh | jq -r '.address')" + local local_amount="10000000" + local push_amount="5000000" + bitcoin_cli sendtoaddress "$address" "$amount" + bitcoin_cli -generate 3 + + no_pending_channels() { + pending_channel="$(lnd_outside_cli pendingchannels | jq -r '.pending_open_channels[0]')" + if [[ "$pending_channel" != "null" ]]; then + bitcoin_cli -generate 3 + exit 1 + fi + } + + synced_to_graph() { + is_synced="$(lnd_outside_cli getinfo | jq -r '.synced_to_graph')" + [[ "$is_synced" == "true" ]] || exit 1 + } + + # Open channel from lndoutside1 -> lnd1 + pubkey="$(lnd_cli getinfo | jq -r '.identity_pubkey')" + endpoint="${COMPOSE_PROJECT_NAME}-lnd1-1:9735" + + lnd_outside_cli connect "${pubkey}@${endpoint}" || true + retry 10 1 synced_to_graph + lnd_outside_cli openchannel \ + --node_key "$pubkey" \ + --local_amt "$local_amount" + + retry 10 1 mempool_not_empty + retry 10 1 no_pending_channels + + # Open channel with push from lndoutside1 -> lndoutside2 + pubkey="$(lnd_outside_2_cli getinfo | jq -r '.identity_pubkey')" + endpoint="${COMPOSE_PROJECT_NAME}-lnd-outside-2-1:9735" + + lnd_outside_cli connect "${pubkey}@${endpoint}" || true + retry 10 1 synced_to_graph + lnd_outside_cli openchannel \ + --node_key "$pubkey" \ + --local_amt "$local_amount" \ + --push_amt "$push_amount" + + retry 10 1 mempool_not_empty + retry 10 1 no_pending_channels + + # FIXME: we may need some check on the graph or something else + # NB: I get randomly a "no route" error otherwise + sleep 10 +} + +close_partner_initiated_channels_with_external() { + close_channels_with_external() { + lnd_cli_value="$1" + lnd1_pubkey=$(lnd_cli getinfo | jq -r '.identity_pubkey') + lnd2_pubkey=$(lnd2_cli getinfo | jq -r '.identity_pubkey') + + partner_initiated_external_channel_filter=' + .channels[]? + | select(.initiator != true) + | select(.remote_pubkey != $lnd1_pubkey) + | select(.remote_pubkey != $lnd2_pubkey) + | .channel_point + ' + + run_with_lnd "$lnd_cli_value" listchannels \ + | jq -r \ + --arg lnd1_pubkey "$lnd1_pubkey" \ + --arg lnd2_pubkey "$lnd2_pubkey" \ + "$partner_initiated_external_channel_filter" \ + | while read -r channel_point; do + funding_txid="${channel_point%%:*}" + run_with_lnd "$lnd_cli_value" closechannel "$funding_txid" + done + } + + close_channels_with_external lnd_cli + close_channels_with_external lnd2_cli + close_channels_with_external lnd_outside_cli + close_channels_with_external lnd_outside_2_cli +} + create_new_lnd_onchain_address() { local wallet_name=$1 local wallet_id=$(read_value $wallet_name) @@ -31,3 +144,49 @@ create_new_lnd_onchain_address() { echo $address } + +# Status of LN Payment +check_for_ln_initiated_settled() { + check_for_ln_initiated_status "SUCCESS" "$@" +} + +check_for_ln_initiated_pending() { + check_for_ln_initiated_status "PENDING" "$@" +} + +check_for_ln_initiated_status() { + local expected_status=$1 + local token_name=$2 + local payment_hash=$3 + local first=${4:-"2"} + + variables=$( + jq -n \ + --argjson first "$first" \ + '{"first": $first}' + ) + exec_graphql "$token_name" 'transactions' "$variables" + + status="$(get_from_transaction_by_ln_hash_and_status $payment_hash $expected_status '.status')" + [[ "${status}" == "${expected_status}" ]] || return 1 +} + +get_from_transaction_by_ln_hash_and_status() { + payment_hash="$1" + expected_status="$2" + property_query="$3" + + jq_query=' + .data.me.defaultAccount.transactions.edges[] + | select(.node.initiationVia.paymentHash == $payment_hash) + | select(.node.status == $expected_status) + .node' + + echo $output \ + | jq -r \ + --arg payment_hash "$payment_hash" \ + --arg expected_status "$expected_status" \ + "$jq_query" \ + | jq -r "$property_query" \ + | head -n 1 +} diff --git a/core/api/test/bats/ln-send.bats b/core/api/test/bats/ln-send.bats deleted file mode 100644 index fa6aafe62b..0000000000 --- a/core/api/test/bats/ln-send.bats +++ /dev/null @@ -1,741 +0,0 @@ -#!/usr/bin/env bats - -load "helpers/setup-and-teardown" -load "helpers/ln" - -setup_file() { - clear_cache - - bitcoind_init - start_trigger - start_server - start_exporter - - lnds_init - initialize_user_from_onchain "$ALICE_TOKEN_NAME" "$ALICE_PHONE" "$CODE" - user_update_username "$ALICE_TOKEN_NAME" - initialize_user_from_onchain "$BOB_TOKEN_NAME" "$BOB_PHONE" "$CODE" -} - -teardown_file() { - stop_trigger - stop_server - stop_exporter -} - -setup() { - reset_redis -} - -teardown() { - if [[ "$(balance_for_check)" != 0 ]]; then - fail "Error: balance_for_check failed" - fi -} - -amount_sent_for_ln_txn_by_hash() { - token_name="$1" - payment_hash="$2" - - first=20 - txn_variables=$( - jq -n \ - --argjson first "$first" \ - '{"first": $first}' - ) - exec_graphql "$token_name" 'transactions' "$txn_variables" > /dev/null - - jq_query=' - [ - .data.me.defaultAccount.transactions.edges[] - | select(.node.initiationVia.paymentHash == $payment_hash) - | select(.node.direction == "SEND") - ] - | first .node.settlementAmount - ' - local amount=$(echo $output \ - | jq -r \ - --arg payment_hash "$payment_hash" \ - "$jq_query" - ) - abs $amount -} - -btc_amount=1000 -usd_amount=50 - -@test "ln-send: lightning settled - lnInvoicePaymentSend from btc" { - token_name="$ALICE_TOKEN_NAME" - btc_wallet_name="$token_name.btc_wallet_id" - - initial_lnd1_balance=$(lnd_cli channelbalance | jq -r '.balance') - - invoice_response="$(lnd_outside_cli addinvoice --amt $btc_amount)" - payment_request="$(echo $invoice_response | jq -r '.payment_request')" - payment_hash=$(echo $invoice_response | jq -r '.r_hash') - [[ "${payment_request}" != "null" ]] || exit 1 - - variables=$( - jq -n \ - --arg wallet_id "$(read_value $btc_wallet_name)" \ - --arg payment_request "$payment_request" \ - '{input: {walletId: $wallet_id, paymentRequest: $payment_request}}' - ) - - exec_graphql "$token_name" 'ln-invoice-fee-probe' "$variables" - fee_amount="$(graphql_output '.data.lnInvoiceFeeProbe.amount')" - [[ "${fee_amount}" = "0" ]] || exit 1 - - exec_graphql "$token_name" 'ln-invoice-payment-send' "$variables" - send_status="$(graphql_output '.data.lnInvoicePaymentSend.status')" - [[ "${send_status}" = "SUCCESS" ]] || exit 1 - - # Check for settled - retry 15 1 check_for_ln_initiated_settled "$token_name" "$payment_hash" - - final_lnd1_balance=$(lnd_cli channelbalance | jq -r '.balance') - lnd1_diff="$(( $initial_lnd1_balance - $final_lnd1_balance ))" - [[ "$lnd1_diff" == "$btc_amount" ]] || exit 1 -} - -@test "ln-send: lightning settled - lnInvoicePaymentSend from btc, no fee probe" { - token_name="$ALICE_TOKEN_NAME" - btc_wallet_name="$token_name.btc_wallet_id" - - initial_lnd1_balance=$(lnd_cli channelbalance | jq -r '.balance') - - invoice_response="$(lnd_outside_cli addinvoice --amt $btc_amount)" - payment_request="$(echo $invoice_response | jq -r '.payment_request')" - payment_hash=$(echo $invoice_response | jq -r '.r_hash') - [[ "${payment_request}" != "null" ]] || exit 1 - - variables=$( - jq -n \ - --arg wallet_id "$(read_value $btc_wallet_name)" \ - --arg payment_request "$payment_request" \ - '{input: {walletId: $wallet_id, paymentRequest: $payment_request}}' - ) - - exec_graphql "$token_name" 'ln-invoice-payment-send' "$variables" - send_status="$(graphql_output '.data.lnInvoicePaymentSend.status')" - [[ "${send_status}" = "SUCCESS" ]] || exit 1 - - # Check for settled - retry 15 1 check_for_ln_initiated_settled "$token_name" "$payment_hash" - - final_lnd1_balance=$(lnd_cli channelbalance | jq -r '.balance') - lnd1_diff="$(( $initial_lnd1_balance - $final_lnd1_balance ))" - [[ "$lnd1_diff" == "$btc_amount" ]] || exit 1 -} - -@test "ln-send: lightning settled - lnInvoicePaymentSend from usd" { - token_name="$ALICE_TOKEN_NAME" - usd_wallet_name="$token_name.usd_wallet_id" - - initial_lnd1_balance=$(lnd_cli channelbalance | jq -r '.balance') - - invoice_response="$(lnd_outside_cli addinvoice --amt $btc_amount)" - payment_request="$(echo $invoice_response | jq -r '.payment_request')" - payment_hash=$(echo $invoice_response | jq -r '.r_hash') - [[ "${payment_request}" != "null" ]] || exit 1 - - variables=$( - jq -n \ - --arg wallet_id "$(read_value $usd_wallet_name)" \ - --arg payment_request "$payment_request" \ - '{input: {walletId: $wallet_id, paymentRequest: $payment_request}}' - ) - - exec_graphql "$token_name" 'ln-usd-invoice-fee-probe' "$variables" - fee_amount="$(graphql_output '.data.lnUsdInvoiceFeeProbe.amount')" - [[ "${fee_amount}" = "0" ]] || exit 1 - - exec_graphql "$token_name" 'ln-invoice-payment-send' "$variables" - send_status="$(graphql_output '.data.lnInvoicePaymentSend.status')" - [[ "${send_status}" = "SUCCESS" ]] || exit 1 - - # Check for settled - retry 15 1 check_for_ln_initiated_settled "$token_name" "$payment_hash" - - final_lnd1_balance=$(lnd_cli channelbalance | jq -r '.balance') - lnd1_diff="$(( $initial_lnd1_balance - $final_lnd1_balance ))" - [[ "$lnd1_diff" == "$btc_amount" ]] || exit 1 -} - -@test "ln-send: lightning settled - lnInvoicePaymentSend from usd, no fee probe" { - token_name="$ALICE_TOKEN_NAME" - usd_wallet_name="$token_name.usd_wallet_id" - - initial_lnd1_balance=$(lnd_cli channelbalance | jq -r '.balance') - - invoice_response="$(lnd_outside_cli addinvoice --amt $btc_amount)" - payment_request="$(echo $invoice_response | jq -r '.payment_request')" - payment_hash=$(echo $invoice_response | jq -r '.r_hash') - [[ "${payment_request}" != "null" ]] || exit 1 - - variables=$( - jq -n \ - --arg wallet_id "$(read_value $usd_wallet_name)" \ - --arg payment_request "$payment_request" \ - '{input: {walletId: $wallet_id, paymentRequest: $payment_request}}' - ) - - exec_graphql "$token_name" 'ln-invoice-payment-send' "$variables" - send_status="$(graphql_output '.data.lnInvoicePaymentSend.status')" - [[ "${send_status}" = "SUCCESS" ]] || exit 1 - - # Check for settled - retry 15 1 check_for_ln_initiated_settled "$token_name" "$payment_hash" - - final_lnd1_balance=$(lnd_cli channelbalance | jq -r '.balance') - lnd1_diff="$(( $initial_lnd1_balance - $final_lnd1_balance ))" - [[ "$lnd1_diff" == "$btc_amount" ]] || exit 1 -} - -@test "ln-send: lightning settled - lnNoAmountInvoicePaymentSend" { - token_name="$ALICE_TOKEN_NAME" - btc_wallet_name="$token_name.btc_wallet_id" - - initial_lnd1_balance=$(lnd_cli channelbalance | jq -r '.balance') - - invoice_response="$(lnd_outside_cli addinvoice)" - payment_request="$(echo $invoice_response | jq -r '.payment_request')" - payment_hash=$(echo $invoice_response | jq -r '.r_hash') - [[ "${payment_request}" != "null" ]] || exit 1 - - variables=$( - jq -n \ - --arg wallet_id "$(read_value $btc_wallet_name)" \ - --arg payment_request "$payment_request" \ - --arg amount $btc_amount \ - '{input: {walletId: $wallet_id, paymentRequest: $payment_request, amount: $amount}}' - ) - - exec_graphql "$token_name" 'ln-no-amount-invoice-fee-probe' "$variables" - fee_amount="$(graphql_output '.data.lnNoAmountInvoiceFeeProbe.amount')" - [[ "${fee_amount}" = "0" ]] || exit 1 - - exec_graphql "$token_name" 'ln-no-amount-invoice-payment-send' "$variables" - send_status="$(graphql_output '.data.lnNoAmountInvoicePaymentSend.status')" - [[ "${send_status}" = "SUCCESS" ]] || exit 1 - - # Check for settled - retry 15 1 check_for_ln_initiated_settled "$token_name" "$payment_hash" - - final_lnd1_balance=$(lnd_cli channelbalance | jq -r '.balance') - lnd1_diff="$(( $initial_lnd1_balance - $final_lnd1_balance ))" - [[ "$lnd1_diff" == "$btc_amount" ]] || exit 1 -} - -@test "ln-send: lightning settled - lnNoAmountInvoicePaymentSend, no fee probe" { - token_name="$ALICE_TOKEN_NAME" - btc_wallet_name="$token_name.btc_wallet_id" - - initial_lnd1_balance=$(lnd_cli channelbalance | jq -r '.balance') - - invoice_response="$(lnd_outside_cli addinvoice)" - payment_request="$(echo $invoice_response | jq -r '.payment_request')" - payment_hash=$(echo $invoice_response | jq -r '.r_hash') - [[ "${payment_request}" != "null" ]] || exit 1 - - variables=$( - jq -n \ - --arg wallet_id "$(read_value $btc_wallet_name)" \ - --arg payment_request "$payment_request" \ - --arg amount $btc_amount \ - '{input: {walletId: $wallet_id, paymentRequest: $payment_request, amount: $amount}}' - ) - - exec_graphql "$token_name" 'ln-no-amount-invoice-payment-send' "$variables" - send_status="$(graphql_output '.data.lnNoAmountInvoicePaymentSend.status')" - [[ "${send_status}" = "SUCCESS" ]] || exit 1 - - # Check for settled - retry 15 1 check_for_ln_initiated_settled "$token_name" "$payment_hash" - - final_lnd1_balance=$(lnd_cli channelbalance | jq -r '.balance') - lnd1_diff="$(( $initial_lnd1_balance - $final_lnd1_balance ))" - [[ "$lnd1_diff" == "$btc_amount" ]] || exit 1 -} - -@test "ln-send: lightning settled - lnNoAmountUsdInvoicePaymentSend" { - token_name="$ALICE_TOKEN_NAME" - usd_wallet_name="$token_name.usd_wallet_id" - - initial_balance="$(balance_for_wallet $token_name 'USD')" - initial_lnd1_balance=$(lnd_cli channelbalance | jq -r '.balance') - - invoice_response="$(lnd_outside_cli addinvoice)" - payment_request="$(echo $invoice_response | jq -r '.payment_request')" - payment_hash=$(echo $invoice_response | jq -r '.r_hash') - [[ "${payment_request}" != "null" ]] || exit 1 - - variables=$( - jq -n \ - --arg wallet_id "$(read_value $usd_wallet_name)" \ - --arg payment_request "$payment_request" \ - --arg amount $usd_amount \ - '{input: {walletId: $wallet_id, paymentRequest: $payment_request, amount: $amount}}' - ) - - exec_graphql "$token_name" 'ln-no-amount-usd-invoice-fee-probe' "$variables" - fee_amount="$(graphql_output '.data.lnNoAmountUsdInvoiceFeeProbe.amount')" - [[ "${fee_amount}" = "0" ]] || exit 1 - - exec_graphql "$token_name" 'ln-no-amount-usd-invoice-payment-send' "$variables" - send_status="$(graphql_output '.data.lnNoAmountUsdInvoicePaymentSend.status')" - [[ "${send_status}" = "SUCCESS" ]] || exit 1 - - # Check for settled - retry 15 1 check_for_ln_initiated_settled "$token_name" "$payment_hash" - - final_balance="$(balance_for_wallet $token_name 'USD')" - wallet_diff="$(( $initial_balance - $final_balance ))" - [[ "$wallet_diff" == "$usd_amount" ]] || exit 1 - - final_lnd1_balance=$(lnd_cli channelbalance | jq -r '.balance') - lnd1_diff="$(( $initial_lnd1_balance - $final_lnd1_balance ))" - [[ "$lnd1_diff" -gt "0" ]] || exit 1 -} - -@test "ln-send: lightning settled - lnNoAmountUsdInvoicePaymentSend, no fee probe" { - token_name="$ALICE_TOKEN_NAME" - usd_wallet_name="$token_name.usd_wallet_id" - - initial_balance="$(balance_for_wallet $token_name 'USD')" - initial_lnd1_balance=$(lnd_cli channelbalance | jq -r '.balance') - - invoice_response="$(lnd_outside_cli addinvoice)" - payment_request="$(echo $invoice_response | jq -r '.payment_request')" - payment_hash=$(echo $invoice_response | jq -r '.r_hash') - [[ "${payment_request}" != "null" ]] || exit 1 - - variables=$( - jq -n \ - --arg wallet_id "$(read_value $usd_wallet_name)" \ - --arg payment_request "$payment_request" \ - --arg amount $usd_amount \ - '{input: {walletId: $wallet_id, paymentRequest: $payment_request, amount: $amount}}' - ) - - exec_graphql "$token_name" 'ln-no-amount-usd-invoice-payment-send' "$variables" - send_status="$(graphql_output '.data.lnNoAmountUsdInvoicePaymentSend.status')" - [[ "${send_status}" = "SUCCESS" ]] || exit 1 - - # Check for settled - retry 15 1 check_for_ln_initiated_settled "$token_name" "$payment_hash" - - final_balance="$(balance_for_wallet $token_name 'USD')" - wallet_diff="$(( $initial_balance - $final_balance ))" - [[ "$wallet_diff" == "$usd_amount" ]] || exit 1 - - final_lnd1_balance=$(lnd_cli channelbalance | jq -r '.balance') - lnd1_diff="$(( $initial_lnd1_balance - $final_lnd1_balance ))" - [[ "$lnd1_diff" -gt "0" ]] || exit 1 -} - -@test "ln-send: intraledger settled - lnInvoicePaymentSend from btc to btc, with contacts check" { - token_name="$ALICE_TOKEN_NAME" - btc_wallet_name="$token_name.btc_wallet_id" - - recipient_token_name="user_$RANDOM" - recipient_phone="$(random_phone)" - login_user \ - "$recipient_token_name" \ - "$recipient_phone" \ - "$CODE" - user_update_username "$recipient_token_name" - btc_recipient_wallet_name="$recipient_token_name.btc_wallet_id" - - initial_balance="$(balance_for_wallet $token_name 'BTC')" - initial_lnd1_balance=$(lnd_cli channelbalance | jq -r '.balance') - - # Check is not contact before send - run is_contact "$token_name" "$recipient_token_name" - [[ "$status" -ne "0" ]] || exit 1 - run is_contact "$recipient_token_name" "$token_name" - [[ "$status" -ne "0" ]] || exit 1 - - variables=$( - jq -n \ - --arg wallet_id "$(read_value $btc_recipient_wallet_name)" \ - --arg amount "$btc_amount" \ - '{input: {walletId: $wallet_id, amount: $amount}}' - ) - exec_graphql "$recipient_token_name" 'ln-invoice-create' "$variables" - invoice="$(graphql_output '.data.lnInvoiceCreate.invoice')" - - payment_request="$(echo $invoice | jq -r '.paymentRequest')" - [[ "${payment_request}" != "null" ]] || exit 1 - payment_hash="$(echo $invoice | jq -r '.paymentHash')" - [[ "${payment_hash}" != "null" ]] || exit 1 - - variables=$( - jq -n \ - --arg wallet_id "$(read_value $btc_wallet_name)" \ - --arg payment_request "$payment_request" \ - '{input: {walletId: $wallet_id, paymentRequest: $payment_request}}' - ) - - exec_graphql "$token_name" 'ln-invoice-payment-send' "$variables" - send_status="$(graphql_output '.data.lnInvoicePaymentSend.status')" - [[ "${send_status}" = "SUCCESS" ]] || exit 1 - - # Check for settled - retry 15 1 check_for_ln_initiated_settled "$token_name" "$payment_hash" - check_for_ln_initiated_settled "$recipient_token_name" "$payment_hash" - - final_balance="$(balance_for_wallet $token_name 'BTC')" - wallet_diff="$(( $initial_balance - $final_balance ))" - [[ "$wallet_diff" == "$btc_amount" ]] || exit 1 - - final_lnd1_balance=$(lnd_cli channelbalance | jq -r '.balance') - lnd1_diff="$(( $initial_lnd1_balance - $final_lnd1_balance ))" - [[ "$lnd1_diff" == "0" ]] || exit 1 - - # Check is contact after send - run is_contact "$token_name" "$recipient_token_name" - [[ "$status" == "0" ]] || exit 1 - run is_contact "$recipient_token_name" "$token_name" - [[ "$status" == "0" ]] || exit 1 -} - -@test "ln-send: intraledger settled - lnInvoicePaymentSend from usd to btc" { - token_name="$ALICE_TOKEN_NAME" - usd_wallet_name="$token_name.usd_wallet_id" - - recipient_token_name="$BOB_TOKEN_NAME" - btc_recipient_wallet_name="$recipient_token_name.btc_wallet_id" - - initial_recipient_balance="$(balance_for_wallet $recipient_token_name 'BTC')" - initial_lnd1_balance=$(lnd_cli channelbalance | jq -r '.balance') - - variables=$( - jq -n \ - --arg wallet_id "$(read_value $btc_recipient_wallet_name)" \ - --arg amount "$btc_amount" \ - '{input: {walletId: $wallet_id, amount: $amount}}' - ) - exec_graphql "$recipient_token_name" 'ln-invoice-create' "$variables" - invoice="$(graphql_output '.data.lnInvoiceCreate.invoice')" - - payment_request="$(echo $invoice | jq -r '.paymentRequest')" - [[ "${payment_request}" != "null" ]] || exit 1 - payment_hash="$(echo $invoice | jq -r '.paymentHash')" - [[ "${payment_hash}" != "null" ]] || exit 1 - - variables=$( - jq -n \ - --arg wallet_id "$(read_value $usd_wallet_name)" \ - --arg payment_request "$payment_request" \ - '{input: {walletId: $wallet_id, paymentRequest: $payment_request}}' - ) - - exec_graphql "$token_name" 'ln-usd-invoice-fee-probe' "$variables" - fee_amount="$(graphql_output '.data.lnUsdInvoiceFeeProbe.amount')" - [[ "${fee_amount}" = "0" ]] || exit 1 - - exec_graphql "$token_name" 'ln-invoice-payment-send' "$variables" - send_status="$(graphql_output '.data.lnInvoicePaymentSend.status')" - [[ "${send_status}" = "SUCCESS" ]] || exit 1 - - # Check for settled - retry 15 1 check_for_ln_initiated_settled "$token_name" "$payment_hash" - check_for_ln_initiated_settled "$recipient_token_name" "$payment_hash" - - final_recipient_balance="$(balance_for_wallet $recipient_token_name 'BTC')" - recipient_wallet_diff="$(( $final_recipient_balance - $initial_recipient_balance ))" - [[ "$recipient_wallet_diff" == "$btc_amount" ]] || exit 1 - - final_lnd1_balance=$(lnd_cli channelbalance | jq -r '.balance') - lnd1_diff="$(( $initial_lnd1_balance - $final_lnd1_balance ))" - [[ "$lnd1_diff" == "0" ]] || exit 1 -} - -@test "ln-send: intraledger settled - lnNoAmountInvoicePaymentSend from btc to usd" { - token_name="$ALICE_TOKEN_NAME" - btc_wallet_name="$token_name.btc_wallet_id" - - recipient_token_name="$BOB_TOKEN_NAME" - usd_recipient_wallet_name="$recipient_token_name.usd_wallet_id" - - initial_balance="$(balance_for_wallet $token_name 'BTC')" - initial_lnd1_balance=$(lnd_cli channelbalance | jq -r '.balance') - - variables=$( - jq -n \ - --arg wallet_id "$(read_value $usd_recipient_wallet_name)" \ - '{input: {walletId: $wallet_id}}' - ) - exec_graphql "$recipient_token_name" 'ln-no-amount-invoice-create' "$variables" - invoice="$(graphql_output '.data.lnNoAmountInvoiceCreate.invoice')" - - payment_request="$(echo $invoice | jq -r '.paymentRequest')" - [[ "${payment_request}" != "null" ]] || exit 1 - payment_hash="$(echo $invoice | jq -r '.paymentHash')" - [[ "${payment_hash}" != "null" ]] || exit 1 - - variables=$( - jq -n \ - --arg wallet_id "$(read_value $btc_wallet_name)" \ - --arg payment_request "$payment_request" \ - --arg amount $btc_amount \ - '{input: {walletId: $wallet_id, paymentRequest: $payment_request, amount: $amount}}' - ) - - exec_graphql "$token_name" 'ln-no-amount-invoice-payment-send' "$variables" - send_status="$(graphql_output '.data.lnNoAmountInvoicePaymentSend.status')" - [[ "${send_status}" = "SUCCESS" ]] || exit 1 - - # Check for settled - retry 15 1 check_for_ln_initiated_settled "$token_name" "$payment_hash" - check_for_ln_initiated_settled "$recipient_token_name" "$payment_hash" - - final_balance="$(balance_for_wallet $token_name 'BTC')" - wallet_diff="$(( $initial_balance - $final_balance ))" - [[ "$wallet_diff" == "$btc_amount" ]] || exit 1 - - final_lnd1_balance=$(lnd_cli channelbalance | jq -r '.balance') - lnd1_diff="$(( $initial_lnd1_balance - $final_lnd1_balance ))" - [[ "$lnd1_diff" == "0" ]] || exit 1 -} - -@test "ln-send: intraledger settled - lnNoAmountUsdInvoicePaymentSend from usd to usd" { - token_name="$ALICE_TOKEN_NAME" - usd_wallet_name="$token_name.usd_wallet_id" - - recipient_token_name="$BOB_TOKEN_NAME" - usd_recipient_wallet_name="$recipient_token_name.usd_wallet_id" - - initial_balance="$(balance_for_wallet $token_name 'USD')" - initial_lnd1_balance=$(lnd_cli channelbalance | jq -r '.balance') - - variables=$( - jq -n \ - --arg wallet_id "$(read_value $usd_recipient_wallet_name)" \ - '{input: {walletId: $wallet_id}}' - ) - exec_graphql "$recipient_token_name" 'ln-no-amount-invoice-create' "$variables" - invoice="$(graphql_output '.data.lnNoAmountInvoiceCreate.invoice')" - - payment_request="$(echo $invoice | jq -r '.paymentRequest')" - [[ "${payment_request}" != "null" ]] || exit 1 - payment_hash="$(echo $invoice | jq -r '.paymentHash')" - [[ "${payment_hash}" != "null" ]] || exit 1 - - variables=$( - jq -n \ - --arg wallet_id "$(read_value $usd_wallet_name)" \ - --arg payment_request "$payment_request" \ - --arg amount $usd_amount \ - '{input: {walletId: $wallet_id, paymentRequest: $payment_request, amount: $amount}}' - ) - - exec_graphql "$token_name" 'ln-no-amount-usd-invoice-payment-send' "$variables" - send_status="$(graphql_output '.data.lnNoAmountUsdInvoicePaymentSend.status')" - [[ "${send_status}" = "SUCCESS" ]] || exit 1 - - # Check for settled - retry 15 1 check_for_ln_initiated_settled "$token_name" "$payment_hash" - check_for_ln_initiated_settled "$recipient_token_name" "$payment_hash" - - final_balance="$(balance_for_wallet $token_name 'USD')" - wallet_diff="$(( $initial_balance - $final_balance ))" - [[ "$wallet_diff" == "$usd_amount" ]] || exit 1 - - final_lnd1_balance=$(lnd_cli channelbalance | jq -r '.balance') - lnd1_diff="$(( $initial_lnd1_balance - $final_lnd1_balance ))" - [[ "$lnd1_diff" == "0" ]] || exit 1 -} - -@test "ln-send: ln settled - settle failed and then successful payment" { - token_name="$ALICE_TOKEN_NAME" - btc_wallet_name="$token_name.btc_wallet_id" - - threshold_amount=150000 - invoice_response="$(lnd_outside_2_cli addinvoice --amt $threshold_amount)" - payment_request="$(echo $invoice_response | jq -r '.payment_request')" - payment_hash=$(echo $invoice_response | jq -r '.r_hash') - [[ "${payment_request}" != "null" ]] || exit 1 - - check_num_txns() { - expected_num="$1" - - num_txns="$(num_txns_for_hash "$token_name" "$payment_hash")" - [[ "$num_txns" == "$expected_num" ]] || exit 1 - } - - # Rebalance last hop so payment will fail - rebalance_channel lnd_outside_cli lnd_outside_2_cli "$(( $threshold_amount - 1 ))" - - # Try payment and check for fail - initial_balance="$(balance_for_wallet $token_name 'BTC')" - - variables=$( - jq -n \ - --arg wallet_id "$(read_value $btc_wallet_name)" \ - --arg payment_request "$payment_request" \ - '{input: {walletId: $wallet_id, paymentRequest: $payment_request}}' - ) - exec_graphql "$token_name" 'ln-invoice-payment-send' "$variables" - send_status="$(graphql_output '.data.lnInvoicePaymentSend.status')" - error_msg="$(graphql_output '.data.lnInvoicePaymentSend.errors[0].message')" - [[ "${send_status}" = "FAILURE" ]] || exit 1 - [[ "${error_msg}" == "Unable to find a route for payment." ]] || exit 1 - - # Check for txns - retry 15 1 check_num_txns "2" - balance_after_fail="$(balance_for_wallet $token_name 'BTC')" - [[ "$initial_balance" == "$balance_after_fail" ]] || exit 1 - - # Rebalance last hop so same payment will succeed - rebalance_channel lnd_outside_cli lnd_outside_2_cli "$(( $threshold_amount * 2 ))" - lnd_cli resetmc - - # Retry payment and check for success - exec_graphql "$token_name" 'ln-invoice-fee-probe' "$variables" - num_errors="$(graphql_output '.data.lnInvoiceFeeProbe.errors | length')" - fee_amount="$(graphql_output '.data.lnInvoiceFeeProbe.amount')" - [[ "$num_errors" == "0" ]] || exit 1 - [[ "${fee_amount}" -gt "0" ]] || exit 1 - - exec_graphql "$token_name" 'ln-invoice-payment-send' "$variables" - send_status="$(graphql_output '.data.lnInvoicePaymentSend.status')" - [[ "${send_status}" = "SUCCESS" ]] || exit 1 - - # Check for txns - retry 15 1 check_num_txns "3" - balance_after_success="$(balance_for_wallet $token_name 'BTC')" - [[ "$balance_after_success" -lt "$initial_balance" ]] || exit 1 -} - -@test "ln-send: ln settled - settle failed and then pending-to-failed payment" { - skip "missing xxd dep, failing on concourse" - - token_name="$ALICE_TOKEN_NAME" - btc_wallet_name="$token_name.btc_wallet_id" - - threshold_amount=150000 - secret=$(xxd -l 32 -p /dev/urandom) - payment_hash=$(echo -n $secret | xxd -r -p | sha256sum | cut -d ' ' -f1) - invoice_response="$(lnd_outside_2_cli addholdinvoice $payment_hash --amt $threshold_amount)" - payment_request="$(echo $invoice_response | jq -r '.payment_request')" - [[ "${payment_request}" != "null" ]] || exit 1 - - check_num_txns() { - expected_num="$1" - - num_txns="$(num_txns_for_hash "$token_name" "$payment_hash")" - [[ "$num_txns" == "$expected_num" ]] || exit 1 - } - - # Rebalance last hop so payment will fail - rebalance_channel lnd_outside_cli lnd_outside_2_cli "$(( $threshold_amount - 1 ))" - - # Try payment and check for fail - initial_balance="$(balance_for_wallet $token_name 'BTC')" - - variables=$( - jq -n \ - --arg wallet_id "$(read_value $btc_wallet_name)" \ - --arg payment_request "$payment_request" \ - '{input: {walletId: $wallet_id, paymentRequest: $payment_request}}' - ) - exec_graphql "$token_name" 'ln-invoice-payment-send' "$variables" - send_status="$(graphql_output '.data.lnInvoicePaymentSend.status')" - error_msg="$(graphql_output '.data.lnInvoicePaymentSend.errors[0].message')" - [[ "${send_status}" = "FAILURE" ]] || exit 1 - [[ "${error_msg}" == "Unable to find a route for payment." ]] || exit 1 - - # Check for txns - retry 15 1 check_num_txns "2" - balance_after_fail="$(balance_for_wallet $token_name 'BTC')" - [[ "$initial_balance" == "$balance_after_fail" ]] || exit 1 - - # Rebalance last hop so same payment will succeed - rebalance_channel lnd_outside_cli lnd_outside_2_cli "$(( $threshold_amount * 2 ))" - lnd_cli resetmc - - # Retry payment and check for pending - exec_graphql "$token_name" 'ln-invoice-payment-send' "$variables" - send_status="$(graphql_output '.data.lnInvoicePaymentSend.status')" - [[ "${send_status}" = "PENDING" ]] || exit 1 - - # Check for txns - retry 15 1 check_num_txns "3" - check_for_ln_initiated_pending "$token_name" "$payment_hash" "10" \ - || exit 1 - balance_while_pending="$(balance_for_wallet $token_name 'BTC')" - [[ "$balance_while_pending" -lt "$initial_balance" ]] || exit 1 - - # Cancel hodl invoice - lnd_outside_2_cli cancelinvoice "$payment_hash" - - retry 15 1 check_num_txns "4" - balance_after_pending_failed="$(balance_for_wallet $token_name 'BTC')" - [[ "$balance_after_pending_failed" == "$initial_balance" ]] || exit 1 - - run check_for_ln_initiated_pending "$token_name" "$payment_hash" "10" - [[ "$status" -ne 0 ]] || exit 1 -} - -@test "ln-send: ln settled - pending-to-failed usd payment" { - skip "missing xxd dep, failing on concourse" - - token_name="$ALICE_TOKEN_NAME" - btc_wallet_name="$token_name.btc_wallet_id" - usd_wallet_name="$token_name.usd_wallet_id" - - threshold_amount=150000 - secret=$(xxd -l 32 -p /dev/urandom) - payment_hash=$(echo -n $secret | xxd -r -p | sha256sum | cut -d ' ' -f1) - invoice_response="$(lnd_outside_2_cli addholdinvoice $payment_hash --amt $threshold_amount)" - payment_request="$(echo $invoice_response | jq -r '.payment_request')" - [[ "${payment_request}" != "null" ]] || exit 1 - - check_num_txns() { - expected_num="$1" - - num_txns="$(num_txns_for_hash "$token_name" "$payment_hash")" - [[ "$num_txns" == "$expected_num" ]] || exit 1 - } - - initial_btc_balance="$(balance_for_wallet $token_name 'BTC')" - initial_usd_balance="$(balance_for_wallet $token_name 'USD')" - - # Rebalance last hop so payment will succeed - rebalance_channel lnd_outside_cli lnd_outside_2_cli "$(( $threshold_amount * 2 ))" - lnd_cli resetmc - - # Try payment and check for pending - variables=$( - jq -n \ - --arg wallet_id "$(read_value $usd_wallet_name)" \ - --arg payment_request "$payment_request" \ - '{input: {walletId: $wallet_id, paymentRequest: $payment_request}}' - ) - exec_graphql "$token_name" 'ln-invoice-payment-send' "$variables" - send_status="$(graphql_output '.data.lnInvoicePaymentSend.status')" - [[ "${send_status}" = "PENDING" ]] || exit 1 - - # Check for txns - retry 15 1 check_num_txns "1" - check_for_ln_initiated_pending "$token_name" "$payment_hash" "10" \ - || exit 1 - btc_balance_while_pending="$(balance_for_wallet $token_name 'BTC')" - usd_balance_while_pending="$(balance_for_wallet $token_name 'USD')" - [[ "$btc_balance_while_pending" == "$initial_btc_balance" ]] || exit 1 - [[ "$usd_balance_while_pending" -lt "$initial_usd_balance" ]] || exit 1 - - # Cancel hodl invoice - lnd_outside_2_cli cancelinvoice "$payment_hash" - - retry 15 1 check_num_txns "2" - btc_balance_after_pending_failed="$(balance_for_wallet $token_name 'BTC')" - usd_balance_after_pending_failed="$(balance_for_wallet $token_name 'USD')" - [[ "$btc_balance_after_pending_failed" -gt "$btc_balance_while_pending" ]] || exit 1 - [[ "$usd_balance_after_pending_failed" == "$usd_balance_while_pending" ]] || exit 1 - - run check_for_ln_initiated_pending "$token_name" "$payment_hash" "10" - [[ "$status" -ne 0 ]] || exit 1 -} diff --git a/dev/Tiltfile b/dev/Tiltfile index fb99aca329..3b30d2cb18 100644 --- a/dev/Tiltfile +++ b/dev/Tiltfile @@ -317,6 +317,9 @@ docker_groups = { ], "bitcoin": [ "lnd1", + "lnd2", + "lnd-outside-1", + "lnd-outside-2", "bria", "bria-pg", "bitcoind", diff --git a/dev/config/lnd/regtest/lnd-outside-1.admin.macaroon b/dev/config/lnd/regtest/lnd-outside-1.admin.macaroon new file mode 100644 index 0000000000000000000000000000000000000000..246395ba4bbfb49b11049c46e44d975ba28d35f6 GIT binary patch literal 293 zcmZQ#WX{P;Vfw+y%q39azq4Ax`2Am&BbvYE7jRAyVl9T=3>drOUp+U6zAf|%qz>!Oio2pt;ofZo0yzfl%Jm`#F3twms*rql8UMq zXi+ZEmc(>4aiE#`X=%wBiJ5sA8uIh7h>LKs7Nn*Yp}9bUi>){_9cVGS{R|9j3i`W3 jeje)EzUJ7;l)I6c4JwX)nMJih%tWK}{AE%}OkUY&h4PQx+CC8y4SRo%@?}=AJWWKD*z!SJMI!BJ+bU`XN~V92*!g z$#IoFWQ59rXqh|HJkHnTvKnW}{Qx_(l$?iN>{ z+da_LHq;0r$*ZH=2dTBN5)M2rCa(o4|#Z%O5lhVm2Mb@eTo6D20R#|0009ILKmY**5HKvD-uwTl{6Fm=_0*1l@3EMf`EWD0i_p_D!oWY5Ks_7iZtm>5CuVyCPk1URZx%) zB2{{qA|T40pyPig?|bk0zPr}9&N=JNZ>`MElf9Eno(W;^WG6vG`yE(+(zP+dH4I>! z^!EhJKhqJ(@t;urGXeik%KVIcz?zwC4N(qCAp?*B$N*#jG5{HX3_u1T1CRm80Av6% z02%l{#{l}Duk!!5{eSAu{J|kJJ3*cph|>c9=WHPKO&|l10muMk05Sj>fDAweAOnyA z$N*#jG5{GsJGs^m_ke-+`wReZK0p>e0Mrb>_z&S1k=Emg^R=na0ceagAYI$!5Igh z0`mZ&^QU~$Z$z8X}hu83i97&^m zI*D~)psCLJ+Y56$))7Iy_HZ6v_@N^vH@1wb?$-Vc>p)X`h z|ExE2Bs-xf?vxib&F^I6X6a^a?qO}E$%$vUUR;JK0(R7JhsUHl=;C-6tG2 zA&u`C|5gBpWqcvoTET%keM7a#ukB|%A%_i1-21`iTc6SG#7ec@G⪻s?Sp7okbJE zyu!Vs9#GrS?m71%C8sjzbwlXdJEnMIQwkV6U)cu3aFtYZN%jPBAJeqI{sr}#B(?Ts zwZ&32n+YxPd5(09pT0J^S-EaR9B;GEVT8=#ug;WkInpjhzM~L3SIG4G zLjA{4tkG`c=76)6ay4D`zB(G`>%$WoZ*)whP(J(4S-(lNn#7|U>;#CbS}{qpJeb9O z>SfPYR~m$lhPR&~AQR{L&iC1jX%o)=BBw0gpSq?}=LQ1Xu-pTTTKvH;Bv%AeI5KI1=-~$A1Ux zPl|=9gBZio`!j}va{&J{1~vx^%iY)cWS9Pvg_2;L96EkaGJ_|;fq)r40O0{2fNzPA z127SMKzxG?_&5c8Ky1}h_&9K2VuuevG{XmAUJd}@fy3&obefjH@O=rH*`*cZ299@{ zlBPmjOzmY=7q-G;Ni6K#JZ!DZeSxx;7@-;nws3T@boj3<04Q@sWo`^*M)+T`-Ay}d zD>QU>4|6w<|MJ2BYt~jCF8`GkkIkuE0m?xE8GsBx1|S2F0muMk05b4@kpXyp`6Mv@ zRA_<9Gc$Yus<4RmK2Vhf+S&knn_F4A!JCPQ>MwlKNqBqsz^DGxzDG=lQpf;g05Sj> zfDAweAOnyA$N*#jG5{HX3_u3{_Zt8%eF1@Sa`pT7#j_YV1JkSECj)@<0aEbBK5%XP z27CZG9?k?v3_LIZD9;QZfP8fLNd+JuU?Aw>44gkeT#GM&GjJ^)V4%DRd}d(&i+|V_ z4#4`D;e)xQC2$4q-v;8G1(3-MAAn_O01Jc%&=&ztewb@18poIj$)-;x_J!QT9Jh+W(y&asoD`0n0S zu3hZzi_>4t7KCB`7pv&EZIbkZtLjn{N>CQsiLSw1T7@p0vM3g_Hx2aUq$mU1d!O;~m$t6ctoXvC`jk*EpSj zxhn{;EXq)q-DAVyve4u2dFe5SscM4FB8uzNC7ePN)cp+mY0Vp310q9;d)+U+$UE*n z+j97I0sqp)Y{AE3LLPeLZ{sU&p;wq?IXMU`vG?M;`$@$M#p9W5oiF`tF5r*j`_9Rb<>v$rr7SsXSboa2aqed%h;h%^xO=2b_1Uyz@2m+DK@P^6NFw2Ju_)_?lzFNMIq z#a+5;IoSIp>VnFGdcW_`)^eS~;hVjC7_DE8>BmXqVOLizFKnz5P}K!st8{s2C)h=5 zj=V4^>&cdyKDv}bEJ_Haz2t@BiiZ^R`P=Tb!~Nt z&K=RZv8s!{tHS-9mOK|0;#N6Wkvh z{Sj>Q%#Yu2)i`+8g*-W{ho}jX~!A-3{8pE6Hw4-ko%=vyRE3p&zOvillO_g@OCAr`mmYCU_ zBF?p>2WDZ-dhvH^Z+5mfWs<*=*p@rgnaR1%98UFE-TJ*<>fp4;Df)BRQ6&~eL?)Fd z?f(J1bnWFOQ#~uE?JM-G&+Nlqe5K$Q&Sl8Me&P3{j*%#kHU(Ew=1G1R*_I6#FSo9@ z3Onh;mYsZ`H65AS)|9nX;;)Rh7`efcYa!2GcKBZ$avwjk!4=O4&A(e@UxK;yyk-?M zGMjDy%cGE2ylm$di?C(FDx3OSS;=X&M_IWPwDh?Px?7zsq6dczOb6OtZ=MDFeCT)q zwg3O_cF+i905Sj>fDAweAOnyA$N*&EzheNnE)T?iO#45>X<@L1&k#Fh(6TW2*EIU< zJML?1<~!2&&znC=SQwU`N<0_;eOvzGh>nJfxCWEx#WP`TQSReOEEgL6f~`};(mjM# zdy-OqDxdRKP|opR%pSp#y!fIr#POkEzhX+|=G6=Cch*B0UR=%TlbZ{pxaGM-QAc9z zzAyOZTE?lg>GrN_Lhazh92^(M-x7$1|Y)zbC#Q>WRj&qT~AOX-NH- zo38%K?r-7^uC~>dnVf&iKqa1`9wr$e1Jm_d>|f?s98@^|xX@(;+apiA*Y(66t6Xh& zy@Thm{FjuFUrO3e=Vr(l%w2v2r|t&oQQ4&*$2t-lUtYsZi;q(xKsz0#a*LvK95+=- z`!0oK+kE8xAM~%J?{(D?2c5fWbF^oiH}E~pnNsXQ$P#q@|D-p=|Je0^gC4Jngvl|7 zn{VpGpC~yNwKpmJqA0JEeo=7W>*tfBB@*E%qLPn|TZ~W7t$lKE!x1H~GWijB zDdWKaUD~r#eaZ`$=JBN$RHHu;PZ?|%V=2L!op%)7+ngh@iVvMr)~c|RDP_9aXJ1c~ zZg|phg+0dD7dh=G>JlyWJkRqfc?4JLV2nWP!2(f|>7eU%cwNzMYfyKg0Ru?7PRV zKFh~#{@U!^+4WvEscwze%vqNu@9afOSt+xRYU19uscU|_!JHRCfBGv^rtIz4-Z)(a zk|tZy z%}rfR&TNT3>{r*>#~nr|7G#Tz=}p=3qY|>~8<@0A#^He(olhq%$03B;|0l<6=mRnU z8GsBx1|S2F0muMk05b63H2_@H1>!%Z{eKY9FG+xP@oO$^$SF4;eJR|W06gqEo?fi= zhiF=aYuMU*ll0q+Y)9xhrA?9|EN$$Tmlcw*I(F^`rw@6Z*-|f3!M-V9X|tbYO*zu} ztFo-Crd>|y8D8=vZ)%Q5!lkmpCD*lSlhc`xSZL5Nv?2zk+?Z}jFSEKu-@;f$`>{f2 zcjD^||v@%QZFa-H6QezHjJ| zJt1@B!hauc7%&B_fJ{1 z(1fkyJuKOmDO!|l?{82|E>lyv$fa+YNd3H{RNvXC)%|0*;Yncm-Mg2*Pfl(ny0UN9 zmmPVbkz;nxqIY=4Z&~lxWU-PnjuS@&s~%8>KNjmjyn2(EUQ56|C3`j^Z^-w3_u1T1CRm80Av6% z02%o28USvj1_A?3{`Uy{lNo+1H1H%p#2wO%Af^W~Er_W>ObKFg5R-wJ6vV_JCIm4) zi19#-17a)?V}KagaOCa(1%F-vG9Q8X5XAc+2Hu~5JpT@ezkzrY#Ookl1@SV77ePD^ z;;$f{fivPZX<#Rq2JsY#CqX;`;x8Z`2k~bRkAZj;#3LXc2JsMx2SGdl;(ieKf%p@M zdqLa-;*TKy0OD>CcY*jlh&w^t0pfNLw}H47#4R9x2V&qoAIQId6Nnp;80ar#Zs{Q@ zDxnA;Ly(w&5;DOqBa@&qG6|_5ldvi>iKroys5&x<0neKMyFPIZWRlQCB5?sNWP)8q zCc$gSB&3Z@!aB$#0`z-9tWR7Nc*Ve964OT}ao`;yfAb^^kw`+o2$^8U$RucjOhVU@ zN!S#bM1Uu+Al4uuYKBZ=z>^UE=80P%lY}Llfb)02F9s73utGtYH3|yeL_r}N6cn~a zK@mF?6tzb|F$WYBcSJ!6CuD>P0PlBb{}dJhp62im ziULo1_y@&2QBd3q1tq+ZQBVMQddJ^+1!2JZ8U8`R+bAgHhl0ZXC@69V1w{i;P%IDy z#e+~#;w~}@3EV?LSTG6-hM=I(eH0W9g(DP@0muMk05Sj>fDAwe{yg;$X#WFsnBVaV zUeQ5r50rqo7{o6@Tm<4m5WfI%0f_TK{2av3K%58Sry$M+aSn)|fH)h(Ss=~?aR!Lf zL7WESR1l|tI2puAAWj7FV-P2RI3C1tAdUrb42U0rI2y!JAdUoa1c)DkI2^=bAbtSi zP!Qh-aR`WmL3|IycR?Hk;y@4wfcOrG{Xy&p;@cqh1+fo^y+P~+VowlzfY=?xZXmt| zVpkBmfY=$tP9Sy!u>*+hL2L(NTM*lT_$G+0L2LzLOAuRt*c`-WAie=&QxIPVu?dKc zL2LwKLl7H)SRcfCAl3!34v4iud=11`L97L0O%Q8<_zH;CL97O1RS>IySQ*5ZL97H~ zMGz~1_!5ZaK`aMiSrA_Yu?&c%L3{zkQXrNDu>^?4K`aJhQ8*(%vGnBZj*!R$_D-_;tx?!A_5tO1tL)p7KMU>(I_bN2nB_Krw9N28p0y6C@30-f?~kK zW&SBFo`8Z9kC9PCAQ1&&K$p3{^NI*2qo7a<3JRy9phy}Dil(EW81RnIf0itsiGmVY z$S5k1je@WzC@7eNfWbSSJb! zzDGf!E)*2*MnRDeC@A_71;u($P`nofB|ae|OrQ@1Vf`p5IDmpegD5CGgn}Z&C@4CD zf?}g6C_aXQ5}%P#P+%MdVP8;CZ~_H|CQ(p$3I#=`QBZUS1;u7jQ2Z+jO3Wdnkia|& z!WK|aa1jNCmQYZ583jdFP*8Lg1;y4-P<$N)B{q;zSYQ(cVOuCD_zeYxwoy=c2L(lT zQBZUb1;xIjp!hxtN*o}gh`=EV!hWEj;1LQ6{X{|GUnnSY{0IL$s~k@M@*r1I0jG$vR^SW-|1DtdVU3vP=z%C&30{77#Omm;uCeAf^E^ z6^JQ7d35+y|@vD3&TPKHbpXOKuxfE<}% z6v!kSMBua}+VsywPPLE6y3`is-z=%vRCS($1MkXN^WD;gYCJ{Dd z5@kmwv9rh|eh!%=&Lfeq00%O`IFU(^3z>wtkx7^bnM8PzNt6$n#Q2d(TmYFQU`Qk) zAc#ybA!HI1MkXNv%{**U@Gf=e$<^e+IPx++Zh&J;lAHgmdzt?B*C%+EPz`O{?gKrbi zlz`8MW(mBOorl-(h8#(wd^(ABV4$ha`P&lyLaCXup_OZccB|xjv5dU~e8wz0_N`pFXh8ub8HWywsml*Z}ew4xk(xd@{g zc7-Cr{l*1TPkdn~$4$P3d#URAoGR)C{E}>qn-VLf;m40EjOg-Hl?gi)FSqW@^_=Rq zJB4TIZs}&{>hVOopDpV=sVC9B`U<}DjJn}Wb89iAWFcf<<~!?cS$}Y{a7|mE^V+l+ z>cZ1;kiU=SrY85^FNeO6E&a3J%#rMbqPSCD)HJ`7jhm&LHM|Rhl_n>)B_IYq1%CA( zaO`Aj1z7m;HQ1E)$#$P`*n~8`WBgkI9G3BgWNQTn?(_}SBEPnu@q`>UEOGA#n{Rza zw-YPXcGJ{ca;iQ{k#`nN2=fZ}j(R|CN4w|Thm@Skpw|tdYwwuiiA^bB?0jV#48v7Y z%_Z3r#C=TD{`wcxYm(I3m(>n}d+$qHpiTcYXO@o*yy(=ttV zy0P6C?l9fIp_)WU$#ib+%g!sST282OGu>|7z!>kIWCN3lk`jhh3`R?5|M)%)sboUad0XuQ!el|uRKJ7@hS z(P|QpZm<&|u4=_3&GKLt_oA`-_~ic#n4q^4(L} z#nGpH$e zqyDoZsu6;bg`A0ZOST<*)FjQ>d|nc*@Dd0vxSzwlvTJO9E{^c()jqSn*+*T7zZ%5f z5@Olj<{p-|F3yg=XzrFSuGa9s2$VRP$m?!tYwcu?l7R#mCx6txCuqSFU={FfISEzx zCo(I57--`l=L7911Osiq-vPAWfWX4k`8|S$g{Ajr3o5HQ0BAb_O;YXt@%00s^`>;S;S4L$&Q900%rht*l>G%bPQ`w}vTVZYGaniNu zf3>EuIh8BGGNFJBKn5TKkO9a5WB@V%8GsD@zZw88g8_l@rG_kpS| z(AEan8+gAtyqSnNZvdZk65bv@@TovW84Ab%WB@V%8GsBx1|S2F0muMk05Sj>fDAwe z{!cRibbJK@{p1dRG&BMDIB*>t=sF7o&^;6Rx;q=3fjpoL5Qu)bFhoCFQQ&Dtf1W`E z^qGVLG5{HX3_u1T1CRm80Av6%02zP`Kn5TKkb(d027p^#fdF^h1-is)0G$Eg5eH8J zR{z6&e|je)7(W(Vpb(6#}i8 z)?U0$yzu03Cd*Ex(U?baa&cP0!>=30mS2y4)KnuB_fpya;ZPYqqh2Vdk?9k;TX*E#I5XMxJW>)B$a3uF9ex0;rQO6#0 z@Y%IKSL=+mdPq}G40=lY`dp__nBo;(;H!PX*gx-+K|^cib7X!|K_l+Y8)ANwqm4C^ z`$6WnR`?=H61s7Qg4K6&|wFQr#mXYYBJNXa&KxYNTohd@|mo(v8L|-GHu!M za8OlfzlOYG$=S_iK4&<2Ueic=!%<73HqA!o++%{$ov*&dUp;8!XXu*(jcQD_&pk2k zk{)r|&bYUp*-}JXtwG{nr?1(Z^K$~;Rr_}U=T!bY&+_C)xctXx;a&~f%neG6lCxiR z8mDH`C6nfdMGw?xsZYf;q_5xIi!j{V&lAt}z4Cpx#65QG;>9hE8+t2ob%z2;lkzW| z^#mt(W>R8l7tbDZGe(t*$7L^z&x>bE>}Oxaa`nRI56k#9awkcW9lI--lgJ5hWU``B1u1z(3}rjW`5>VRU2-N z{=#{+l4p9_o$H+jKEt|jNIS#3-G%5WVzrGckJRWQKX?96r^E^KpB#2@cbGD|FPp6| znMl*a(2e)AEkob>@qOXwUM;RwIaqh`PU3BC4AxUm^pkHAn60Ia4|UT8Dyb>*afNAx zhP`)79OBZoTPlCH@DY}%I`3bw{9(ME$(0gql*FsF+&49&(fjbzXEy!#aiwF$Fx{dj7PsAB70#X#{v~&DwT5Z) zEDx3G0I8j&7$y-ZB^hy%L{Hc9p6OHASDCS_rzLEcjxbYPo^*}kp5vVv_yPEwsz~l< zi^J40D_aQFn&}s;gI!v1XuOarMrSiQyI`5HKbzqaor!%k`Get@rixQ0UNBRNg*kX zCUW&GGhP?HuCCV0!^am6oZQ`rW;6)gp*AD#c=aoJJ}@baIhIH6{OGo92-v6K$!!A& zpAi$Lw@Xi(Ib#KpOtG3jpTM=j*EBiJB7M8~Zmi%zzIkf2+Bcz087Z$6o7k?otYU)- zf76Ww!mRFa!7Fb^RP@nI7=EO&^e(C-g=oBY+{@viq9xyJ||C={d~R~>vl)J@;0 zf6b{_UiP*&y)|<0$9qdI2j6or-omDJFnZ1?d5wN9ifP+}U|AxBP!;W=9N_7m!>dZ+LARJXqqM=tY;7+s)YA)6eCx zBtXV~O00cSCujAGgQwktfUn<%JH`ym`x0<8@5(O@@TKBOJ_+>|F#6H=$<~6hvh+i9 z3f?m|j=*3!s+$CAnRo;51#1tlu3V32)tH7I)Hz|>hA?I`Enw?)dk%Hc-B%qhH^mCS z*2B*zPS~f_q^SWB@V%8GsBx1|S2Ff&X9wK%agf{$2YY(Y}v?H#U*m z^Sz+T{?=Zj3rokw8Qz(&O+M^c`1tg`HH>*o_j|${@3Gm;p$Dhp z-ukECW!{c_)UhYnnsa-y%j4ds@Wlx8chQ}aOBx@`Sno^YVjp`v;f(WBu*fP23=y{Q z@mA|uyw#W(_tGPrNvNONY^hA2zfLyO;HLeWc407o27wlv#i-)6s*P1y)am}~F9k0N zE6#8{8d@y$cdKsy$@N&Su^p(r`nBAYeS1i4S^dz}nEUq3T5Tz&RNzoZPAhMsJNl)I zVnK%G2NcIObe(~9eYA&$FIQn%^V?;~lRVL#ZB0el`wc7wKd)?mw;dTTo?;()B66;Y z!=<~xxA0EQ7#ERw_1wLCQH#8cRg!!$OX2Oe#c*2;tL7qJEO~zKxb><%^hVEn^#WB) zR)VUx@tw>)9t*vn6h00;NN5D?0fDH!iU8d#{`$nlODiX$S-yVJo$^bJmOVCi5F2e1 zZ_v+}ZEfs3j8PHPJafdSjxHxCCc7Sce5}Hjtz)vu47P3j&MGI{YVAw<&CTc+-%y#* z^~w@o*4Ga_1?gfMsxM5jW#gSe6QdCKVDB7A!r@Q*s-t|x11lO2>o|jDCe^U|p8G9% zmbb317~Z@-S?@&-$+LKP6X%` z_`av4uTf~|aL?1WI{xhX{M>OOakN3jP&>4P$s+?kK@1Ky50XjupYR5ucUuj{ zsYla7G;dmmTYo8(z;WzXys2CKELuR z>fGh>c}?=>yB=c$9{PQT<${X8?Lw;03G&35|8L4UK#|A}~aFJ4IN&zf2fzFS3$ z@fjNeuSJ?8@2urvm?bY6yK0R%*s9xJRQ8#{5glVV8qdHQRR?_XZ|8Mx)nB^PeR$S! zbY4QAjYH}|Y;uM)Rg2+7V`J^1;JsI2PX5;gjvPj*#GE2qXi1p*_sA=Sxd*8`>_h9$ zgbDi#vUuVh+I}L8o8;V;!x^q`rJRlNIHko|#rO-4a3kxRX;^{rI%Og0dUCkLbsLv7+T* zy*8QyT75sB6*O_WU{>*ZhRg>4_+M#!%Ws7GwTxo(IfL$fl(geDBzu?>PXqYe_qo#O z(asol>{gmpROMNJzj@1~mws8d#f+Z{mi>PDpr!pxYpH-kQenehiV0y64~VtG6rT>SqGE`<9eT z)S3;7BVONF8PqZx2tdC*J@}&G-Ox>*;FiO;Ya2!94Jx}Af9bx}pO~&$OFoea|3LT@ zKj~+MX#FeSjSZ^G@R<(0`tD^l$)<_Qel1DTix+d1Un8-}czzO^jq)kJOxk?TgkSw3 zkp!17{;9s{p5eFe`MlR6^F;0?g_Tkalw~ZiUAuGIx@L}?U9N%e?PzmdQU~#KyO6vX zfg4%+>gYP3HVd&!sIxZajL#Wr33OE+v%i_?`aZWz_FYQJnZo2FO|8fX2A;Ngw8JIE zZU+VpSHS1GTy?p><;C-k{K0CqFd=T^3$^VF4_dF$Q%Bhr3Lk!xIX%sTIZl9kiRy_6 z&VKc-@A*`^kcu9A&ev!Um*@o}D$WHlyl(nXq1o$hs~z8|Wz;RM<@LN@tnbc+v722% z{cTGHTbw%`cI@4XZA}^8I^o$rqjlUflijt%j0{A47&D&xNlOW^H?+ytA703tO5U+# z?!I;gxO43!5I%vY@j(F@fDAweAOnyA$N*&EKiUBBIBOvOUHkva$)#pAwAerGe*`10 z|05W99zM|iN3agOwuRu6Cjuz{xmx`-fOzART#eM@42R@Mhse3?=lG$85t{>9Ot*Y9 z{Z=sil%`QftN=c{Ko=Yjfbpwt^hk?V0imRVz5N9cOxRZnd$Hqu1frp;WD z#oeXAqseY;&enSv$rJE#V~Ayveqbm_(P!~F#{tumF=?J3EvgUF&ft3svXyJy+-!F^ z8cMu&`9w!145A)J^j zJR*ym`<#G#S)PW|2ix>1^lQr7^aWx*GQEwtzH`NyEAfC(E7nHX?wj?-J2UmoeqLMD z?3WAduTa>@lPnNIP2EJaOf(#< z&+_yaVFWftYJ@9(#2EVjnxw|d3OANobZyzA=vP(sMA-iGCHGHXVeY^T6!zv9{Joa+Er#q>m=*xU_VFVF<2=3eH>Gx z?4w~aez%KbU7pEwMF6R(eno}RGJP{9&clj4PG%h<-t8Q2Uj>*w{ItsN_$yTK zp=wudo(@dUq3DbFc(-2vtR2xg3H!|lS}_fsTO?JhpIM|s71Jha73SqRXE2gkgvsWD z&OSM-+l9jPdGy%mg2mtB5v80UVd6ABxvF1(qOkuOiF0^SgCC#<EuuMrqEoT=fyS9@}IcfOf!Lz}P}(U`TI!Gb(>j zC>7h<>eJ7WCMkc8oG%SAE^pGKuBS4kHXKRMcT?2RD&sG_HHbXl6T|icQUN|mj&;QVY=6}KMdH<9xS*a{{TPyVW+)3 z;A?iN0`tg&F&#o#;vwS4dN2J^`P!)qtGI*0mPV zH2$of&Zl?Y&4i0u@85Coir^{}vVGXCSf8AIcio#%N2zvyn`lv~o!?jTCKaRjr;cxn zL!4E5dZ`of?_+a2&!PpeXIDNdcs_G_Ah%#H*acP-H!E;>L)pJhDmRD81f zrVAI%r=VzyKR*9?69m)+0HFj*Ap?*B$N*#jG5{I)Pc%UGXQTh8+W#l_7a;1c2OGAV zTV5_ZRG;%-rcDQ98W-^4@VtD%mHPO?PLDR`;(=t3GM-Xpet&t?1qs51-iI^G11as{ zQQnTj=g!x@O*ZCkGmF_-rp%SQq;n_e*Gg#Rito&or`{60_nANFOby=(qEHCszD_3N z@T?|aN@7LMTdLw+__JCu7DA>L=M`&_t3M*% zY@)e0rJ-2g0#jzNGwdJ#dSY(hfA#)|{t72UM$EM?%BCR}J`L+O6&eq53md!e()#+! zzVy^*CWmoS=-OH;hKwBF9t6xkPV4z>m+HJr#ONzN-}q@-S4QKypPfolF2l2wJLEbZ zsh^`M^f15Wm~7bAUYD0J98~(!={fKS>&BfsM{LxSFLDCEcFDhu z0g;mq8wjDqY*-V0E72s}4Y?n4Qy&x<^iop>^?a6oU(?O%`Tm{Cb!O`NoHbc-8QWYw z_1=3C)WnVkuM0&up4lvkUz?2GC%B^0{f(t+{pVZs`IpVZ*k>3{`{2pBe+bJSp7(si zOX%!n<{{tO)N6R3E99>1Ip_L{;!+u1_>O7+5&=*1 zSy@@x{VYJ}2O%H&c& z-EGr(jo@VdRbig@HoqSHc%a`Qh<1}GT4)wiOG>NA9apC9S2dqFBCO>kvl|PX+$r~-$tC0Z5GwPup@Ph z`-#YSoX>`tSjW&{RER&C+V2i;}d+zR3(dd<1487_-pCK%dQGc zNH%^H+Dkpt9X=M##u)HGWN|73*h68ASGGJwXY2Jf3ZjG$8JJ(zL_T@-z)P{Ah%)6% zqc@$gNgI1=eY$;n__dPanFDHBkKIu6)0qiMiqEo{r#YXYao-Xbb@HdE`jU=2RdIGh z^G+vrOt%fk=G(CYEN2$wgSlJvOWT7(NjmvdtGQEjKPn5W@fY$Mr6dk;ePi-mQHgy>hc?GyosGw@P#{0g@#!n9eUWw97TsPg z-KTTx2tO$0Y%Zzgw62wr)P&%`lnRFD@E{U3=SgoPVYh3~bA$I;( zrZfS0KWJ|E%d8rG(XEvrP7ZeL|1hs(_Ve<~HLQvqP0r&=k!b5H4s2!gXhpHu@)9&?x4z0<}(Z&``erS#{F4o&daQsZ^3v9!06j-wp}YF) zN+RAb?6MHarAMaQ0zQ+tHhBj{bG!;6GyftK>I8sL0;P}v$N*#jG5{HX4E!e=IH_C0 zH~fF9{Z9@^MburRE0mtC*~TS7q7ZPw)a_ImfhP7Q*3&}8eYUY zvU(Vp5kPQPKkY+1g+48M*--6wf1xnqUOE$|s&k9P>8jW%rR*OFSsK1i-W5E3<80{X z3e{vS{)UgQl|q2JYfY;FfCh+cf z8k}EJ!+%cyYI)`>$(PmcX@h5k-x?ZM4H&POFQ!&wT^=NR=h1E4AvGeSdL*Lo__e-X z#kM3KSq0sQ#edV1 zLQPRRX-`!;O3nw^0|L?h7Zf<@5`Yl8J3`h{aD6iNTkmW6OM(KkwS5jQpRXk`d7c_s zVYOkX%o#7qd|7y^#hIR#nVE~_quh+d{FQ(lHI0BCi)*o}4P@or(tYcSRd?FnzGDdb zIDqSXkvVAj-aDZwW61~~9@)hmGseno36;n~rhNzW#J-vZtwWyEUq8|*@yY2@VQ9WD zdSxpv{G7Azorx}v@)^sUaW~T3SV;k)bw7v2rZp$SgdyzWUggASvIcVx`V_ zEv2{vQ^YE)03(vRRJ*c%P;~b6wWP57I?@f->{Dy%PlZaSx0_aYZ{TISTLoNwpg0yr z*v8(bcHvu-Tmi=PWt@5q2_~9gr6}xmXQ3`@`)kxco+=#%Fv?X`tvjUQ?NdaZKXv`) zC$Wg21NRR@Bq>=`X?2bP{bAqd?HU1@K>QU7qXZBkRB*&jqWcn;^ztu0-7mz~E=o8hx*Z2+bbm1vJXWqO5})E4 zmgEg>TICXXqvXm>?;vQV%oufEr9836S3TP(e5Y?~yipbhE7bV@&_=(~EGgso@!jAH zJkj{7y_e`B6nBjIEUOlHv&nSy`6MSC)raDRF0KMX?^;i0_YCCJ{_GqHc^KJjGX9(y z50=0a+DRdrjmvJE$QPfBDW^&ua`~0V87|gsT=O}jMi2eL2&}A7hw8_kDz#$;i2+(d z`u^t8r{z0?;$~b8B8R&t0v+Zz@@FSPazsU*`QzUV%T;`jY1umb?B=fwM%yES8>bS^ zue%SHWXx`VuVnA8D3GN?$D!9|y!G7lLapvC72x@xC-GOPAQiv}p@e)|Hw`7js$_81 zzS2#7YVC`v+FdJwUF8~a-c`rwI~G*Bnt_-8y=3>fyUNznibG#KdZ9NNKg)D1m)kD2 zUMpO`##QV>GkU)v+xjqVrQiML!QGfIo(wf#qu*Yfj6dc5EoYq5=+Xd8xtz`A+^1x| zx>bEoWgrShp{=A06Z$_YwF0j9 zq3LSoJtT1a?q)=>`Q^5C%&ya&7Z2zz@lDxM^F^FCVt&EjPDzffeJ^Q9EOqiA_Tr~z zE2%mKje}zz?P`)o4y7JOPg)-phK{1w96k89mAy=Qbo%K5DGhq*ndn<e>r&nXYeobjp5(bGO=@eeQtnXRz%Xg^~4WKxoAG z80QG|?cvYG4-?V}e-`9_jyo%;Rh<9cQ|fXu_SHtk%MB%;8t|2Sc3(T@q;tl5XN6!s zEU~g`#5^n~B{_}_n%v8_dr#x{?K-z|DP|3A*2RWtAp$2&vcjIipwjAIEWgM3yU`7b zRz=x|Oj}XLx4Vk9+sBPtyOmP{_vWi8A_*#drFsf37Llm?JqukNnH7n=H#^4+*aPCP zQ0V&qZz0epWB@V%8GsBx1|S3fnFdbU=kQJcpKAZp09p}^f%kgcmq{>X!X*cP^wraJ zS5n;%dCPrgxZsUmMpm4IfYNL>Z-u33jJ5U6lJBitJVZjxvK@t$_1uvKw3*+``t@YS9Hbycx8n(cT#=ehH`Nrc0+AtlINv2+=5Rm7ZQHydrRhAnj7GFv3Y#( zeSlu<+w7vHq7q+y5sNxW1Xr$432*#bjz^vr?zd;7?tXJX-SzpSq$iA{$0Uy)-~8Yx zIA(op=J(oGsnb-anVO&qrXK6INrQoQGmceSU$%DNAb61M@o*@?`lF?Ed)gZxv&YCu zO%iMtTB7H;gT1WEh!}J2!$1GJKC4&$W%gxhwv>N!_ccCc75&L&Cb|g!9eo{=b`8zX z)81wNFQ*)i=r3kI-(2rZ9CS78u7U(B&iS7$++XaH-{^};r znIjd>S%teDl)3Z56iYGHj!G}qK2Y!5TZpA+485%`9%Vb5SXs*}H*sZtH;LhctNfET z3L|@%ie=Z+@D1VSIm##B1vGqA>)jQ&B7yQ-KTsd?HYoeQP%1ndFvSEwi* zfC!--e8H5$<@GewJ#(v>H;Z*2l43Lk`z<^k?7SNp>%aV+lGy(y3kUDWFbk)vXpz%S z8!blt86t<+&DQH)9a^)r(|k`SJ^A|=cv}sUD2$lfX9M30o@>v!5OXQu<{IYk$BN;H zQyeS#6KeUwWWDkn3IldTiRs4}4e;W}WoTwR9?8(E?2c zA3&&f^==jpp2(u$Md#?;!VlG3>M!KRtz;Uqw-Y6M9P`9m+on$|Mvq?D&Th3f5%9~M zyMu9=aymb=F`Z?G+zb6OHo*;ymlJN|-@jEi$|V)ijA11jEQ)nIF+EF`eqMzS@Xw5I1bp;Xa_Md%etu zpi0)Wlo02!DYY)crD)dMH$G{TH67^`Q(C?nqczbF(;@kcS5elS8X9=1nmNgZ=d(l0 zDEuLF*VLI6&jUigUP8}!5`Xii>~>n>nG2ojYr%3hN6ERGnf8UMVd3?vap#E2SAUS7 zM(-xXjnv8=_umheZ2N3l(C5@FZ*X1}>mX;n=AKE3Lu61#t`cr?WbLdH)9Vkd0X2DM zMGD&FWe-)<^u*=AY^f3DCh%|Zsa{v*by&1(_oE!bytV)jNi4ci*%*v!C!aiXBLVS(JEL| z>)0wki=3x#UUn`iIY%{jUU=iTP9&kw^?!sCD1{6_1|S2F0muMk;6Ks8$>n7DhW}5s z{}}WNFVq){k1(W@?|W-)Bp333yc!f#i;d5%A4x6tIcB&^YfXhF1yNq%@SpJTx>{ua zS-Yfc3d zYu5MF&l?ivn9UK$7_XHDJlc^eqIPP0h<0~fSfM9je9sSil|?Gd_W6nrgEDQ)^tj|6a1zmf-zG&OR{E%ktfJyE`n6Fy7%U;OqLvQvD zhl|yx+RyO5z$xT^yelzMn`z{TkD5T#I5LUbLba%GxYhq)+IXQX| z`OaP*HEGE<9?@Z|B$3e4n61J0*~i&@0c4CS44NMlB}IHs>CByZ$F(jet6P2anLm%z z$|ycnHjIUQD>)*ltrxHd#9yH>W&jaF%@}XjHCQyv`07zm3UItr7LVeRZldHw*Cp0W zy=+)fS@@&Utgq#{Wu1b;O%pLk>2`jzWca?C#6`HNsdVw(VcOb(*cl^2Im+4|#rxwT zaT^u^$Ev-jD7`*Ag{;geP?&sk?*C!$u7c{=wuWKj?hxF9 z1$TFM3-0dj?h@SH-Q6{~LvTrOw_w4YZ?C*3``>@<>vMG&7u_}2MOV#d%>`rB=$`#} zixq;5VSclahaa@LUEhVg!M`_pvckfE*j{PHnQgPurDO>Jm7|IkcBh&dsP*T@oGI{= zU%dFf)7UiN4dPlvO_ryu?+34iNR`0rO228w9Z=fke&MrcC%%@u7T|HuMuOjOG@3_z zKZ`5{KaMJ)Sr^Y<7K|!$z&O;q&LxN#l>rV~z%>i!%lPEe^7I3QB>V>a3_RGV!M(yS}fF2$jjG{|KD5yHjb#Ly)?k8EXdA3sg-Z)|um@D1?UNv3g7Qq-#qICne=g z`Ctr5;(^h>XOnBfccNNaz=PP^?QP`N+{o z#FCxB8&nsFREy?M7o`_T2D;GTN`CFerJsFPAN{c_wgXHXJm`Ku|F24enpJ59UK4eV z`g8Kp$qqU5e0^C+)D#Dau!iUbvQe1GTm5-lRZg>ZdSD9oW$LFJh*?h*+dYfJrCsj9 zcqJ6+-OI@rGquPwzWB5YK|F^7U&2aU3i_WE{hueUnCk38<2h(aBQ`lTXEAhxxX`3_ zSZvVmQ(WTXCEO0i&)q2ZA!9Amrg~88xQ5N!@CdydB##v<%mI3U_#2do2r&Eunxw6I zI!dp{^DW#>=ank(_ zWIbtmYzK8h%zBJrKAOTc4U$k=EY$^_qPi8Ed;mL6@_OmX>QBT zS)Hf8$tM%PgScHWvk%9)Q#qpcc#E+bF!siHIRpxRI4_7q`(?G0_h46om8OCD$q=ft zFfsWarjX3ydDp3UDm|m^S1c8`$k1`3(Pv|72bSCX!PvTVIrGnWRj?}nJwW^o`riNl zKalt1yTH4^yTH4^yTH4^|E9q2yPyA>`hTnbCkC+o$z9c#1)%IVOf_n(bC6zP83oXpEOZ9sX_||io=p+^f>kc8 zmotm@r;?jg)Re_a0Y>s@wt{UhwES0EaQJ~RoCGE^_Ui@n6jqMb> zl-|=zO@1gV-Y(>R9d-I+vp@VQ7s?1VIxwgH&!YT0cV!{@C+OEOHbGd7h#97zUB=^$ zT8(v%5ozo+0`$eJuTU@_mgGk| ztu-t7TAr>_K;X`8wh6cBO^8fWp8C1(u*$66Fv4t{K{UP)Mk&hf8Q?5En-Yew%~f_1 zd9U8r5_js|>Du7%*c;ufW^$HM+{8LPrV9GezBC&ldIHMTYLT-rUQg(_6{Y@ekA-7T zH*Gf`QX{4}L8qpXt7T5fb_F6YOkD>C zpG8n6V)YdYt{x<+0B^xie~SB8O%XKK7$e(FsGNpK+O<5?YV1@F9KJRn@x>qAkh;20 z2~<}|7I>Zzjf|8JJ1tD*%p^J5j;GS!nUqwWjDF4i3zU`gpP+Tb4nwt8F22{1B9hi8 z@IVS-@K?}dzW7fpCgp~ZlN^=If&_F$?VHO1Ay{kssQRw@tHI`YgCa-rNDg~r)K9mk zKq7|Nw71yI1r~%zdk}6&Tg=ka_V|)W357t4UneF?>5SNTtY7sMgf)Y>d^4<0U_c`t zi!X<>-3S%tB#G8K=A^^Fc=}dBn#DLMIkf1xJ*A}~eFK2z;)Nx}nnqqFQ4e!_L!sgu zaf7tf?=*yufAO=ZO0y(%If_l2>w7|F8kax}w7c^B`FcMDOcpfO2v7b73#+}?KA=UL z_o?ISaUF>W9(OhU1a{KX(jiwm`4 zS4x_4B>NQYmj<>7R)n1FtIM59l0-NAB1P4%@K+8Yhj79R&q*JDa1|L#bxfscRVF9n zIfglKXDkYEYecK)#J6q%t6|U*Bm7K#OSD5=U9B+j-4kDtmL$o;1}UGpp|s*7Ki=CG z$X;QNZXtknWBH`${@p$NOAo5?0qxj`(FYN=d7p%TfwF)4C+L^Yrg%y62UL+2qZm{E zmabaa%)^18*1V?_XFdEVgY$dWYdEZnt35k%W`@i24QexO;~N`Eb`!Kl-#TTNv){Z8 z>7R4^(xC#jIFlmpP6m6jYvp%`nGhRvjqUf-Zh>~&VnUgL{#f1t&+1{ za1dUVvj_43S~9hjhrdnyrQf*Dgk<>8BoHmD!1^s-{7P9~J0cXBNt;f%r{QPSCfEz_ ztaFPK-QydWAQcmPGuP9|Ce*L8Ms_&u+$11yB9)=aY&4H9)T%__o%Z6as6=v0cwEk8 zb%HKS!ArSME{E>5x`dAFgtZKRdME!J*4jG6uRr8~1C)kwfJOfT) zv?rr6g}6B)qalS*0_3i975zWFOLMU11n?c}$bfTZ8 zR^NiQnIsElX7eO(DYXi7J3!FqQLkqyMHxZ93$Aw8@BAVpeOk8vIqnuaE`E7v19Xg0 zcWUM36>10S#u0iT^nry_9t!TU!(3r4VkZw{uz>yNyob1SF`qOQ&rWJa`P;3P|M>C1 zZK<@wGzPG5OV-q%CHbfRXQu!C!1W(c@2ueNJsc={SZG6$17Dd!v>4Gb@@WP)NiB@pXmD!IY57A}e8vS;zNGG>GQ*&M z6jds6i~hE>v^SYp$@EwjcYM^Yc5Ro=gy@AM{naLSg(0{hxdwcm+NaZE8fe(poWqDD zwKE~oS5O_d8|ZUn1?lDPozDF=0CfDLe}YUdw%Lv>15K6kl_78J*elaJKW5OQxRM2J|8^Z=!u(i?}C**FyDB+KE&QJ&GxxVaeO#!Xwxxu zl~h$kg>x1QT2svzaugX}m@6X~yaMtGM9v=@&Go$=&X=r8la@bn#sGIGb!P_p)Z$1> zPI#4k<&*d1p6a(vXqBI3r~fZd21>w3e?X;Aux9y*hxVEWebB%<9T9r#=FK-H9^H;F z&>O+FyQ!XO)ToTq*42t4c~_GmphL@n6^{jSs-n_EcqH`rq(4H9s$ZXE0QKHf0I^(p zI_!dVJ9Q);QQhf{Ftp8>xboV9;yy;FPDQ%(eziTZy;`48>(()K*uo~j+YF@wV~1zh z!9zSxh7mtjgtw0Q20xU#BI~vB+6@2|Aj1Hrnw01!qu&hMDt?RVRF$f8r&4_JUx`|h z5S_c|pud8tZJs2PF_*ZJd%NTp6G-=tmX__USJ3dw(7J69phmyh_o`9Hqg!^@nrFfg~6iu_4TYF;JUd<@?jfR`JDJkN_cjLt3u~4Vq}ASdDDdpka|qo9;*}CRfUz8|D5g=WRpDI=CQS`Pgo) z>>x8ca<+q0suEYGa@%t^Bg7ixQ)pWP0JYGwuivU)gqd5MJtdo}nA{U^sXVq91((Xo zkUL#%jKVNV(*MXi&Q6>xu69r7*kuJy;H;KPW#K_k$9?hnzCl5{3=~YoQ$8`qeY$0f zo28*-lv>ZDN+e+Ri~)+rv++8so3wW60JBsv-gh61?#s?4H|z*;>&2MmzO*CVLw(MQ z{SWc+oR7xvLW=Z#iIHmJ)Ix~(75@Tdq6U2Q2UHB%NOOH`;2h@j>6}twUR=9S2vHd? zQJ`KwlE|<+RsR8qAxHLi;skbO=CJdO_&7JgpP|s|U&r*CZ6+v;7Em~~gXQBvhaafX znB|l_MEd;OEcu++B`_xtx%hQ24B7R81ah6yJ0i>cnp4G&Uy%l6-+sLkJ%zyV(pm#0 zhEb^>SA*Z5Gv?_m&T5sTUy69Vhyy^m8Mp_(iP?%9tLg|U8y(fMh3eR56VsEk zZnV1{x?5Rr$G9=&8L2{U3PkynQ9Bw`|I(tB6C|k0M5opHye4xReZytbWhhW?HYclc zUjGf{L5VwY3acaz!>ke)-u9K?CzZ|FN@P=_)jIIpxo2F*%kx^CoDWP776heqC7hJ_ zp>MrLUIDe_mBA{~%M#I>G({t$M1I4+K;QfSe@NcX?*i`v?*i`v?*i`v|BC{@_m=u= z;{UDsp9X;XCwD~(M}srw|D?G1-SH&Y#o6CWR`5VFn6-Wm?MpU8uAM7dGTw@%|0>eIRKNpPemM zwn#Vp{A?g>zK*ootN+L;Envl8X7h`7AgA zCvl+}=ZW$!l+i1!7=hh{AXh`^*AP7D2P+8L=#nfN^RFg+ny=)mrp}MN)*9UtQTOgA z0gtY@3;;bq{9XUE{N57q4=8OYtR~4Pl^LA+u|(-Bh7`J;Z6TFoi_o~HSktA8Hi9gI z(Gy|0dh1@jz)xDhZW(F4=U1xpL*4p7g@Xd=Eqf)@Vk3~UJ~0vf-_?F7%t}?deSBQ* zmJh9WrDtxf7Au0(K;N5zfReKxgeDE_ughtoiCrXF84k8us?e z;|)Epd=FL%u@ae9EC&ExEDRaqh#PeqSTv+T6{DA_zxicc8h15$c-S>aJU5%NQ4&eI-v?Ta*lN;tx$w{vBl&F3yNPx&`$4e%(-{#FY2;M%p zovAnIGT2;=t#&U3$RCN`(Mh-&VFZUmyD1olFo2BK=3M9`)>_QrmU2tMN+ zA(vW8zriXeqkD_a&x9tM0)UD^6||?ph$NW`-s+7B)5xGjjZD()1rUZMdcR}OdY%2ZQnU~^@!*t2B z9r~GY{B&J{1%Yh#p%S16h`(1T8$Dq72lQAB zSWD*?^g1=^ZbcnR_6snteRIc3p4c*AI%{m56p|Ipt-bO8WO9;@i6{(NkGpV?)gueBP)7CAw{j2-h@z1mK# zWM(UO*o>6`x)?LvmezN=2BAZ%W&~AgA?-`U7H`xkeue#=up}o=^;uG~vtc&2`E_5B zmM0`{PR=*i5XxR(JVoSyMzDPbFp;vUoBWQft^kDP`az(yQj*>Rl> zh(C~1m^-8W=yqB_Or!h)C7`rim+Kk8XkHXAg@yJMK3h+Np;Y!DJ<4VmnBXCfnv#EXt|| zFh6XURbVIU>-`_{VOQa>>f$T6YAbWcmdu<1^t5=*&u36$U)^9rGCeX)Il#P=;_0Yp z&Q)TApk*$8A#^S5j*~U>Jgtwn)I?<3=hd5lw3%1yO6l5GwwD@ET{hNc$=>%=xBe0b zHd1_KcwggYi zWx2?>LbqIR6{}5}ON}i!O0vmh0fcwoCxM;8EMVGtCCl_ZyNs6r+iA%Saui~V`)jh3 zb1MViE+t`2&Q+r_h|G8~?Jzdb*Zl7q@rLkgC+(xbJ9(CUN9kQIH{BuAa4kY!eFtC4 zZ5~{9HA0>n!OgCzqX5Og_pc!w=gpe23$~=j>M+P?nS>rgV?}%Lx&yPE8YH%~luE#S zG&TOAT;)=D)&4n~l`@n(EwsY3vcq}1#%z{k62TquO8A;EPOH_#gvw=O6RmGxcm%tV z?)PFdMy4pcQ~QfFc``$w;8~NrKOGkX$?9GG^zoVWl2H{9qnjZg91xdo=y}uGPI4rm zLP@=bmS*O?D69YVxH=0x(?3Chim;$2cY#i;KIGtjyb)&e4&Kh7$QA6(yOf z!95!TW%bdN=4pKLxushgG!u75xJD!)3R5EBL(Liz=iyGrD~ ztt92K1sxZb8=1h`MZS>2T$Am)D@|&?A6dV~esUg?np*0Wjvlm!-iVz;{)%>+$&W8l z!_sC2qm_515G+?sg4n5oXVfc^m4eZeM~koEEenhvQL>BoiI62(AQo_qRlW;oEQ16L zXS{Vo$)xs)Pa^Kc{n_r~?_z+3;deLi&k7YOA~!`YVR>l;@4oj=!|>3Frf!AHZ7GPI zg}gw~oz|tKc0E>)NWQJ!&fU)cZe%MMEq55yGZY2Z3^N7HRkao!OXq_Z3&LUbG$7f_ zgP`Gg+<{VT}TY|rP3c5`(3)zc<|>Q(bm!>1xlO^ z;MZrKveN-cDSE{%03;-%Yl{`~Kc+4^TN~sj?D3^ezHeC8f zheM)FDHg&GQtQOvBh>7B%7Gbs0s1|9ihH637MHv{iT5dwGc>9?>3M6-NP4qyvg<@* zr?`~tgH>b>v9AJCQeJ3na~W@0iLriW)z(lrvE3J4lT$?-CB;W%p7IZBN)eV-B)A?{ z6xzF5;3Y^4*X;2_v52GR1GZz&#b&!6*O~x5K>Q8L#0nVx0ky965D)^}xBWn6`jM<( zz(D^4m@p;O7m4rVqCsg9>|N3)ed*>uN@YJFog*ROK@)Y^Q$Dn@r%p7_NA&Lkn9_>PltQC#c$)~@0f1U z5@q8_J&1jeSVzwrL*n0)gw;|-@mc+>f{%$l_EDqF5Q8tl$#g&}^=p@%h~wv1DIsG&7Mz|^N_(@dX; z`1HZnk!Rf6^wofhy7Chg%AEW2d4+p7IB1vxZfl^h`W?m+8h_Z403RjEV{LfPK% zm#%v1(6JmVW1@fMF%&tDH1MfV?BTE+<-`2R%F_5vX`4oB+FI1jC$j|@ekTP8F)g_7 zoX_KA^{5pr!ZGe)!x0!;=y$uCauRZmfuxO3Ylvwfeix$aIF_bgg6%5ChL3>{vsp|h zYsba#v31~6Xxf;^&#ezQ^{>aMzMF{gmJ#JC99F^pwHQzOxI!dz^8F~ni(SjC!Mtkl zN827m0T=7iBm$ci8T5H?J9Krdv_QVJpMF#+*6de0o-nn8NTuLgVs#hg>se`Z_DrWz z%3SF8m>yKCdutuKBbu zma-$!nSk(~N^6-23HqaywZ_Z<;=pxVO#5f0?ItxkL|F;nsXCwuzOe9MFh@SbW{&)3 zm+0atr$kDpQaeS36U7Nzq@Tq-f)^V0C+$gUSj!(mIhhTX8^66hogohVY%*MQKG0;<*?fv zR2`F(OpK~aE7rQFoZioXIzruf7w+fG$G{sW=$G!SDj0VZYZ8y?&4rjk5uX6SuX9VdyecG!d=IAaK-j1kcd&#U8MoG0=j@MH8> z2%0EU4KQ3xp{|uK+rrX0E%SG^!4SVU`}_ZavT*{2e?U2`ltpXxlS`K{T@7Xq4lS6- z{(6btgB~U=GiWk;E(O8F4I-V*RgRSwUb4IB69Orbp0rj4oSb7! z4uQncV|@8d&(*l%*zivr7sc+dwKFd8u({@x z*>BAJO5p2Nzc%%di|)x~NLnJ$_DsL*TrsmFUg`nLRjPqBZ61=@k@)@)--BaFXF_9G z1RTbFC{I0pdIpYJvFcJ_=WEuhU7zxsb7eZY9FtQS?JM@StfCyaSU9S*MhxPm=4XpDtf#<4vViVd}p(0zemdrJYN*+_&uTOOzlUD86de z9aMa?gbuRvq^2PRA>ev9EM0TFdhVXoFA#3Z56@?6I6CIi{KcM@auXw0LE@r54*NZ}$w@k3N~5AEJwMW$)J(HQHh%~>C9K@C<~z2UwU(gB^zGZ%n) zot;myxJ`IYFJgj8wuTKdw*hij8JlfC&^!uV&}$4FUX!pvA)e>ckG%?(BZDay#6A4% z&19K=C|sDf$qT|=GbI}jjq;z;h>KnC@&}{@<`PhdgJAXeI&5`i5O@FMOyy7ofF2XJ&UAGsA$#*oPSWKZ(>Uf@}8&0_HU{r z#F@SBCG|LN94Ud77l)4Ra1Ge$=cB)M0YGyHK^*pjlA3m2F^R5q^Yt9~zqq$AZ`%Ve zBGqjn6+mfQg!RITzfSj-kb-K~m43!=6|hpwJ)%YShz$x2Qb7 zc?(A_J;mz^saK#=$hDG8+gl#4atJ}h8t!xh^Z@ZUC?g+W_y@F$X{`PJhRCo%IzaDm zJJ|aw84QO7*n*^#W&v3nO9Loz#V&mx>ICXb25qr2=KV4+YPSX3#rTax=*Qcq1YLVI0kTL7;CJp$7POqH*5co_4#$N26Lhe)9y2v2 zvifW+4K(o<#1z&TH`SU(QB2L}Kdmb&Tzy2p&@1S-u37?s_RUs^&yu9G)vAuz!}pm<>uA>RWUnEI(XR{y1YbIA<0irhBY=df5evkBAbh%Z;& z=OcqWT^dFpww+*yR(X}Eniy&c3G^{6mK(!WJCD`B`v0s<{Qm?U0|lupC!ENa-1D=b zlo{8!dxCIz+3vM;fukATEoFoQrYwA%E#pX!bbB_>d>wH3LCj}mKvCGaL7>2K#(<4N z3I{?v_72wT^1A2nN>E5y|K7np!X<`{5YsO&sAWHepv(n^aR?2iv7lDP~chd#oI1N zSd6FKySJC8B<#DKS*@ByT}9mtukLnLr^IWeQ^Z!N>tiGxwyjKEki^qi4yqfYxcEKa zdRiWK6qPgB%aikrN(OiJS6~whZJGzQkc4bO?26?&nYf%xx>)r3ZP?yl&@jvqL02&J zIqsEL>T4f9f_cg&`>+U#j;Ujh-n=-uRvXS4n2xCW0Q3Oy_X>UQ|NkGz`|(}iUEp2d zUEp2dUEqIH;P=bA|C;)LtNs@Nu>L6qwscp>T`?v7BymcdTYBTpd1Qpxi6(U8iqD=o zYM<0}GX1^5$-KO&Ju>Bi89+sdC(D?V>Y?uN{6el?2)Pf z8=mUU8Mi?Dn@&@(N)#+dKZAHd9l{;)%d;F#H&DE(>)VvMd%O9>>?H4?tg%A%lBGY! zYTA>H4|7J#@@I==ONf5o%4>igApXu>Sp)&YKcJ{)vqv@CAY2C;k83CpJvr4_#)T5$WwZZ{r_>j9G`(ap+M+ZQEY;fh130w}cIS1;q6HHI+# z=M&jC`~qcZ!V&NI7_+mYU;I^i+>Q(6z;t_56nSYdahfM$VkUxobl9X)(?&xO$@iaK z7K}#f1;Z61gxUj>R{B)c6F^QLd?vNSm;s=b>NN(P+I0JD28uVlt7_s4&iGy+`7c#> z=AW8*aTLKtu2UE5{U%br)n59fhaBQ$-F+>FG@Teq3L<3d8X#(YIP8HSvVsZ^GeV4G z0-KkvhRXk}%V!q$d)^*iT^Y>q=0|@0@}~5!W})aKtGDJm-pw+`1fJIgZNn<6Vp(;qQw52m5m5bX=-0A!#q9@TV22OLr0NBFu8mAOKK2&O*D$Rk&B+_FwRCK~VckBW0{m z-)D^m8tDth??-SJ-+pcL{=BB4a-$Y%Ns!ROcd1I1vtB34*(ByIE>fH?E{WqDLh@HK zUL?e;p)T0VnC=>HEOv>Kg4lMofIM(0g@(@|bg$Za+-g>mA$wL$nL#5u*Ux-`zMcA6 z2D*;srBEs~J+NKuot`m{y)!^E(I(@Bt2PT*j)3@kg|Z0)hJQdI+xW4PV#(S}R8@tT z652grbb2URXLbB41!`Pcw@9w`qNwaYY*1pH5}yQ!pPe!$;DVhwgD)TWEIj8HkAb0D zs&rf@f6v^ueH@g4yMw_z3p}%!glFHZR$gDGk@&@mdWyBD0h6N|Szc_BQh&?Yj)3xQ zTOxfGXw5!x?{lrHm>Esy?bJq4(&H5ZZ#VcF;dH2%C!YcUv<~Yv1Tt zqWRVlE+9OhuQ9-&A>9udC5nxB;NxP4rICd^J?IY(pl{8j(?$M!>LM@>tydAvq>biz zJJ4b-X0$RhceBCz_XK#vIfYUG){)Dyh*z~{fKSq87Q1M~p#Hz>OZVE6}gnyT)OzRTVV zQM@6DddW!HEkF4UqA(@7?L_n8V8v6(2ZF4&%G2uQ^O{4+gdZs7eo``UI(G@|=g)#? zRbu#>vK|DLx-SsrOz1xdPil9@@V5%c1g1w7!|iejo{yqv6s;q=^cNAIuOKfl#~%Z? zU9AWcF}!D_7#2f&uhpXMz0AZCF0uO(t8$9hf<95x?{#jlb7rvuKocZ_fl3|Su4e9C zCHoq^=-iv*D}K>j=NddGvt&MDkaY}kxsfcHh8i$R#u%M0G(E+p-ZJ^K&Mus1hU2rs zm*^TnGhYUnuI|Z2)`{0p4Ix+nncTpr&-lj z^crwSd?rB99jj%v#+~EVVE7?Fo+fSO)z0>9K3@Viz%lyi-z)UJ{|{JD@9{41F7Ph! zF7Ph!F7Ur9fcKw?|F`OYQNZ>8k|UV;S3%uTP2$!o=66i)jDg%O&7Y zk`x{s#3d|V9t-z#Bdot%umj|-tG8+>g>8mMH?)Yc@~VBJm+Csg5KObd)8V%U7h!_o z;?&e0pDut0?2|cLfi5N7HjoA=_La}lZQQfsBxQ6?V$@=^?0mrz9KxUtqD1AB-hy5- zZK!CB*+l4|5Z>Ol`y1b0Nm<|Ox~gw02%IRz>I_miL)V(hy^u7O{Yx+({=1sXJ7D(59A@GJAbaJf#rOsz`!0G^@vi zTTVE=ou=+s)D8%FG{>L=!jwvZ`N5EA0FT3P1HK|fiGMh9^s*MLxT6XGFlvQo6L27s zHLjlFVqbjXo)B0pXMC-y@2X?$xuy;PWoOgov(*f|f0ds>6_fU1kp+zaVl1?jyHZTq zEFHf2a!pwT<+^f3w3k2{RnHQ}v_u_?cJf*N+|f!1v?JGQ?%S-=?G!y+E_zgR{S<+& za41veg}N63EtnGYxEk}C znj|hu9e+YR{ty?A0hFaS$^hQAN{&Nm^u+eFFGPSNyvJzMM^?HQcQhY22Qg7G#s-FA z*08SBbCXK99nd?x3a^VuyE4;S3emj$2|*id80vO2JS~~5e$?y2@@49pBBZF3$jNI* zGbpFXF3L=zWzo0n=p;oAd%?P@U*eajOSb^fHgp+_MC+f?ts=f$YPspv1J0j>fU;u_&x5kg zO0@~D8lt#P3@*G}m%*&5B|7_T(x*}s_lu5Bb7dM*NTjvTDSSA0X5DJ^A%}d8Q;6q<61i@H-_gsOMEO8AI^<^#vtUu zD~7-Vop=rMOx}g+R#@&~$ZSxdnYIl=MWGzZq5vni!j8-pXzAjiKv+0cd3_q#=xSKJ z?5>&dr5_|(LUD=6IXo2@K_mh)v;hFrYwmlYez6-{4~|eWizJX&g;U#X%pe2x`GIh_ z>4|G0O`j4cspvzZ`8_^j$G0*gOHzZT4rLy06;sOM^bCG=5dI2BxLO1v+=&w2k(qWY z&QH$6iq>r5Akwy_P8U6&fpj&GQ~7@7H%7dA->P^NjB+}iC#%)4 zr)>N>_S_Uzm z0N4Lh|0hN(XU};_SXYW*Xec!5vki?HI(<{*uZQu={dTpTAiK4^rmUKiAb|;giKmR0 zZGn~^uxIhIc?)_gy<{i zKCfr<=N9xU-~QeK)LeF)P1kuF*Pi?m8VtHkHhSD-ftbUhg&04^{s9*QWBG>L+xWPY z7(nhiMd(j+%J=#C&6g~KwTvldS4M7>Ly?tcMwhoC60K!Xn(Itv6e8V1hm=m{j+$#a z$*S@eB(mUCHjkZm02zOO&B2 zBCf@c9R`4w9C0|8$~Tt5Q=hN|Xi)+`QX{rsZ3;MribljDAP{FOz&Kbmh&h4yHz=ax zmm=90XS3?Yosq?GeavX$qJQHEMX**-66@toRFe^(P+Yq*AW9~_-wN^MZREBVRgxX( zSyP73v=IwfbJZGA65WGy7pSh}=M7NXI^G{@3X~@JB9n)J88XFDr>W6h?7VMdG$9l; zO!50w>Hxt%-BmVLnSX*}PV;r4@b#0xaCM)hVJ-(scm4H*cobFD;tqxP)TGYFVJ0q0 z3$;-B)ff98zbFrTbzMD++?=KFc7@MWzn5Au_>6S!rG4UdrGuwR<0;u#y+<>JCZAbf zrbHpI{U$>0a%^VAh7Jwv+e=mzEiuhf;FN z2{NRD&#OIi?<`5U$dxrqJH z|LOHB*+T)yQ9-uT@TmK)FRw8b3=xga_%p?-xvL#0_C18tC&B4C?0MaNWVN6<-@XlF&^o)neVQXhg@L?xi9U@Eb1d2@)UR?k`Dv0}@FFDwso9LA7dDPnZ zLk27nsEs}~6S0b_LcGxW{nXKGH30NP!V0NjD-ul%jh9o{Zw=Y%jXc9!hA51+E_Z;q z2d}9umn_$dhH+O!>Wewzs?vE*eKX{*Oe9O{5Oom)HM1n7mg|p@KiJ}$c1lhLOwp`D zj!f_Oh_~6l2 zpN3D1sYgY$r6U@~ii38-vHa_W3T*HFf53uzk9UE0fp>v-fp>v-f&Wzjg8xkXzg7Rs z1FrukcP(hQVg40d+)#^lN)T9wFHde{iLD*K(w~s(YF0NTZf3z}JK#x^lss+EL_`8t zGOxQ#%T??kH|!=5EfuAep5A-;>F%YM9a|(|-N^95b>hSExgp1wBkt&{3UpY*!dSuv zth+un{own)Ay8(RC9>2MQ2c6Pkl7?CZAvpGW(RNG8g@8pt_5=BSTBUyUH;0xr;iIp z0)X80>zTBTVxxlTl)d&^jFf=Q^VF_HyH>eC_b1^m{DPWfPG|M~K+;k-QJ6M0t0=ek zyC4vDFxkD&wKW&K{nTpGD2_UHy9D*@Cvfmr(;`!FKwP;K7GQ~5yM0-o>E14-QwG@L zds--4j?JjPFHi($3GUDYCTY>{D4|W=fa^{;!3tFlnFd_Df!=M}ifsXJs0CH{Mr8#5 z=iB+a7+|OW{7+Dq?4*HN{^nelo~!&1ctv{kF(&2jvL;v417k)k(4HyDW}rK+@RVxTm!kX$Z61R&Pj&2P8D`>E|j4!m#`ZKBG_RlyZI z5zn*Z9F5#eL1X6$*LhY5O_cQWEHj*l;PyT&nN;0Kd|pn)+>0Z;HWH?o)wWJ32GT{o z<@yZ892(W8e&B;DL3+ zb``COx+ugBZTGDokCGksLVRC{uTkgg^9yb{z!4&Dxl(I<*ziowMwcCSE;=b!Js&va zOs>-GM30hS`!6%$N?O^1%$$1LxxaaL5i?&@VrTfh$HJc#deU6u#-!Lz5OEgH|1wXyjqXutrfC8RMig^Sh7B|m6(6rz zEnOrk*3W(O+BD*A1d{m44LU>F@uGlSwB~w6YqI|#Qa7V4nb}p`24N-nabXydywGpF zuUf!P2@9Iq6hrN&t)DcFr+EM=4Y&Nn{v~#3qC8TEow*I1m9Aj|OXza+tx-|1nxOYD z5Zx(`SGzVkH?ZJf0I0`B9g&-^YU6#A_l)tl0#$p4|Mw|<;ba>u=O#6Cyn(}{J~wUH@WAPy_ce3Aef305&DOvJL`F<$V0QUama z5Pv)hKq#(?e2qGm5BC;3zT~WVJ~dck&L!8c)ERZ>ExJ_B7-%3^`0+!BZw~#Q(X|Oi z+|fmAY`c=(7$I^r&HBR!SdhIm*U1wCf$_%gO5ca(D8BC?Lk}d(oRZazcy^Ps?(mss zZgV!J5`2Nkv6#4n4+Vfegz}$uqc4-b_L%1l>5b@JL*;(BwZ+rkkHImSj_|F9=-le> z)Foj2vDX9Dnt;O%*I2NVW7(!Km?3cpPJ_kry@dd5EbZK0GQwb$sS%41WkX`0uZSjD z$(%1!xXCSjj9}wMTRn&0nD&)Zxuy_kX?vUpD@h~>wr90BoEt6RQl4|M<(zf%r%6=Q zgk^o$46Ux&3Y+u4K$(>O2|Bmk>|S?Bg<$Fg4Q4v`_GIkH$g*dtGio%CgYt&Pt%C&% z4<9?J@rx4Jr4LV>LmsEb%%k7eC?$AMaY4&5By~t@(wcFYowf*lr+R&jHVZ0!L445M zGa%^DRcVBjM!GdbjJ^fYJh`{=5ozNqmjtX=)@jPZE$C~X=ti7-dBX8V(o9b^gJA(t78=DA6Z}iB zy+sj;(lPZ`kLtfb-~0c6NZ!xy0`CIv0`CIv0`CI0F{#OQE|4(&QxiWuh zm!qFV9YJd3){OoG79CmD`m3i7wsK6j+g3y8xBti9JqOpdcaP(bZQDj;G)9xgwr#7i z)!4SJhK+68Xlyn~qwhWU^Yq^PoBR9s`RmD==}ydw?cTVt2>nTT_fo^GS;cuo|&EnRg7WsRVKSNvV> z!_=87{dxN=MS{h%z&Y7xvHwEDknz$^+ixZ7ml;;J zLtM~+=<&~$iwzDE|V<&LM1S0U!tSVE#=%dX(cfZf`fh84HecG%9BsSvJy zuC6P#1MfPjlQY>0@$C5L{{J3na#L5=q|~dNL0!F9>GnU~3MI9rFf<4@^?2qymArPG z__DGQ8p>7)?mh{0ivNrr3kZL>h)z2%q7ewPN z2_D#usk(deOkW8s32$o{T|)fn(uZ)u*R;V}SOa}@RnE7@-Lc~@g|1WDOLo6?I!>e5PyMkr~%U7pxyS!ToVaZTE`X7Za-Lq3120}+{x7TXbPgq zw}XW5HdOqVzpQ*Oy*zcL*N~fJvT7;y*l%3l;rmfG`;_9~4LKW^l4znI&^d}nAtDsH z((EX8s*(EOW~PL-wqIHw(GsaS%j-2y$j*NHI@*UpYXJRn4mS(mJJP%tT4_YBNCw}e z0R4S>!kA=;=DPQ2JDb*}cT0b$0`Omcch;YxFabx$u1p6F8iCGr(_KyhLqmgI+YqFR znIPxtxlW2GttmXn9Os*_v;slBg=JcayO0G<1#wQdC7&GZL2C@wz%gO!>%x#+dpOFm^ z#4u4F+-nc}GvZ9#Aue*{CHnpi%BlWO(4{b9u@|O*L*in0SqJZUSVbP=uuNl`f(G;X zH%-qT8s5z*ZgUTnp+P~2ug&2pg%|ihMGa?~Co=@RiS}y8;OStedTCYa?3sJ@ys3+A z6Dl+?+#R9A0Zp$E6y|(%Ag`KKY{0X;!YdQvIVy`^w3*?JVT^mzkXQSL7v^msFc zBzuwIh^mT)GetiHt1_sAxf>%<0YLL|o}O-T^Og`d_g+UH&yu#l@|nCVZt|LTD^q1QvFZ~WE_v&hS`lCxgCTgeLI?QIR?m28J#N2QV*8Ar znk$8+6X;{bFwGNu?@Tx?Sk0hE)85MEt`9&xu z84rs`LdqoMyTh0w#;fwvHV8lu5PwzZUmpVg-|O$kcY$|-cY$|-cY$|-cY*&Yf#1*X z`fttu8UW4T!@w}ded}7-$q$1q(=HQ|AmCQclwOXLz?__fwTR*Ut`cq@sIIKaP?P}v zay&QoqJo!sKbG$PK@P8yJ_bv9nEBHKF>XcS3R ziYxwQXylro0}(id#Uf^mrfppv_Bf!0TfpMxREF&F@tr+0kUt#N2jh1*sY9d1>oB2{ zeS2~FU5mea*N=>U?hpPOlwl~9Nt1A-isO{}0&Ph)$V)6YyDhPv3xx}K`^%ua$-nB&9ds7m=N>@W}U$u3GD7K-OUv=CY}kbK}n ziT3K1e!)`KA359ffoACqTSVM@dfRK(ZAYqR6A#hGz}Nh!;vdkEE}I+O$O|)v$Yi{i^Y0iciPh*V~JccEgyO6Nb_7Y|XHr#&upEUbbH!e(K8!<40 zEl6~^iUh07{Vlq0i=quC_QkfI91kS2HIum2@6ygmgqAm=8XQc0m08+rAj zXZAZ6q^ihIGeZf%Kkx4W2>w-}%-VqTHz*n7!{=JxdJ~41kyv$1lWP2?hEI}9DTxo; zxp6~8`-yx)PES%2Fh$Ku7EA;b<;z`4{BT8WFAMDOc)wci4S)*2lxe}935t&(Krevc zt0_x&^YyP?vXcT^WCy{10qLL+4m}!A)*@YK*{{qoXVQ-QN$?X@&#0%&xTdK9^MVH#ThZi^2nmGXUkYAPe!|;yySC2x>uB+ESHsrf^t-W*nxJz*8 zUhf+FN`Kne(WiB}$P|WdK*A|n)gN^;u~j3pGFX&>N~zLp>Oqchm6~Gu^F;J@>~0q9alt@?~1KN}Sg( z;5@;rL?ovBTIO7A;U_V%{BqP8Ko1aqfwJfT(%+!_qy&RFXO~k9uKgj()=*2Bp`I$s z!0kI=o85b4KJq>*%DWEm6=5XGibo^}e30k4>qTPmy%UW|R{q!~X!D#L`&FUp@Ym|= zh`)eA3c+8{P%j(@)(^IWj@wiwxuiL`A7E2l*^rH+r!v$z@H+_14aPaX?ctaFl*bD^ z!Y(eb6e-x%R}z!EwKS*nR*DW@$Q=3n@HGJd+HEcVnqwrXosFPnk-mXVO-c5trfDkP z#G%QGzkJ%MZ<@RXm-<4kc}NLwq^lm9K50La`~`lDC_gKDJ&HQE+J*D8GuNJ9uZxZo z8llUxWN%wfDCO$u#y3uFT9&BTR$57HKfmg3j(zO}lpcb3G1^`(u~4;VnID9`>v48p zh_@s3@2A3l$m?`|z-_LBCh^RL37|;**Jr37-`D>E1@#{90`CIv0`CIv0`CIF~U-HTMdp#2YL-fJ%=4-`M$ky1vQMn5?Pkq@dkNm`7BL00`CX8-ar`4mmN*1J=*O`h}CO3E?`_nsN-_%uT zq}l`NoaF$$D_*}#4!$~Ybs((l$a+n@MlE+QHPZ=rPi8cuf+mus{J{J}=&_9O1}59`;1=TOM?cp)5}RuEzI>g z+u*9WZL_z|EVAuAcniZg_IAg#-$>V`c(${6Eqii>Pvh6Kd_?;;pX1rRuPSLYBFaK# z>rZGnj6y))1VqnR*#0DpxhUucx-wGv5kA@6sY(I-wV%5Iqh7{#2qkWKu2FFH6Dbh=jZ)Ab(}x+u6<&ABkw%8sKh>mIdpdH^M%qJm!i@GtuzO*>%o3%#wM^0tScI0FmzXgh3d;yyy) zyfNX}n~Gvi<{z^DvF!h&N3)9D+u1Q7b7hje_R7A6N6CudJ_Pbv8ly7)+nQeNjcDR) z<^HIc8i87W4N;JTKqr6GmLdR@)($BFg+W~sPB|tbGBMZ^vhVF~ny;>An$uBtmhP~( zN?1C+1O?A8SHYQ5Nu^K|A<40WEy5oGWO$AVxXBJ-96jqQE}k5w$^kn|K@M~ukDf*_r%J?DgViu?w; zAFDY^g|Thxl_^QuVznId)0}rg_SF4AaE17$wAtJDz>k+ldzOqiN-Jqk%X-$56w#$Y ziLuFh+5KD{Snmd5-hyC7!A3B1t*f_cul1u;RVtzQGIJxP3}5h9H6iTSHv^ksZ%jN{a8S%z4~!3>-qP`HdlYioIN4CDJPC3Kc&=ocSje)8pi zzqX?0lcSHRm~{MJ>M%7r;w{{0uNLo&#wI^++adE3X{u&u7C(cos*>KfX;AI&E|z@1 zhc1O%aopCB0ktm?HLlF#o)iD)hA9BSzd$(+0qJj0E_6Ou-`%tzce=X(VYz^rGiWlW zb6E%BicoTPj5ptn5>}$cxsNC7O1QSw-g-+2^dIWk*RE*MpToi;fKr%fjl;k0@~^0A z7x`rk;q^$1Ror%rX8*{+X-&F%7b&tGVZoG>qW-qmRwzYZ)>oxd~KLrzlEG0L_MNK z2X3=H>abha5zhv*kb^Ft?Fr?&Nv{wz(ReuTvH<2?$a2v-+n+MS$0u~EOQC)HD$LK= z>tm%=E|133!1Q(C6xEA3IX3GGL;%FkWATwLiCI93m_w7yb&4@3#*(oPpa%%ZKmO<& zI&m>EG8zN&-=gY;xo8RJU>@0I`c?UL0uicV1q!|luz{@s0bg3QR=`no9wx~HU&Xf0 zR+5<$FKZM_bRlko81an)2K+RIU(T51k~pyBq%A z@mM!^1h=SZ#F1IltikeXdtu`viMcrG*B)sy??ClRI!9(=$Sw0{49ETQ#k}QT9%B8U zPhXAzdVu&_l*t5;{}w$C$Jny35^(z(@eKBj%Ze|Qvf04XtjV1q87vrktmxGI^wm0s zEeC1=n^RgD$Oo;n-Ga|0*EYB`A?)M$D_P&b*TCfBP>5d~r$6OD7;o{Tmivr<85Pm< z+rH(lT{wUroTL=$Qp?!hH6NGpr|$Bk^ZDQ>9!b!I-F_<%x@zq&+<0wiw_LS(-In>h z3D-NaRAHbuCN>Wc6(KrJb9C!P6V}j1@!qijH4Xu`kmWH1As|m}4~P&ZPxW^ibj~n*L)a%Q2R&Jk42(=IPS(ioyD^6t1`0JeFKz9RE-de_6Mr3A3X! zC^e7|5Mi8#Z4{DPAo52XtzSdy)70iLd@gPR*@hO_t7knR5ma(wM{4~feu-K6{!!hS z`Q;ObP#G8V06jqbEy`>P$bXB1I42u5vVuD5Bl!E^On8r&fEE(78W3hT#l?yzF%D?Q z-EedIZ}|OM#z9HhgQEK4JDEC#gbAi}U5X1d{M1@L-kzGMJ;AkrqykG2jv|X2KN$Dp z%91cod2V}j=+Ue>){ubAgN34RblX}^L4qLl@-w^TQu2!ww?~B5%S&d4g!QbfYFH z9{sLgb`3-yCp&t%0nh`)-=ZvLfc&@UlbO`0FBil4`Z2*QVOkvR*Wf)M8RqhKQHRtw z)MGTvon9P3gLFrzW0| zjBHW$6;p%VIDckeiA+S8{k&lc5dH4V6ds#F5hyjyT1=^-Ff{g4{jomy+QTfV0yH>l zM48m4f#VA!*B{S7wNRM`>xe_Cq6>FfhtrwzCRh(jKye&%{V^I(YF)V7BT|?#O`nWz z;gLM!Y^Dj_U^JZY*02ilIJ9rt;@?+o&*^(l9P;5BV%eo8al4mp3eShBf#)S|6DkIk z7o(*eo!%_+0tCaqwO<{^Ck&tmh`&YOZvyx~k@w@fz`MY^z`MY^z`MZzoB-K>uK2$- z|CV ze8h%Qsf2jgAgS+LzMMzT{_^T}piCcLnti(cHmgwBR&j%#FbrX9{ zPP5V;(6>5_P(H$NBV94atXE?-FM|2ULx&0~Xpkak9N#xe3tITIq>DaX+S(#Bv?gjw zJuee9jDh*QU0yUvU^S3SqKPT+qrwy49AUXdh4=e}agCRbO(r>de7LqsZG%ze;29oB!`=|*K0u1=qa1uiwtjMG;fGg@O8uB60(-E3u%+fKto#>lz4Ako^)cK35A%CA-7eHd{pH3#Mu*8Wp9t1gnv+3z!fd0SXJgisyR; zZ+2}K~ib-C(kEBMuD?!c8w}hlA?i$x@L|McY@c zOTa!f=Tc@H#CJ9p)+?!9$$qKxNZz^LwT zY4VwRkN#Vf-SVHJMe+kVq{$x@$47x9Y6{rdQgk^iVCG6t9dIMb^fw@sy$hkXbD_Gz zcIS}64OA&FxM=V>4$u6sKwOPeMt-3_<&S@qNY?!*F zHzJD=ODF`nfkvUuBv>nIArB?U(tLED=&?48eZ?C0$2(-mwh23G7feSz`9+ zM&Dr7A9swOkMCS!P>0M54Ik%SiSOhdyvKryq@1z<;^9Oa-Fo}{$M?%w5cJo=ehIKl zy}l%aH$=k%MCD51Zp)wSz1;or+Z{MgY%!Ws5XZNb78yOq=b%q=mi70x$ta%7bD-qw zaWsR|BIJ{XFK~MWMqalb+jN9Ok&}tbtOcw-UogI{!c#g%CNwOc&9!4t9~yL}WmBmj z8;zL`%fABCw7&kr)w=JNyXSuKBho*yAtjjLGk9DbFvm3$(8nPJ*Q(GzjZ3GPDh zXd6g0>_}Ge(?%=!wF2v<#MXC}&Lu8j1$+UTM0&H}gd{kb2yNG~4=#{N-#Y;}?%$KR z|8@_ogYvYahzJlRIlj4YrOq`-kO6Bbfj^3DCz*bYWEcL}(#YI413xT5sVL?-Dh{3I9GHANG(;=@tagw}L(K z9z2xT>ffO*uR7O%n`|{$*R=z~u~0L3E0NI^E&8GBIUQMxS8z^(8j4+GmA-M&7{;{Z8q z1^QLkq+9zq1Nbb!P@nE3t}JxRFbP!TEV!K~6v^i!>%7fasiM2j{QfcMpI`O|2>#W# zGBMf$^53F~(l`?H;#05DY(9{mkjV3O2e{8aP2R!Qq%VIIARdcWAJ+Mn5M9w~`)Qem z+qBhns6xMKbFglAA*9q128PX<@gjzF<38-tDjCuUdxTRtBa)0zDBQww%5t#Qe3SDKvL50N=(#OMkWvuRA$!Fmb{W}F7ef@AAc>mtI zE=mr7Xl?ss!4B7ikPlmueT}sq@kEmB@fP7fM5kL7%xJvHpc@M1lq=d8N%3w7w`BI=Ji%i+EvI31xQYj&@qPR{n*7Sq^{1 ztPJ8YQe)^|843}C$X=SWN5o`&E7@Ie9=!JPPrQ%OKvVPvn=Aw+R&O}Ygx{EHz@#jGd;dliQ0bUHDGnW6Y7(T}y(D@YG!o{|?MrLV zqo<7GLHt0$Y(0X8WS0FB#x^aXo9VQF*Wzcv>ip7lmj^kt?XUxsI9v)!VC0^_w=x~Z zCKMZ&THhxmczJTjaHI~=)s1p7{*-MY2RbEvtT)s7MYBYVTgR>oF*u)LP@NrE!JhuO z+`Sv12Z+B#ne74j?;5?5msa57J1+>qI%|}%*5O+}$xi8hO1er zu=K18PpUP>;?LFUHMmg}d2!E&Q#aD0ejdnDOx2fyxB=Jt$Xa1b1sMkhe8Chf6?ID; zcmZWNUJ|};{Tmt+<|#;6x75Bb-7P{p@u{AI3|{KlmeH(IFj|p&zrd(E{6~F$=Ay}9 z`{RzM?POdo@n4y@1_o#*yA=9C^|Rb&=N&6!@G?=E<(aN!E{qzCNKBHsC)MwA2$D4} z60;r@*XaLwKg$1Cl*Qqnq7$Wgtt8Gca>y^k@H?*;7>!gNi!rRKB4_nZ?3J+s>2e#{ z9PNFYHAUd!A>7)jOPQK*{SR-&t#m%YGuwlL5*$OEPKjt3@pqD4Xp8hK3s2VHPqlZu zo|Xc?FnWnF1>a9r4J=$M)h5{t#zP63xL{EkNZo8>) zwB%x>J2i9PN15H1Wf#uEG_Jld1gz2>!`d652Z+CG^nLyR|3u!8?*i`v?*i`v?*i`v|8oKq|GDD-*8J}XIREcS zUg5?@hso1QB*XN)hnM;>etCJtoPCrb9zUJWtzQxk6^OWek+9YZ(6?qq z`#}C6>4}a?THhCHdnH_1u7`+??D_yYC9Z$r5I$UnBFSNAcYBkcJ z<$sP2 z#woF`0vW6x?55Y0blW$P9A$N1Y2p0BU9A7=Jd37w|H$p2Y@3{8}F~x4|Daa$WZs|X5dYx!tks7rJ zPFNYOZX_tG(kELz;G_4qB;ZhdRH{bSL$Q9icD*L8I%0{HehQcB?tFtz=(`nfDfqW2 z`=5_o`(2~`q4ZwXC6XJ^*M_*Ko6;al4+<|rd2Pe6Lop^fOso37L$M~gzv@2U`{ke( zpNjT0!g+C9impPPCa6&2oSOhS+aiEjDC0(Ip9*fHEU{p4*~yYd)n`i7_y6Q8(1q!k zb~<$+4bOJlC`54kZhntbh>21b#~#7EI&r3PJ5z*;0k1xdoJ z>kJIpokD~vpcQrU!*6}OWEc3C`cg3mS=>wPV4 z^CmgLJ#W(~K9BK5HONTEp~-r~I%QQQ!K?3eigBX@QKyfSRK*@Gi7t45v0`<55@tR4 z^YbWx>ff^!$DjLF{ucFZO^y`PYwnlK29|jGke2$mh&+`znM6IQ$sVHC*O@={fO131-1ANY z0VKdB7%-If`T~B;{k%rB0gkTg&CPj&^b>xCb zRdV-(n>RC5n<95VM6p71YJQJBKMcOgrR?5H{r0+(Tlwj1jxp-Yk@T2)c`2c$TBzW< zns1jT$0q3zpb3b-MLE9!^53FAi2|JOBrQSn$fSE&i@9aX4sb}Y8*wv_=sm#~PyKq}Wjgtb6 zJ8n;{m!A%O;q$v8jah9G8=dkVjBOYUn$CH!Rp zl}AmnOH|h{salf#xkS@3?Uj{4KV&SQ!H!mwE#}yYsa4PgU3&%f~!N7$$eJ!XPW7~J||8^5ADplyp-yq_?f*z@BcaI$`(0xwb zSwBN5Hv1^TxPk)P0nh`)-=gp9|NkfQetZ{r7kC$V7kC$V7x#s%Tct=tq%UAV#^5)??`5PRxkX9;9R5HHGh9Sd<g>M4(mfb8#y1S}` z`EeXNfyB~c>6aqMMf?_>2ie_$cpBP8$<&0L`No=pRxy}Z3?j*wMxSNI1NQdU{(pb< zt;~#W{}e4{u{k*j-fwHSPt?-sAZ*$xMqQqB5}~3Ti&03vif}cM-;rr z^MReMvE-B-k5`U!X)sz`h4|cXC|oLU(4$|Yscl7+g&&3?hru*ht@+w`LY;Z-OOOGZ zfc+VNi!!+bUie+3?Wxr)TX*16tNVg3OE`(g{b2iMF^dGWz$ z9>YE(`8>ECAewf=JPBu(ztz~k?m7Qi2G*|+=M3#)S7GtZ`I(QJ9n>KysM4SqjVAL7 z)bdk1tM$aGBVjo z6A*CPvOhWhIQ%Wj>;ZV~x9Ca!Psk}ko=7h;QKBQu8Ho+X?jb~Saq!wEyvA%TkNx%5 z$YuI)!2)Pu^Qv1ae#f7IF4#IcO(zby$6u;L?2%2j}&7o=s zy&<9W3s+Rm&rC!U{<){3;T%NNW$j#!eQV&wUB8XGk?8^sHS7?KPMM6rvroTc?3(D? zR3kih>K~gp?uBZ=4t~E?V|70u6w6W!(jj-0@e1#3T}*PV6Ed-dp~&X!zeQO*|0$YMx}u9#Tpbs^#6UO7ZEu7oLq4!0GfFATD?iQ#GJcH1 zJsDzRqgajJHG$5YVSWwi9+c#*O{LfsaB8lL;YGSh;sHK<|HXCb&aJLd_-4;>j&IpD zYEXBMJjzh+hwV0GM^&+I%E<Ih-a!k=( z3x9BXl1X*j*`(t2>f+bo`9PkIMAK@}1TK3QJXUd9QlLk zabf#OE)#s%Yy#x#zeV5I|9_jj|9lsC7kC$V7kC$V7x*6&p!(1C{9uK2UC#-9`q) znCu22dZNim@wrp=dJ!XjZ@_6{uf?=sYZ#dm*(*fU{n6mCPMsr|rWj6;PjBmMkSKjMM}%f)Y0yd6=~Oy97X%;F@2 zqTUR&=p3BZXd&Z(i{nPQrxxN7?BJIabd2>YP2QT~;sj<*aX{XO1UGcG1`TOoI0mi_Iw?@B5OBn}$ zwJyP0@cI?kkB*Vn;`lLayIx&dbJWaF0zVt(=wUt%e7E3M{(k7q?@hlp*EiZQ6UDB` z;DMR|j0-otf3RuQ@?^OgR@0lXhpK=1#L6>+!g0=9RLu0 z2F6v*CGzY+`so|@s0AU>hjLLl?$3QntcCCP1El0)mdInn)Z4wnF+L6#H^L+RuG^JH zIJAw;p$VGQm7*Na8zpZC>)WRUjgagXE~?9u$FhJC{!NZ-SKTvNy@D*B^BtZatOZm| zc3DjW8AQ@!$qpAa@)_f;+Ep(i3>6Ij$dA3q%z3B%C{-?2j&Ed^gZ zO~)#3>2_?T1PqF(UVp?ZcWI7G@D&SbJz!`ibhLp%u9X`P_;cHb=nYlT&ZWji z`mnm}suPRCa=+sh?-I*kpRL?9^#fc`obq|zp9=?k6U>Rmb{udTL1z#S?!Gl4Y zDJXsb(Ytv*at?Qq3@_c}M)*&3(2Xk89#YGaOKZqXz4&#l1a0&il;|d7GB3AJ&2xs_ zb+_w*u!aLE=cBVA0w@d8JgH=ISZEJ>Kqh4u1H%*JzDON~Ou(e6$Q}!*d&NE6afF!D z$annC)cDciIF(@3z03YTDj?XK5!M_jE9{fm-?Ux60&_eku3U#Lyn4!w45CnB`uk~_sMrDPzS+NTNNHPNo}L2qVZ(DjmB@E!>^|W;dWeSaCfTS88mi|- zTLEpUwU20rlF*yAFQ$jopmhZP7c!&L!IH^iKKtdb44|Fr9d{i?=9C;(U9HYJPfaO0 zK#u}(wCD&WMNhS)s^8gw5%O|dJmb-&w`S|%E64m??0o&)`a28{=Ty&)lU-2qrD5(H z2Fx?A!rt5fq8x%h+V}NC%F##24j~`25=p<)TP{n?9F0G3xI_=z4gg(nP=uvbSTl*d z*aep<5)z1)&Nhe|_z6@S03R`R7x#R2x_qLPa?J`AeKU6sBZxJ~hX`=QUcqeOryg)N zjA)R=>~R8R4$}8PUYyPi91|9|5%|^& zXN%zQ=QC3Qf`5y0`T_FaqAavjKZv`iM8q2w=ovuw$)CDblAWrOd(uO}GMzr4VVT=k z9gX$v%Z%&-%?Y6lktqqZRDWkPaVvvPh}_{G&OKWc8$pOQ9AFAvVfxeX(0};508y zJ^QFMYn&EELWv>DnnbuH1h!2giL0gA+^v>X*2Z?dw!VGkpayI5q8i>2u}yqtl;XkG z7+-;GqyED+*t!y+2Z+B#-`D^DPvrghF7Ph!F7Ph!F7Ph!KPN!_pDX@v&HsO{VE^u0 z{o#R(|!)nq**4S?`HTG!<0iML_x2I zCCgu4kW=MiZ|1n%i$O}c`)a6YQ%dqW=(G=s;8rQO&Mj}-yzi%CM_iW}_VX*jL-bCK z?7ntO3}MxR_Bhrdtf)-XRG)2Ljddq8%g{i6sSlJ_A#9J-D6I$78-(Y$1rIbHU=m1s zLq4;_AcoWxc4e+muRiLM#>t7hmc(}vLx!pq4Nidzd3LuF+!k?sh@kCo zZ_xvuZyjq}W}tGjh9a0WC_>~A3xDRf+4-`L;fSmnR2F@*n-3N&v1!*lQysjz%e5LQ z%u4fFm5%u*2kIWH`MC%OQ9-+?rn%DQr%rs*W$B3O;?%fA@$GPV;aeNq$v>a`1$c-4 z>RVYD0|5DN(Y!C)S$i-6dcB%d+%1OTsi4rfB&Py@M>BOuZ z%@5^(*6r35@DMf<%fNOZC`)O$sAr($42#CDTsX zo48L@T=`XJCN)l4GT@B5R+d__W^pGai7^U^Q4L}DZ6cTnIK9aoOZ2B%L|i&fw_Snd zF&DwypWpxIrWEE=!ug(gi_)O#kLjwlZK~2PCG`s8Ag@9$y{hpfN5^Mx1`EpL;1dJ< z0cSDh=T~+9hc1uxqkvcz`}xLCo*~LRc4LEtBfxQW{o32KmkW&2MR|#QLoAiWt;)G; zZ-X9e5;F$u75c^`3VN7?IvVB?Y8G*zZiC#jb(5lNpasfl{6*AHY&3&Vt980p2-;8I6BkiY&J{PNWxU z;Tl)Y{bO@$SW-aH$n}Z*2f+=6zGIH|u##3YcaeJX@jU~MGh;Dx?MqB;%`8I* zV=;w&LVZAuW{-qmPI(+6M9Le6NUs`kHz}b80*&;>={v2yuI|`2n-z~0K{T(uI(w5Z zkLe&3#nE~mocA`-BuvVX$~^*8T7~b?-a3+E_0yxP@b#0NMQB}zbELd_#JjT#eo{j1 zad4&iRuHV|eWhKBddDz{!N`g_a^T$-5sh&ReO0-`uV_fw!mI4pVg;uZrOJ~sMF)16 zTSmJH&;!KZHOd?W$bZ);M92W_`WUysSA3ZcH49oYZAM`kDR%KG6{&;IlEiT9U>3LF zohnRVv-s?@mII(X7xPLtf5iE+W%N_lOrJM}%t zagqDl0NZLQ8WhMP>a#w%dCj zR26EnzD42zR_GBYSHDLF-}-9k^6*iChi~t;Vz~|8Qo{wB+4(k3!4(yk%Gtb980*FMVYiT#YA(F zG;}u&HWS}%sIkdnsSPd};&nZzI}E@?#q0jj(-YI@4G}D%A&2;u(l&=t;`P9@MKN6yUeb*&?DqPoNz9Md!QR*1I!CU z6+U&W^HOz6wo^K7d1{WmiD&YfFqqtZGWW$O{3Clh=t79ssLv!Rg5~RSzH({zG&+9#=V(w(AcknH&Z`6 z@UAr0JPZ=ek5)=uif=JK2N|VlD51&s^geJj++8}gFQZTpq5koEc=cxH8hHPCcm6R6 zu!a6pG|tf^QZuE`|3^^+!gX7GfYjJr$|1jYSCmTY>ktx2W<0ChkKul@T3k6YdY#9e zkI06PpD(>wFl;G?Oh2XIN%M9p9-7qK6zQU`96+eHkn_-OeKqHJ8H!b^c!qlrBW|wf z!RvrF($5&1yjS=jpB6Y;*2q$4*Nt|w%&uD0{POyic*+Vw`iv*O6d$sM5(QE(HClu->W3)K5Kr)wG@EV)`MirH9Ut(lwOAen>uela{=&`(GKj}f2FkN6{ zEsz34)nNynD!L4(7d^ajXvrNIubw_cGjAX*J;D|gjxWlvDmS}fjN-Og7|;z-BWa( z-S#l>*mh&5vCYP|+t_UE#%XNZYHZt1>nEPUly?%Q= zW6U|$1BA?v1=$=jDTf?S%@+ocXuRJ`knB&DNea*AG30pUEP{lufa$e3K0FYg3-i$k zkC_Fj{uDEo*toWqN#3hx)x0A4h!la`d9d&+!aI(w1S;|GH?F^4TM| z!4ib|_=DqR3F4CI5gKaq4;Ys7aEMWH@lc-fyVdBw-fm~`@L)yQ5+0j0y8~9fSXz=_ zhdVq{U@i*ZLmyVW=1(IM?xlA!2@stYINtZcv2q<@Ztc zB0gW9I$qQlSkBUe3SXnCV@gyEpAAKQvD(R?1yzA*u(>duqP=I^UJ@#hF+JpWy9i}* z0ngl6H^rr#TXk|8J(Cj1OOzX6EJvNI4iJ?}CPa~fQaOsSGj9N&HLJt_tRIx{5pqPq zZMvj#hJ>X@g3c2Zt>p3KDGKoz@#EWyc>AV=zq4R>l+S$5YD0IQit$_43RE(&pWlUh zY2~>@RV!jgn>X;i*@#A!rOqh@BZW39q3})%k1GyJZ_z^qgka3Ce*GeGyWp1ZEM&H! zkf>&)s*)^?U?H)XNW|&^;SioAK7T(m1t9oG^nL#y;PD>s0`CIv0`CIv0`CI#2=w23tA`nvrAnBsB{pH)rL6<&7kLo}>omQ%LE|Vt7oA~b!^`sR?+r@s!hJ6e zG4`oaMt|m(70e0Ng3TDXfp9(Rg{N0 z+H%3$X%8V->@dEqKbd1!SYtoUfeO2AmwuzX*3RE)(d|;S*C)sY-E&EbEwf=yjmh!F z=drJ-<@bvGzq*x$A^e}BwLt#coEw-o@P||q%*nk6wxLUr6f5%vRN6rOTUO=@&jM@3 zQJ0okMJK?5Jn)nx5*ptF*mxx4ko+^dLjQWIeQs59Eko0&;Uo1KGu^f9mVi6=*%)u6 zRvM)r=@Z6o#TsYYaS_r=YHt@YrrdoB{9|e)8@F~!qkhO^|()G$P17HzH4gqBwJcmIRA3Ts?QfNOMnZSA`fET z)$7WdNff?{V*LBfbO6CWqKpy$6g`ol*+q0E@qCO%Y?^E-16eJP-Ee@L!0&cD*BU>R z=-z{9tJN4dJ&p&0=+K1WQh(^Z-h@PYQWc}d_&7QjW|O}a4kA}7S@H1#wv>37zvtYy zEP+E9!%`Lq-||dI%_9A>vj$uBRp>3%=NH1`kbvWCN@JhGW%ET%X}lBAQs_#4t-9_Y zvbDm<*a~BHJ}BIVn0D}BK0p+S)xOAnZZYZwmm^DA5Cq*UH2yL6Lo${)+;!jevHql> z9BlPR2)#CUTiP0Tytz~;4k^f81Z67THo7?QB}Z>v+8CoX9WQ-n93Q{ySUV+lC+JI% zv*i=<-N~&I31pTJr(=hn$m&xsP z4Lt9{muIR2^hYM{ALo$YaHpqSPes%tM4oMAtW#|aifW~DKR&30RfI1e#xqr1d&bUtcf@)3sxeiQp=O^big-psE;lb zz9kk!w($P03tidyDMqQs?cGuUJwW^sWsU;mzeQ2ibG2%eQh1WYzhg@+E@Dl{s~sAX zDVN`?a{KUbkxs$i)9nMtbby)hz2INtRriWl9%<>`!FE{r^jjpp#DCL>;65nh!f5pf znRw1$4LAT#{Q&jE;gl0dFU1yD?)<^K zX+j7Ky#fmjIfvT$RsxF$uM_8u-wJg;3dhRb1gA!#mX1<6%wsRir4cJW3-v}nL)x~& z1!;5G{SeL0aQXlWn~O$gJ^st?YPjbZpa+OQqVN0v{}OpWz6-nyybHVwybHVw{Lcx{ z{Cmd#t^Pk6F#hklH41-SB7N)H`NxoC-VS!&8np@M~MDQXlzkG7nTXFE+8j=i+@dHz? z4x>E?eo`H!x$w}0FLr~Hb8rF@{)L}m2`$>DZ=_oc`*amlBn{GdmK>gJT_AfBv#%MK zf!JQg5}nhB2dGDc!9KLxF76plG1Tq{DcU7`xKSCzb8lxgf7>=F{}qM1tT zBHo9(1Lx^#?rB6!6giKEYT0Ha?od6s+E`-VQ+e`EdW0soSBN$n7q*SJ8Xn^fGPOqv z%lD`aWh{;nvG*CmDU<>6 z1q#1IBkBM5zw?i}l{My{qF6u@blrKHOF33Ox{g^4P%dn(n#&}^-xy9T2asCJfn}j0oCwEw?D5qs@xaG<(P+%)hrsElmLZtT&{!w#9WTeD?9+8D%l18uZcT zTc#@Of&AO`4obo20NAA?qt_2V4Gtja=Q^N~f1Dge4U*ATOLN`}g-Ly>s~Qywj?2X> z=`cdoNBkyA$3OC)qHMAM6h(m+ry?{n2yp{uf>7SKiQ#q;Gw6>%wOH44G?c@U;};G4 zq?iD|q4Zo9!y9X$;^e^avTDEAZ(dyc8REom@b0S=i6!g(aM>gC*>R3 zthpOOKv@zG*Im*#1NpIj7t{k^^TH~Eu)~@9k_Y+}F@{|oEj)Q(oiVANUo(!(Kj#Ql zTr)B~mC^M%+=a_Pz5ztLcnnv7laKYzA7Qj9rRj=~B5~X0K3oq%ZLXNDQVuoP#(PX> zd;&ElE3y;nK>p&qNTmg<@vN6L$B09UQ&?VeR%3x|S`%G!jWh0%WE2^vB4r{L>)68} z9iZ=?(MXvO+BLliFGmmRdAEGhxj99>!bprGTou`i0Opv^0rD>%v|*m7B>W1i zM2J?DUu|J~`<=KpZojG_oQk6LSm;O&z>k|A(>NDJYM(7v04*-?pQ)l%hjYug%hH3r zra(I@;kY|ERFa&QDuf$%8Ma>1`I|UL$8*#O1Z=;8;%YiHCe? z9a6387S=~GXz2XYNtzMB~3fi6Ps#JSDO%a=b zu;Uyli6w@lMH!4`;k-yzk8@s-z5hKbk**%ohjolg{4h9Hee(E>v=Ik=sV9P7JhR5q z7k|Tal=WUum3zeh6y=Ejr)c(Rv#r#tL#;~x3wY0GK`Kv>EOceo=Eqcbxw=ATNJf)k zroeT4r0X^6?m68fL>oiKc3C)v3&PJ+wmG8GCh5r*)e#_O0dW##WhXv=z1Nigw%GMi zjgVY&3w{cSWi8ORf?_{hqxkqt(RKi}X4E^g|K+Xk2fTY&*<|Ar0iI1GhK-rtk>E)g zv{88nO!X@$sLq7PvkgGhsbxH8=5Add-qM|{kXC^fn`JVTiGJ0-6$Vn&m11w_zn zR=CkUfq05Z%9s>3Hceaa;31BhzQF6na?m#x*dUvdgN15^z5y}abXpjSiBEPt@nh^W zsgtg_MLdy5gpg$JXxUq5MpzuFgFs=p95JP)l@DZsriLBxPsLEbZT`pdY@2P^C2;O@ z@K~|&6AP-VUtHM#Df+(u|J&sK^IhOw;9cNd;9cNd;D1bj_TTgUZ}tBPfboC#|5f-H zTU~AE5x;1gP$3PKhLND>RK&5_w4v#fG>3?*DhCVGqPy}wfior+9KXp7h_FNWc&Od0 z->LftqeY#H_Nc|6tgO-Xc)z*D2ejdRBnYkCr=*2Xp+SXm#l{_vJ`xL~X;~Nev8>P+ zVCJw~?=%uV7+frp9A6(2`uVH%*QKwCCFQmSHzw-p7&1o3>ROHpe00=QVt~3e?WRH; z_GCdShh+f%OBD3@+tVafm}WsnCgO7N2YUmR)0JQ)LPJsG1KA8&mnu zcPfw!YdbB>=Gd;#2>m@}WrB2#Q~K@J+vNIU;qne6aDbFIkbi>;4m8#rQ)?_r+)?a|;2V;!@ z{6_lWJFY-8(6*1X23eq-U+c#+-FnVG+fbcml-wLu)`RO?iMU@xZLZbS36@D9J^i&O z{+)>vSE-0>nmgrOpkg7+DNGadDP_7M9}~F!h8lFiz4+6L+PTtYvOFveW;*a^;6(=W zt7de%iY+ts$Nr3$K8s!}G{cyJXqHLMre!^}$sIS)$oN%N0$k=%i^%Y!CgjEhLA(@Co zQc;J2eRE-tl`7-{p*8WbsNpiBno|%xOG66IXD3I1@PVUK{1`J_Cj*RheFJ^T;)mO; zCMx|Vs|r)p0&C}}^wRuF^IbVXwLiE&SV1B~xuMTM?B_vj{SNnyiqlc<&oLyw_~!5w zK9F_Gdo7{h^#MfN!%(jp!B_;*g4X>XbB0Aoy?%^eHRqZ%dqKV>8m`xlR@lkEAbrXC zdB}2+TKm9NavHi)0-fcdvdy`zeeZ30bW7o?pO2NxqQ}Qr%RTxsR5M1?5 zBe#+NeWrS~0%|?7-IEQN@|USdose83dX6N5X!{tZ8w4{l=Th*v;6^mnsEZLNAXe?F zd`lIv&5mn;9w7dRG9?4@-=dwuJjEvjwo9)9!x>1P9s&EB75jj`IOgvov+IO!+Ffb@fs+z${l=xOnH~ zh&m7eXEArOGI7dZ*a1YP-#i^4sfRuZ6ZM33PRiQWG~)QCvYqpJU>;_(hSGmyq)94r zE7!Yplk2)9$qevR*gie?V2a^XZt?=uYT_O{Y>2v^t=@HSELWIxM?+7ZIzmJzo-H zcGr0Z?sDH{If!+usO@m}tZK=WmHP?ayK}ZN%+yQ2NwGT<2xAYwxNW`lSqwzYS6&M0BAusvI#e1{BI^Fq6WjC!5)*Ge6p)Y5{Qb&k4}|d&d8*{y!Bk z{_naKj_Om<$3FZ!{Nm5i&Lai(bO$rX-m&A&QwUT=Y0%#-k;ZlPZ@Z|KVfbd~z!4r7 z@E>EakAAeP$vH=fnX=b6@82kebmW=FB>(g$7zxwy%7)yD*SeV-3h6MSa#qG}~wAC8#8~Rp~&Y>6(;e5Y(&lprQ#M3;TH{#zIgz z?wC?7K=8%A#dIo=|WPWYbBck>>V5-o$9`?I+q@%KOmUi|!Ts zsS1hfk~|(KG!xzjjX+!Ht-(n1zH@73AlivcExPEI{jhOnn|2zDt<{#h3{y9dLGkx` z{8P8Gru|cN!v4l(lR{zIxL{W72L|*&xla3(^2sjdR$tNUhh%{vnjSTO8_>v+FILSk z7a2-n33Yy0;cGS%Cv}L`R5=m~A*PUmISWRyjO<+udMW9R(^jy{>wLuKa zC|BO&kh1NKoXO6&htqC7btia>nY}>AtYPT!b3zWRKlfEQk4Q1t$v=q`S#LYc@MCJ9 zef{(S&Nu0Yauv{EEL%hjJC~?K!^y}(61Xxz{xoUL62k5 zgIzwazRJcVRqKq0;Y`3Yu_#B*ftlc-%2YsV3ZxCAaH?Gx`3)zDey3b)u^<{60+p>_ z=QdF&XM%EoATuXARAYlsGnggR5S?O~PWmA#h z)mle(zgsN6y#?40KR8$BlpN`LFNY+r+F%IFxL7_zBV5Q{b%qG}45tL%EZ-(lId0>O z9rVo~&>-WbweT!D#N`w;aTYfd68+pe#=WVOi44z0L zxe-7&x1z}Ze*fRh@NtcmS?u?eTO~Nql0u_Y@3M8-*3Oi&*IYXtF7`cyZ&FhFOc;m) zt6?O+I;?jgmewL{>%#6dzs93plP01%kpe#-Ylx~ZY|Tj3=(slc#xG%YCkL!sPnErK z)oJw)&Xp93TFB>+)K32>sCFn=G&CA!CHGt1ud$tU;3I`!7V-*$^jE9gU3LlFHg0pgD+``>r4|32$;BQaE`kg@&lau&%#u?f=I5c9ez+VG^>sx6`}9LjmO zcxT<=k%I}ic3n-NK-#uVe2LVnAW1j6xZ2~mIOckeS`+p5;=1DQjB7zixa7Wz$pL}W z;){FkYRMZget+%=pw91It8dbBxUIFbrhqsbf#k);ZHR(mWu2Q4Z~w#wzcFc#t2ft^ zfpPv;uY>9e-Di0?#D5N0qq;^iE2MaLBs?`m;(g*WSoF(ne9a{VCAeF+AjPLU?jGAz zyx;xl$axYyKsi~*qq-*bIF(cw!&S2&uIN9;?yUFMajeu8$2<&z<0mBTh1VVX5GAH6o( zRpS0BI44RUUti2N0DQi??D^N5_})BZ>jgPVu$Zzj@2@jE$6k?HTC5F%@w7R+)~MVj z+jlz4A}c2#1T_R9up7^3oK<&f0HSdwJ0-3nKNWq6pm!N!9E_OZE~epEyDa-l}yX$fP$rQN+LK)g~*Ck$5u`P?F$7M`#ly^~nndz;QOm zA*?qx{v=Rh3$U!G>0Mh#_%(-60i`O1!{zPgAm8(CyQ3-5jd=V#1Yg#Tmxjh4R}+Yg zK-w9*p5W~}`erN$=|0y}7ZyMd5P#O_`~LsGMBb0@0`CIv0`CIv0`CIYv0Sc8 zcQa@r+<9YLQgxQ6=im@D;J7^Wc`AFszE7YrN_N(Hw@cXf{QLCVJ_l|(DXGVzc@cif z9!R->x|L(REnjGw|D#^T% zww*e?Erza|p*v<#fP)%eQ%Q}o41VN; zF9*;A#Q)W;Yz%+*TfaruS2-l9Rs`TJNp#olIf}-oqAe%3>1ZquP$cFvwoGW~^%{8h z_-vd^@k!yOSo?>^$1hb$;zNCaXU0{kXjCb6|$dn9dt@EQ#G+K z+o6J4{a^&-9}gu)(e^lb*HMet+-;I*B1M;D}pIYxFy^deAjZmmg5LB*SVN97i+y+j_Drig! zb7>vm4HB&X=KTLe8FK*N{T9VmetgzxhN``}z0f6$6>MnB^s|?6i2cq`8UJ>ZIs@DA z?J_RbJ&?NE$8*_)tsCDH(5E z^TpmVG@aGHaHEf5j{)cjZ%Xvq>R$qVPg>&B3SZm4A6Zf2XX#ctGx;y)!xOBvn65^) zKt_)2PuZ<@wJ5NgmrgmtqCy@)TT4}5(9w=K zQ&uB|+Oe_;{peKy=mFx-8fD4_(Q1OKgu^<-kMF8X-nZkN3-eJIYrY#P{*T9 z7T<%`xCvbr7kyIrWh>Fm^iYUO3cLqQ#GkVV)u&M^o+0_Yx4tH~ZgbBo&>#d^!75IAwDeq-;pdM?=1t^};rw0O+84!iQks+z@ynN5w4?WD3I$FwK-gD;va%1H z5lopIF_GF6n|Li~ASvd+gx3oIQLEI&&{*%}fvjSo3#9{@36w&Pi0{Vic1jn8ICBP~ zc}3v3j(eO%={9<=bnw+SCJ4~Qpq@B7F0B|GmwK164L_>C+9F)Ps>e_1CWIrsCizaA zLj^Z-LLvo!m4HV020U=$>_GR#%hRGG=XC1=_Pu;eUmbtU*#HKpvCo4k^$ui>fxeSI zPi!;;YBO+R^*2*$C6l!-U5p?0*)-9Cu9$v z+f-K!pWC|O2h_+7-sTetx7C>M@ID^0)tbo+`HO9JM^C zhjOE(^H*B0$I8)hIBiwa$mzwL@G;+E;?d&1Bi3?mDpz6QzUR2u1H%jAv{R_oia6-rcAHBf z<7gWPvvZDZ5qC7h3GP2H@(X5M%@%I&p<-7y|z z!*f-l_+vk2W-|K8?WyLX7jMAslTh~RywV+ z@S$qRwZa4HR#M0xXga-E`lA>cEoDLcU0bPk&aDl~JPfJA|B${cnIWHkkPT}UVZ#dM|RT+a+K=`4C&h?JH zj(Q#Z=aazLSPT9siV1fTww$uHsKo%ZR563H3UVX=H1OA55X(8!+Sux3x5aCZsNrZz zNzw%fpAR@`inv$T!_$!4o5v-TSa>Xd_R}!O9ld(Rg89vy9z@&Phauaxq1}_QXaCrZ zd=mY@fgKuNo#QmW$*ND%vGGeRETwi<5^LiM43i5in7Olh%`y-^y)N?r8N1D<<(kga zb=6YanYdG`9Uxj7RlS;4;DbQ)Q;wcb10|wjA*uQ6=GM0lx!~Nqix$m|6eH6K{6z<|FGxm6@wgCQ0b9zG2vhRPqN6PUXoYgztJ-)UvIL zgTqe7$Df)wR*fvo?8NXGP2@O9$NWei2BUrCAmShY$^{hN{DmwK!M^QB}s%`+;H{y z5|l6vb=GT`7R+5m?JH|HRkxy=>>HW~6v&?fi<=&v8!p|&1rc$qp{q_=h1}-ih4KpyS^}(*z?ZcfUk=+}`HIN&)9a{g z%qUV=6pi9H0$_Cd)#Hl*(WoosuzDY6OL~G4Xt;_AMRR>J9=+Sgu)f4iek(cIbFlL? zC#5A^E%zToJlV2GpI6{hSNrF~lY~`JJr1z`n$`D}q% zF@j{GQLa6F5gdR1zJllEc2lH=_ie{%v34kS*ug0j(Xt@ zGgnH73<2_e`h0i&IptTrgKO^KIMPG?N}+{f{O zJZ|LWjU05tDj?b9$?5cJwWDd|C6H&JF-s#QV9z=aCv922LUIII@khOu!KIwqX!ZQh z*xmGabsq*`7$j$E4Kv?p$pE6`r5eCA__`jxq;@{#RapK9G=daX-=5e-qsB+Go6Sv0 z9!!ATJic0!hlWx@B&V?%$_5IoFcNPjT8JdHh?7=?IC=2kuKG-TS#BA438k?{!Bvd0 zwhyV(-1XupYAl*Yc;h{3{}^xQV18$z;ZWC!&Hru5YzZ?n^=;i}%m zcU9-beObI?b1?*+nHmS62Z%pwl%p7s|6Zd`Kv(*z-7c!^?Y4X4E?SG~2%vD^$4@Y6 z6lZyp`Jb*EYOWjOQ7`mQ6(k8#o(=-GI2OXLJB_J3scx0Jv!Ku=KO{W+3&x_!)ri{0 z5PmoQLWdX?Lx@y|({5S%I(In?dM|JLAf0;sP~rv``C6mwNV2%|4Y;UB;3pJ1%YypZ zb7$V%QJ$0fM9R(i;aGj+9D*m~3wJ+2REn5J^f>1#&X+y4(w+!=^A*Vkm+U-LDP~60 zEHR~G1Y!P&`gJ=2sjP8ScV-YQwb|SU9}L2<%!l3Hbe%-uHH5hmE-V#vqK?8}{}(B+ z2_BXMh-Reg)2V%0xOS`vH)kvxUrNag!A{tNou*7+1}YZV-lJ`woxBgZ#PFJ-&4smM zNLwz4v4%2x-UQir4Z%XY?OZ50Ko1aqMBn%S|0VK%d>42Zco%pVco%pV_@5K_eP`r< ztN;H25dB@Z_Ds55BYy!>40WnzV%f5OrK#>yBH)${0|CxyNL(UhW!jBVpLE{{v?UvU zj`+z0%oid?2St6pBMv;s1SL`dQOZLcp54Y~KX}vlF!regJ2Jq23i4#0pvO#iSza=7 zHhGhQNrVq5GX>g)O@Rt?65c$2kVZmryx`=B=ms%Jk%ZFV`Vb?M04GW}alPAAUa9!X zfh67lP`93vl|$h!QYCfo4chTOsvu2)72Q;&g+Y=Yvh8PY<6F5sVWp;fl+KH!XA}26 z;?tVn;(tHik6U*+SQM7>&OD_>rGSpx5%IN36UgCbNsU)fwbT(A&^s2Jn|m!604`P8 zz5TUsY5)RS)x6`~B2CBvr%Io;BnGZ!^#>YrdIah-X%oxS*44aSOy+)62X;P3=J z^uGlW66+S??V^2?=912EtXeanAId*eU=YD{&QnNO?aSLP(c67l=5bzduhP_RE}?*- zJL~4`sQxr~IKbM*8BSrrU^)JZ`p{rLCCwJl85hvZ*)I6TCv$w(i6s#6A!Y!5uE8PL zo90DR4~n_}9w18jan?)iR!M|{$a-2EXS=aDHR=pg?64fWN)G4xU@?>42{Rp$}Q&-G`5)qo+TnInUy0G_Jpe z0tb4OSp56$34q`qQO44LiWU!~U+UKsdcZqUoRo(kV5WtmUG3u#d7kWzxJAQhjUg>f zmgZLevMzaB^aK-Moy_)f^48r$Go_SOoDbW*(Gt}At0AdDV=xu4T&fgktRU2L$4|0J z%W{Qo8_!0T5lYPBpo3HdVl5@n5IP<{<_`EOw~g-k1Wk=@-}uc$wDdWByY_(A!J-H~ z!yOzYR;bu$@Ro$37a*FLdG2F6Z@vbq5Zgg$+YHfYr9Wb+h%A)?zR z{_c3n{rYNNRPhAR1H>OurZPbO`>Yp43nZ2-HQ9FGdS=+q*RR3SN*KB9R9uGHOdaZZzf(H_LZCcZ zO=J3L&&k_O60lJW@R@CrYe?wbdZ~KLm}$uX{~Ark#(5|Z484s z(d8nkpP(rso=J_(ic*sS=mFx7D04X=|1H`;ZWKTAED|LTUJPZm#i@7KV=B@i=gQ=o z79PLqT0u$Ai6j0k%-z#oVwRXFbC2ES(8?)ln|4gNJQb@8v90rqXG6;lJqqzBZaA=s zV0>}PLG=wb0@`>A;K}c!I0PKvazr!5Kk&EV1~vN)?!n`61!Xl&P7)*Mx(;aFY1u6d^5)H&O-Qn?s)d_Zd( zzhXU&#t*4WM~Kvv-fp>v-f&V!Hrhm`) zzt#U&0LK4ax30^Al!5U5a+!in6;2!qY$@%YS%B@;(JFg`=TTW$itGyYG*j2^$!gxu zZRKk`Snhop&3j=^C;|~@4Jf|#6klhRewOl@7MSVPuiWlRu`Wm*las8LH{Y>-sY3VE zMe^6vI<#$W+9WLkIcSAp#k^Jc5O}cByzX@Ze?$1oUx=C~6RkB?LES7ah4b)BaF$s> zpgiBk3!rYb%~o`76?{`bEN_`)RLjwaO~@nH@M9x&AYBR;ekJ&%4`g?;lWoMa zkDRbK)Hx#%I?}JiMk3;^ia%YW@vznB2b}6~xl#SyUg8N%YMF6I#0*n$Cs#!XYAAxB zG4F|NCcxaHi4ALo!zDSQL&U=M4jg0S*g5fyHpiFKDD7>{Fs@0-N=nl8+_cVOz-*XH zt&{rS|IR<^R@TaYipt~P&wTZf2yeq4`=RQ$Ze<|2$n)CW-sN9c)jSgkY(;G7RA*-? z#G5cD>)jg6_aSmIWqAqnX5y(O4;=?rx)PWr(Bo)5BXj5=KgM8$r^?$3Wn34joPBw< zZX2RMUaBP=q91Gncg4ZYQ&sdJw%OfEr-3H%I*4>;y@k#>ro(yzBp%%VDsi&LXcSlJ zTb(xySZ0P196&TzL1LVa!GDDS3Zc7mI~b*zEvw-mD3f~f+jH}i0D-1^)RQoouWtFB z_OgJ4z=GP<&8k>aW|~`=8m}b8?zn`yl22JUyZ#W!HPzw?bXs=$TO)lyls!q3=!TFj z)%reFCg`LuD=eB(y|ozd*R;{fEcqKksh~aDPgqCgvXLlE`aPj6Ql-qIvhu1RCCN@N z7M~hmWsLt*l&$KYqJ2Pn@w`lWc{bGw+Dj0l(3?axRRu1pwQ`y|&h_BkkEP(T5a{?h zxTm`^#a!X`W*;09`J^rwcjNP23*Giwp@lhROa!>;;1WS2t9$6ou_(G-V|}ucWDIY< zxn0kmZ#>TM7~h8$fo35MQMM}^#@ly|^$5L?V{V>-)q+3Nc`c3{vqb9|3-vEeEt6?E zDZ2SKPfzXe07R$ptkw30BD_HF10~wZ`ZJB_eU@CvVJbm&ZQ!%96^E-Re6P{)%YKPU zR?1?m_WPe??s7?z&VBQQA2=Gx@0Yx@Z1Y-j(r5V?IH>`-h92`g?EbO9GmBXb9-Q`N zRK+LN6dOEfg2e6Z#q?K`t-4G0jZ1_DDX2osG#ph3fx*(`bN9X~MdZmcLZt;W+fw!~ zYzw|Z4F3NVWv~9H=nVJyx0S4ho1^U-Lo|;V^L6UD{Dqja&3nG@$~072kEu`Wy5u!) z$XMd=HHuK{i#h1%6`>G;b40||y&orrjn`?~L9Zy`0<(-`GCffmL_BtkfU^%Z)yZuP z2XJdP*+r`}>OLr3WJPTWDt_|6tnT-|Jku8DNX6X2NFtVL>>IH0y|@>+#Kv1}Cux3~ zi$m_&w?O(X0uY@!a0i#ZeyH7BzG#>6SlULti~Tg7LmhqowecD}Q_q8|2jUrOV7~rj zDYrZo?8myk7l&}sXeAt#)+2okxjmR_!aD5jsNBaE4WHH4IaD)p+9O>(4wr|3AC8kg z$-Q+uX>bfR)L#}+iRKsNYGAWsyS3BIsDVO9_rFL!_vC`ZjdMIkE4YNumCYPSQx2fp92d0l`Po<{U>RwR{w@@^*2oUaf{kKj3; zSgV)kWG4+rFxlgdv0*n43_ni&l}%dql_aF9_Dc$N^I7kMuv(-+d{*2rD4B~!Pl*Cn@VMPc;ep<^h@@1boT&>{Mb-tQ5 zu;V#~2-#s^7Xw835l{_Z92hclC%lPlro;!-@wEv{#~bNJ#5em`pZO~OdLZXS-9%0b zn&PUrl#^VF-E<=}3@C_8<0gbd&r?&49eHlm;wv9Recd6le*o{XhoU;G8wM`65!H-E zv$)y(4=*;YPej(P1gqwcbr)Vc<|Y_ZiNwETdtG!>xTFJ*GR;I<`e9mE;udOTov4li z#MGUWJbRV?Q}liR|F_Be=exkWz`MY^z`MY^!2g&4^S|f&-|GKs0ptJf|2xTX;;8RK z=s@H@tbpBudno=8yLi-MKDArH(6En2Qi>2zB5AiE=IQ|#EO==})hAi-j}f(Z;h?q@ zENR2NtENM{T<4VWC&3jvD!n|j;DF|@T7N<)$Jy`SBkG`)59PqWlJ0&)U5*pb6IO4h zF#lSlHuveecUg;3Yx@qT#zRCV%f})~qTAw8*vy2jN_M>F^M{>{NFG(i+cX(E|76 z(+yo0EUSM9Yt_V-!N+L-;n~coX&r+fp*7M+8`G>FmmDqf_4y%O5AkQ-F3$?>Ty905 zxwN(|lZLpzaoG)%qh}bA8;^#O?!Xd%`@TvB5_HBf{FqF>I&i@trU*f+YsvWYr#3*; z=SkUZ#&q|xe&2xfu$0p4*UWaIb3e7#AZMx#(;Qm}>?4@Rr>XtD91(s=C*e@s9mSSu zK9<^2_wYyXpR+hkM5bcM-wvM=^zVnYLpl;a&@dNZ6K_b>g65}13Vg_D6osk-f4+_U zQaDCN&yC4;7_LoUp&tlMcd@JuIcBOqo)RLm4&ReuGa@^#IVF|cpTIhczEtz~bJPKX ze?%GU0r_uHM}ZN}Skq5LymE99{`Ezf4XOxi?&f9EvcP)9SZxynZC`HrM&8(aX*#o8 zjyf5iLcm8CQf85~Y?Ol5yeJQSfi}y@8f))0+O_ZoQ-Ehwq*H&kUN!L!WmV`8C6G>} z!y*x76&I!!vo44k_2G6Byc9VuQgOqM5yAXoqh;HYs5z#h*i%Zt-#&|7B7J28le> zY11_YsOkq#8B;ThVpIfK8EDHP418LxnyzZ497v#uEGHbg0Ho-V0X*u#DxoU}_%7Pb z-@QIS@Q)}{10eq`dQ?px7XR^l;gYZlgfN6l$ z&7gV!=u_=A?8DEMv01BwbmueHktmE5L+D6~kpSb6Y_COrBp+c!=}=!iTg%Z;;%GFbYW&Vj;5Tf}_!rVd61t+fYTCLpu41qWgvAJ3h7`H>at)}cqE(VH8 zUNygH!(rtVN2!{x*^NF0W!R|eXNwN_fbWS9^F*qz@x39%?Rb&M-tx@^z!*}_dwV)! zf2$UQZU*Q9;*ThEBOw1RT3PDd+h`(cqorel{bm6xX&7NsaUIqo4Aqg{Qws@_F^Nw! z2-mFmb!$FgXiFS!rfP*hE4pr8c~wtCoII_}++Tv=&OBc#%#-(RQGv4YyL@_CeQ~eP z;*-{tQ5({of7OAbGiIS75n_#kEijEm&pzx&?%VTJXjbGoGn4!W#B@J1L&aZ3(dYvS z-+3wLEbcws>UE(0en&-{B1DnDB@xM-a0uoDo*d}K?O43w-Z3UkWej@@OZw+~O=ETK zvC(~QY{w5op8c%oD`U?=0fiA)*X7<7h6u0|9#ran?CeVi@QhxR*}75q1a2P2b5z6- zxD}bX)1nO#4T_G0Y~N_3F^Tz4s?{NfQtXzp<7qq6*HW$Iv~nLJ;;ly^j5*7mpJP;s zmPgI3MNlvD^dA6vfcPW&zW@I(k@w@fz`MY^z`MY^z`MZzoWSog=)cwfHvvR{*R5YN zZBb?h$lzjCoi?gC`-4Da#dz2*NB6t4!-wLcO@1ltcQ_^m5rEt`=y;D3@MteMlWxVD zn#1&j?=?QS3#qP2UhoB@93)MLV0(;manlCcaU$;*B;hXeVkGM_W5-{{AFul?_5__` z@BWZThb!{HbruauNt`rJIfZCkt2MjqvoeB^fSzc1 zB9_?LX|J)Ra)OSlqKmo@+#`aPb^6Aa(oscSeY9lcr;Y>))&aF`dgvb;Gu;BKR`6>$ zJ#=U}l)=5|3(UAT>XsNTdKd+JJfapQcE?^ZJJb#xws z-q=}28dyeq)?RjyFRip^qU!Rto`-}5rXMD&4eqe4ws+$2RUxuf>pBrhySnYl)=jl( zhge@@VCLplWKU6r`e$T{Pd}$*>U}5UpK&R;pv$7TLpB0iahB?4M!tI%#2nl$)h@;W zMA;rS5DT@z@rzOJHik4`?j~_^x0n6rr6zZ4(37q=*T2CXj*0TNF=9KiUNEZRg+^S( zCN__9j=0ayhiEbm_9!mR=|yE%GmMfCMTs%nbAmi!CBuq%qo1UMu4)(hI%adql44cm zKM$gD%Pp;`cna8wBkI@G^v1LU36cfuT<~6?1Z8R79%boX8AooCci1#FtT4LF{ii5f z3*fuoqJ4cGm#-vAcCy08yiI{2v#@TuT@Ohf@-2dKb5Ow~W#`we2`pFS@Nv@mE|-Gy z1%a9_NCW*Z+BJJk-Zn><*}TcOv0_(;)drfFIVu<^jj4F_^1(He(RKT(xM!o#2828b zpt-7dDkY8{CXJVo(_zc2CS1;XG1RaR#6Z*6&;GeKZ>)KWO#BtykK20*V@k=3HAfVu z0MWA*J%baS_&uJ-o^W@EOP%T&&G=TLV|2l+hfgXc1Ewrh^Qx*exG+Kv<9K=^*_9@t zv(<}h#?j`UJj>A%ai?P6c$?R4<*J0c7>RupP|qx zNF(ZC2Xa_!wS-(ZYfBL6Eci6Yx*fSc@qQ_g(8)Tj8l_u$vs$hWoEZK_a}t2Bftaz@ zhI@HuJn(#@I%nX`VJ5Oy-;_t?q#NA@X3>A;V^?Z7ySc4R9+$H3K_cmml@*s|X7!(< z9Buy;W$ThQp#TMusx@wGqb3^xnCpDg7=g1Wa64zBz- zgiinV*V^JM5>ig2qAvx4GY}f__~3S+vF#dD8of z14Oq;X<*oh94ZRPeJA>vzDFrlm`txy+=T<_#+|GZB zzVHA4HhKSi7kC$V7kC$V7kC%=9}{5x_k90b{eL@P{NKHmt#KNdTc2axdP36+r3%Z) zxoStbaPniOQg3+g>oPxLt6l%|Y+MOAs6-g4vbgluaF=OFwmPV%ahB(!yM4A8>FW&? zq1xd>A&7Qc2rD+>@nL2f1(qNu3!NyFTLyW0VEU$R+bO?^WoJAzSJuT-rCVUovOqkt zKG&O%R8m(U{`bP?0~#G7pK=o4c;}GHt2Dka4I@?o>Q=bIG}<2XW-+Xy6~q6>-dzRN zv26*#aQro;Q zYxo;THWkjP0*yr4d=f*GKyd9D=pp?Q=CZT7?v|y|$IV8~buej()A%en%4m}%LAMKG zx`9&|T$>MjtnRFx;h2ZMd~Ca3$tn_RTY+pU}u1n@1=wPoDbOUzX%BZ5Y7 zt@1mCCbW86NL=Qh;CL=uQeKt)I7uq5!j>k2 z74T%ek$w=cG$UwCVZP5;co=x9kT!kn4_~t)z+Eh@l(wfPIb}dsHpHqcfat(v(mdZp z>xyp2%Gmk!8D<{*^*Jly444_wm_EAn1Z2#f^jZm6Uy*&Ld$H{cYX=jx1>gM6#yptK zb&uFI-5$^%jhij1X=&P?JzBPp{H=We`r|kEyEyhw%_sybbC(bYJ6!ZMnIFH#o^9~o z^?3DKwuLv85#e*Ec^{;x_v2I~qY}Ua~%SeWK2x?dMDQI{acjr zSKo@?cRhe#V*#kt)A^G+HkB!nPHTE}v!R3@O-fk%BNC0o$-#uTPwydj&KT;sIivSl zXsH7sV-F_XAxuA3XJ)i)R9pcT81IS{dy@$E=?_i)K8>nCX!M>MmesUX*<7po(Om|) z>lMCAnoABXwfHqMam^3%=epzMfo_YG+OcHeQDpq*sfoB*L+8>50avy4cKoF zOf&J2-b5kw1BWY$9SGT*Kol?P0l@N`A1pE?#xDepa)NUGbdfPt)jqKb^q8#s28ua^ z(Fq62wX0O!IR|GGLVbmVA>8R-BJAzsMn&c*Ac4?`h)=m~{$T(NjpHx~fui)yzIew= ziZtW6O+%6l5&&H_g9Lf8w<3rqEb2?Yq!HOb4zSFYzAt9JQXC~h4Pq9rj;A?yc+ozh z{f~dg=@GkH!@GkH!@GkIQBEb6hdH$#B|L(Wr|E>fw_tCJrSr>(C zEM(?H4dWv^r*w__*Y6EA8U$JO(zE}}Ec6*H}wr_SG0kEStIoANwOWo6+$6hBC z(#WeOnY}*;u6MVT&6$5KnQZ5FMij<-5bS%%repCEOar6F?ni&iTjl0C!gpn?2KHE* zyk*P>py4WsEw&lI5zU-dXAm%R$ip37?fYy)VcYeIqC$r*J;S;ywXT5_Gifk3TM?vX z->}LUUBk?1k5H$c+EK+Ydrgh5mma?^)1VmWRT@9c4dtoffqeZe+WbR?r?YK8Dw9pf znX9$$WQ`-NrtbhCG3~^afswb_2(>h)=gRIVHY69a4ho$Z_3x|mM||FL0&x0gv|s3yQz3Jo zt}4Hhi*PC`_QM2lX;HaLWM^S@qbfzSoCdy$Dh83ATX6Eo z*k+2!TP;8JS~+w;942RY_s;!fk#y}wuM1z0FZ$wZoAa6SRGQ-S<0YutW|61ORDusw zU~nXL$_nR3HBapfalb1kfzEN>DOtP;P-YfXUPG1@I! z7P(M6F3#MtPYotnLAC9~W09;rk~AmZdGphSO}w-)g_Pd<#H>woW>g93o`L8F6{iO` z&k=>l_Y<6)e3N5*O~=7`aJ?Cne*ZB;#op(`bfe6Oy#}vmo3*FU=UDpKuyEoNwfvsq z(Tj14pOsaJqViLgJ~h%2C%+J`z=&)GzIL_tSnJFkpQ2>*;1iO`yO;5SRlkYqn?5_& zgF~Ar@5S`;V;)C+`G^sU=mhFwxzFF-3W2Gj*0ja2gP3)SUB*!W$KmnF45+)B(~^%X z5oRaS4k}u}Gocn-KE=Erd2`?d^5e5pZ|sE6tl4qAA$YsMj;f(ODuQF44o$el)0thZ z9i_CcPAl1uXDHYyNsUjb+4EMfqN+6qAB+3}n&DM9v8JOwpn32(J)``4jYsT9Ea<3841qD>B$b+LfWRhmPN6l10tc zZBFKN?N}5mM83*UN;m4LZ!Gk|BF6$&4wSbk#*oAwor{AtUa0;WNVf98jq>a8nK*E>jsi&{@Z&pR#V1{5FCDucGsTXl^{ZE(QqUB}Hgn>-E3iw9Vd*S=n1|S||Gip02m7z* zR=;DEqN{n0IeiqV@nq7KZ%m}Lp%0zBxOFH)E(1~jlrvAJAK^Gm5Xc)Hl?;rapORwA zcO9epV6q}VcXsAxF-S{Yno5T$4yTLy5FE^=$xe~Wgbx$!8%zb1*J{=|vS&p!J49y+sw54S7O5^65eN4VCV`I<+9DXEj|b1;iH z(SSvN``O-}s?i@rNQE@O8U2omT1_gmA(?jgQb(MqS7vw4F&M!o1jLz~yF{FE7{)H> z3Zyx%1V&$%bdXC@+qS9Lxks}3$fxI8Yk|@|#%pc(uvVv7FnA(6TdzUw*J7<8Mxh2G zQ%DodFp6w@Sw`gNn}^BSF4|???vrm88JPq4^N0ZBq=JH;@10YJu`ia z$^ZQw703Jh|C`7Aco%pVco%pVco%pV_%9S-`}>^#Q}zGA+wp(rt(TsB#LC<|#vrWz z0`5l7v6qUnB+jlGr5V_GYX~{45>1YI@%ymTp?V zFo!lg+}xEWKRHxRP|?RHklb}*oUQR2M64p9X&3cpk_CPF)vfL;dB0Uv)QDn)=@w+} zvL~tLv@huTO7}TiB-%Z^@>hTknfgR#Qp@iS$Cw~>Ao7k12omKc2UA4N-NGh5%ut=P zCsdf7Q}PC9-Yc1~mbqF}!t-RydxhbU!gRSdx~0^W5BhX__FwkHQjD@CvV>SZC`AY$ z?Q-FvZR=%>N2c&V1@k15)*Z9CYoE?2&_Y*d>Jz6X_3!?U$lrM@BR&1#pQ0DtqPNFu z)0KVAp?a>xfoLdO$pvfGGEg6N8-L6KC|D~8u+BP@^f4s)J;&CaZOK!`AFRp@^!yOg zFv+S6m6%H>bgqIoWW>ws7qCRa$%1e@n|JZB6em^VsXW49>U$t7HMHz5U?UYqnWR2Y zF-?2YskuXTi-Eb>MpA>HN17XrB~qgW#m5PchHk%5a!%M)2%Zn5EPAU1GzlidYkP&F zR|?$sn;`kA!sQ4ADV}tCQp9aqUJqa**f6wS`C@Zho^$)Ith)}X%Lk5*t6>n zX7@s692!K#A`5De3Cf_DS+vvQX6Zh%lT8Hm#Isw4+~>F2)ef{L+=8*woY^8hBSqY3%7Ufi)eYGHB`#ZwtX=>y--k)zQem#xyT*2 zqsLDR?es%O@{e$=Q~L~}2S()wSp?EvA-1wXDBP=i+BEL*)IUB9o7a; z4ICZ*rO{5{mC0AnnL{@6llKJNr_p*W7m!X5DW%>htlFEsskLr?W>;c>2(vfQ9y02` zS}p>rn|_SeT`A}$@Z+;fCvUGLsr-O8DLB-beJ`+4PP4^ zx-m0eZdbfDX6ac!Jg8-3CIwaM#XQ#dk<)!+q)j?)ztV{CD({scoF6DMpqKe4*XfUC&tvaLwq$bNIu^`U@1)mba4I z4+AMY8Ds0!%8&iPndz{=97~9Pc#A=8t6+Jej&~X*TY+XJ`s{M#zFLd`R(v1S`O*{w zR&Wfh*Ml^fq!FS<78ygzFP;^e@3DwcAfRyZcsQe~ll&VKKlA6cyKcM4JRlbaaLCYR zzKKeCAOGNWF)%oM23P)A@k6{Bi0zALcj7zH%m5DsPHA!>c1U)Lxj%SZwPA88wAi#qL9!!-{2gaKW7Y{0Q}? z_cs0!Wg2PAB6`V151B;x(G@wM1Pm2TOTgV* zvcr@{$@SB54-i|tNr}%Ou31>ObT1>ObT1^(*<*#AD`|5W`y`gZ)^d8tsd>IP^BV5uo5s6l*rTCRLr+1+s1=peTmCb+aQlId;pfswktqf_$%r_2kfH z8+FA4!pG_z?d}1>39O?CtRMIcdNgDANcUba!Tt5Zlnf^__|MIrmZ@>zrQeP<9IY%~ z_C7OMO1rjV*@t*w;}XJ35_MM4e1TEAC?_{O6{nAf(y74kR`BmPR^5N3$#DccDk<)_tXV^y&jSB5|I-&g04yp?6_Pf@rz zS?Z>cp1pZrEusw@$KCbN$~uTEG*AFSe8kgRj?vmP3C}*hs=!wTVC@kig1nfhbdWC@|MFrO!x00QBV0eqEVfQx<>9M8{pxY1<*2ZqY!}Ah$8JJ zrwr!wJj&AxS3{|Ne@(wb#2TV98@ZU@`A=1y=W21ticx<#z#hr!cFsc|kbV=b^VY#? zKm?UG3B|13!gggGsC+^D9Ff;QkAsk=$J zIW}7#)<=vmuVlR0ZARa-B&e_R4Z9$>Vrf}GN#vVIl_b)F=BGj`iC_P#u(6 zzhgA2AaX#**JP)*OOqD&{?X#LG7n%Hl!c|_DRa2H>rezLWDX=(rUS-QBhz3QWKv@Rfb0NSjFu6eOYK2-nB6Nt zwc!*PA4Ll4UmbiSExhd9Pd zebnUd4CZmnIN837#X-wOX>=@p3Rd$1wQ6P}h1U zyN#V#G9buW$5ET?vD)u-=nEJ@allC53SEjF9&2lry4Nk`xkyrPtE=w0@QAYT`s=(c zmu6q$W>~81n}i_Pu`3$u3~K z$2Pf(3JB7!ZN1Gn77hbAMV0b+qQ$zi+ntG~F&yy<;pxFioo5XQ|8vho3 zpa1`D^8WoU@GkH!@GkH!@GkIQCh$8A`cKvWQ*WNXYb!!jo8~R-uS`mOUM8{>w({!n zn`2{F3*RRhy-@woBaRnqhweIOqniVcwil$(K7B!dE=R>m=$-$VMqLsvI7GGVd;gZVj?|HHo7?~mSRNV`^6~X!SFWPz z^VOVl8~Mrt>=wJXXQzpZ0%C>qOJ3sk7(E>II3JIt^E9C)KOZPXS?9*}(w~M=+wot* zeg}z#-w#pZRYEvz&Iu`0?Bm}j#zkN}oua(j3CzKevTT)CEhVcFoxxe&e0a+KO4bP^ z1xRwxk?)(P9LMB<{ zsJGKp7e9*aX~HY?rzt&~38_;zj)uH|@go2!RG-8(!7;vx-lG$sBBk{;LL60%23?_k zD$}EUK!gwY^vZ`8xWqu&;I$?i6&!d$#U=weX1B~#J(zJ@KxXGgwpfjnWp9B6HM{)- z5}>}fx3cFlMH!5czO8n4@P$P8*ytTShk4%Au1snw z(OTL|MF^%$;mod5g_4y8xNR5Zqb)vE3n(ru`VH}4E7QLT{v*mT^QS1=1TX4xpe*5D zGSwsf1%8D`^AVT5MB68d3f=&Q zP0baplPvYx!&eLVWBn}MA~x(;H1qk@NBbt(8ThgSr5noZH@&y^)XtbM&yT1d9_?2T&a~u2|4=7sZ-T!6`LDTRx6*dd>2Q$-b6*i0U$#U zPR+?l9gv-?#r61%lMGPz#RjXSQP^=IXom!gwwC!=46Z-i7ab+D>6`42JL_mf4Khzu zgHx4u03GFlf~`Ikx3Xb@3ew0k^B{EMEMk8PYwFf5y#?h6AjWMLj#KqnVrJj}Rbz=bvBMdU+_D!x^P19p8=`Pg!T*b1%={Jo1nv)xAAE0mZ{r_PreA$4 ze~VsRwtJ=~PejrlJvHPcV3$byxdn%9^u$b@tV}-pQ0+BqeLanDE_zaIWWfcA9B~w2*0_G^>!vRXM`T6mm6y#h+&cTGQ^9{a9MRKYLuKu5$t6&9^va(m~i)$hi4Y+)CPNW}#VBpau_N z3BIbGt|p^47Q!N_opc{&7ba{cSh|B#%Co|ye^vRGw_a1}g`X~mM?SkV#0TrL0!Vlp zm@WR4G)^R5u_vJ0%VJ;7=X*2@vrIUx_bGB{5?&Tl0$s%YV$GD%sKBysbV)^1<)Ot3 z=|H*H7aMU+CRlcs2+H_L16wr`Q3<6R;G8;#=%vpn&Vzv%$ra&>HU0*7s%7Qj6i5b# zfp6vo%jaiSuxe{D)IN+KE!~>SSEk=p@IGPLm3D6$*0SzA%V>*v* z!ho@KCRs#5qT^Z{R}cJpGnd^GoiS4e*5g08Sx13!$nFAir9p6bTvMvPu*Q8t`jJ8T zXu6=Vj>C9T^vLBihUfaB!W}XvwqQP(lvCDS*M6LHrTEwT|4nBaNasdm)=yH_d`Y>j zW$R#+(DDQYNfadUlw^;Q=4Mo6-2&>GG@{i^iq+{aJNlE`%8b#QR=i|xVlatG{M~{# z`WFp}M&5AXwmxFHdA7?F)I`Y(fTrVXJ1|j8)MW?&<(fJ8(+z>cL8-{rPf=v--}-A; zFg4WuD-1`J6RM^)xtBHeKfCkD5e+`jV%L{tYON{={9BZD@lR2ORHMT73N2jJ^dfx4 zy@#Qsg+gX$$_;B=w^7o)8AAuVI6#0cclBoTD>B%ZMTF~B7^t<=V^Fs3SWog7uX1H7 zFl3d@;J#*<=~Vt8MFC>&B_ni^Rr-QdY1%F0(QaX|>DQ|o#VG~~N*P9ym~s3F#6v5x z6PVG_O{LQoCKKrw&JAbki#}zqzZx5qtoPDWzs>{Mwq(D>XzvL^4}`32T*`D@5qax4 zPZTYtrd56`E;~1>WITAI-yFPj&gw&9Ar2I?x?PwCE$GeuU?sTR_@uz~lj0L$ ze~&8+mw&iR6U>*@pmI?LE5hfAxSX{8m{#VG{7XX!d)DlT=wC`_0sSrH3B`w43#XVw z_m5;ajFEZw@?OZKnM{b7D zI;JD+P)mH{o<@>paTbV8#@h#hPgk8fH82z^&rs0r$lGZF#(ZLd#}+O!d4R=}l8Ho+ z@QXA=gcKzJW^?C~ed^JEUKFsVb{7mHy6A{~kfHI>n+DKIy~S&D2!BG}%=?xpBGIaf#Qp>9*E`|cRc^<3c+HkbBwcob2L z7f^~_+yGN&rCM6_u#0`DnG@74alCfA&ITJSm^x{qirN5%=xVaHBQcvP&yji?CuPEt7P99%<88o`$Yh z?1F?}dq&<>X}69}RA>v2Uq2K@W7D(RtRYH{#L50VD}!U0qDO&fxI+iRN%xEI*anYd zn-qG6#PbyUva*t@?ZVf>XSWVj(t$K>5o-cL;E<&v{gTbvKgmJ^qSeHC!QN_$ z*21pNPTsq6;KG=TJKm=@YkNLAr!C0-mbZG(onz|lA1|HYZY~qxa;gg=oFWU{1^Ei^ z0^QrAC1yB2R_XAv=pi}4QzoC20ACiS+vkTq@dI2k%I14>owP@r8Hdio;MuDV1d?4A0IH+0; zR5{TvUklYW{Z`;mypqenbdI+j@b|^}qY_}G|JBR-x9CgU{m{r-mmI+QHasW&LJ0?A z0rrjW$i$03`dlJ{R@(vnF;=T#W(kE_XzQe-M#vMUcJ@YT6kvSojEfITI(%20z$=7; zc1STdVX!wDfK);a8M5yQQ%k9D8g zJbXm>?L9#OtbHO~>J7WI^5J!o9SC>@6#dB@e{}-0u}7-wHKl;q_hl{CIM`uAidlpX z>yvQVK}-Aa36Qr3<6-+$#MqCi@Iks+!LnO8LJg>$6!iOn`pWKO=!$dhSKv5bM;@ACjH;qijiUUZQpNE{?iJLj_MZY*v-BU z+SJu?51m$?evA0N)QbY)ppOAgydU@&!jMIbpy_s3Ip+37MP*&ku>qu&Qy$ATeU3H` zAK8@0uG}=ft%vT*OTMTZmn)ND)V%B)#MUUZkVvAH;uN6gz+;X=n>*3of{W1)@{KL3 z?ZAo6{6IIad5wA*6-pI|%NmNY>1^+2zav{?VHMY<5>H)ti&3)hTavricokg=>Zua2 zE+i;jXOjzu)#HypgWT}W9dC~@NC~agRhsi;zqRgjp;4BjijlS`HM_ctnn- z1~C`oq01R8P&CoH5)gki!PU2Pl+jgY8Ug~6I4!j4%DZg#41OJ5*p7PqYpF=SB3Q#Orv}EJZfXcJS#lCgn#u`V`OAp`%^T#mL0L-)6H4D zBwr(2>sn}I7zK)ls*peR_78p*9V<)*)cvn|Q6n@8TOA%ZrL(pr zu<*=J#LsDwq3JwBrGKMZh7Is1w4a77cTvjYhp>T)XNsPVHhcxR`sAhO>PEAES>ZS= zATl1+Odg;0?oUsr)zxYKlF=#h{F*(a!ZDj#TKoW zw$V~;ofhy!PjJrq1^R9b9du0;pbxj*0Hbz5e4sA~JqY6o-}K(bKQYR*{$6A#_NHMHpRKIM%%Yp$MqvlEKQ!D$ko3Yh3A z&l6!+t2xx=i0vAmX)fC3$uw+zI%%WPntM$HAz9x|Kze-Ovz7V5e49C0aa4qL9#)0J ztuRs6wCXB`1dTm1Qk^(QP7w5Jkf4FaI$DlJNu;W~aP8;E&A?LjA}*$i^A@8AM}v}P z3stkFXK~}CejowC>l8mE+euK%N}5ZA3DiZFe$2;wck;hfmWx}g#vcL!;BIoO`B_6@ zx3R)!W<$8xpHvab{y_RDMbc+01r*(=1>2KX4cSTN6;|Zjbs&S4!;2)6AZr?0m}+?k zvOiSKGfaY1VVDilqIFLdB5r>s|Czs^4OS5kXzu7U?PeaMpIPPY7_Rdu_50s)ZE_idvN1JL z+RW_@#WIyiv*W*fKGd6F#I?&}_4Fw|CNr5%A-KZT7`xU|ju4p$p_QMw%m*qlv$GwHJz>im zhuyXT52`wSk0Y@>k_28|5@>`$x0Q712d2mOyL+|mU;Y0s876~byUIzZ2UMhE@DGix z(s@YN;R$vb0L!`YsxN&w>_r4rqilz6Jwq}(t5R307VbEG7{=?NHH5WSi;i8@E4FZ| z>3B6k6vO*!DI+gm!KttJZ`_x-)jH0VH?{f6@LA8IKlRUW>~oo+UIputV*&41-uRPnbc4+{UcDC^drqFNOPU#d5Opp1&jTw$-W z=lI8w?}ns&Aj^+eMOSDPuj~z`$TslZzwwS=Ha9DKfM7Ny)2s=eH37#Ga1k<9ZH+G| zLw6%6;wt8(ynuR@Z(~Mic3d_IkT~JklPF32&{}S|KsD_-S#6x*05?GQckU{OO`y!` z$6#H^GSnBd^8RYK=gQ-wRJOd2*UD{_ASKh2Jf0*`cp z9rUS;Kt*22z5Zy1AP#=HS=9)QRMZuRwVzzNxpaG}n3T7JwRB|G?ifqj8n%q+-V_lGW*pLD(BId-(V&zT&ha{f6|j>_ zYdz{X<5^`~jmatCtD0|w0)4tyIf6+CAe22aDK22LoLK+VK)LmKM4=_}+%VQZ5q&T! z@f#yZ+f&<-Ex3G`4H&(ZkhdIPef?3V;20~JTwGcI;wV7Io8H^_N0j~73iiMMk0y^l zcH6wjan|Vw;dJHPr4uJBk0x9bSbTpV`_)uVT96V%vNooR$@xj^$bXA?q( z*P}IdUov3^R(|2gaK^sR%c4c<1gtvs#Nh1XH=)*o42XfyxGcfMy^D1E+)tbjo5ZfP z+RdiSA@xa&HGbLQl?cq!>MW4xrue!&YBU+eVaJ_6z}wJ5m(K#bRcq*qs>D)74)2XL@M!0BjBme!7$?{{3T- ziTG2!d`slYNf~>Hq>V3u2TAJP&^%6rvY|2FXk$fj-|_L~f{*z>)E1Fm6w98s%kGoc zv1$}CB4y1zjllWtn1FP>r1z8J`=zxYL=5dH2@wCh)~4M*iKr%4!oc{&`F}*;=l_43 zynnw7ybHVwybHVwybJu73Gn=VzW=HE|5pe5-+61DHT1%O589*|eGQ-r8(AwfoS4$- zM|B2&vRU$C&K77g@fa^dom{NGnA_XbEHk&YO*k_Mxqym*J@3862157GxbEs8b~F8s zutIVzwHXkT(U|Ah{KiuQhZ@8V&d~zopF0oZlF`AHo?b!xXgdZ7p;ItOmDcGkEVUaQ z+A(gPayw{){4iEN^cAD}2gs>Y(&_aWA z-9Xi`ftfY_pdJ}e_yaU;#AvT+F~CIBxZlzEzm)(J{odQY-=a*jD)CPYMON7b_|UCJ zN+d|8JqQlH#o$xK-_fWCy;mom+zeUKLwK%_ynZI0$YyAm3y({`E3JzM|ph3&4pU z!WAM;^Ew+%ymEG6+J!l4xq@mS6M#gcxcOmL5qVS54>7767Vl z$Ae&%gkSJR?2?4W{DHkKPO*{M$_Jz~YlwbWkDeIhZhQ9~P;EF_dr@cF7E$4V*MG(x zJgd+~4|W^hlZUsB0(Y3a=1O;Y-noBxX099NqEPNJlFlRrpk%&leO5M%Zrw6U$y%{4 zoRYCbg5iXMKf4EFfK6*?ta7vW-dT>5XLtH~Ne(LfZ&8N*KSfJW3A30r7xFy4pwNUE z@-@^R6KWNPo1oPX9zeE_4fch~o<6d&qu#@W175Xbpd;a)$vlYdsi>;^PccIJ&ivFs?u;1wbu z*0UR|NHwD|@8UWoU^N*0FcOlun`QD*-EFGoAfDP574t1dJ6y?N?76<6uS^M8;or+D zpAvcdF!-H2PG3?Aps7?W*V)@gm00O3Uxw@5hS?pPgo(6$I zNNA3Tz>ctD6A&apc|ol|Qh43@iO7DI?rF6HFUKH*Wm3F}lE!Qu=ZwZvpa3uaJxEkh)aL)@sPj&>A^+r_;9UOa#e+ctH&# zUuEQnnyC?xC?6$>zo>4EfCe*v!CdZZVG|J5dwG8TruR1fx$Bt@-?o3>^|o^W<#Z#= zM|2LL@`APvv8wl`Tg>g{?TRbsW@;V7XhH&nV4+FlTHe{>WW!>HB1(btln4amokX-; z;YW>u@h@nT=pb8YGe0+QD7quX<+X1mtT4P*%-jqHq_NPn2~!{VoZE7q9dqn&RWcEc zhaw=T;8^ zwYcz<2n~k44cwJD(npRvlN?@k431DqI+6gS-l(RkNUs3K`|f(wpC%~EBA=-yGlG0tPtTbX3sZXTRghjPMS8&d57taM2yWI?nV!n|P*7U#Wy^ViF-{=4TN96tU zUEp2dUEp2dUEp2dzfOSn?=${S)&IYGS^v&kgD$MX6zT?25`*Y#9UBo*(-0xPWiTrt zz}xg!JQDfY~#xXh^`a_;n>)B%PD_N0Ei#F(* z3pVf27kxhaiJZb94W$nw(fjyguKhJ-7`Rx4;4Zk@oKjt_74uY1!=hP!86k21jJ8)^ z<7>*uEUcV@ z$jFZ?cmdDG7+1qua6R=z#4*?%fL3G!k8Dm4j*XUkfIRaxbO~7#5=k`=Eegm7nENoi zx1%Lf4MJQ*=a#Xllv&9S6jSykjpBDa{*$+|9KY@REqaXCc1F>$9zDWSf*T!?7uZ;Z z*6muZeCB4x|~qk;2ESh*A0#`F_3}|f6c9?go(>P^K?J)oUILb{p|j}5%cNK){i?W{lDVh*(Nl1j8b~?E8fPu<$;@8Je z)nYLS*`|Mve__bFrZXM^=d3ArmY69yEc}l6E$(Idnz1Q?~ zAI_exS(_(iRsA@8HR^NNvJsa;=8sf2YGo??LTczk9DIDZ@jfjiuGsyD4U^^mxMZMn zn}QWwpL_4thS0Kba_G%yy=J)Vv4r4bdF>e?f2~&UdV0(n@TsBB96AmPgu7l;7;rR! zmVPV{@2F;>hZ2zf6)3TZctI~4c)mzSwNs?&MtR>-=933m2D0qFR3DMh69Ap!;ePHX z%tTj|<+~G^*pPT_2DwwBZAdelTd1`Zy-V=64l(|qYy2@Lm5Br_4p@7xM z{JBPfTp{ePJQAM4$XiV*sD!Ym{$TjK$Z28!7G*pAQxp-rtk)N6z0xyJE^G3+?#Rb# zytYPe^FFp?iK8ag1#x$vRl*+}3^-l12>lm4dxzm)G_ z^-9&?@H61&ITqIo@symWmYS_`JLtB#KQ_q}@ z{#ZY`o3_$Okytx~flU;$ms91>br7YA;a$DWj(EH4SGC(*`2c({^M492^4y;th$AVH zwHloORP+ve<|ae146cUCq<(Sm-F4aAlWXM$A+9gB$90dk=yf)~F|e&!98%8Gli0{0 zJ^0}Eup)OJfw}de=Ox51I72qAIKEnA@ifJVytkyTvF}i&d{3VwwqdpBdyYqc;w=Ih zewsa_QrP(jkun$8RUxSQS8oWep}`d*#f$cqe~Yr8{V7WEgQNUg#XX%5+CzC)o@Dig zT_tBA{+#3yW=T?VpYDQ82{#qh4C{Tz{g9ed~Ofm*oMMN)l00>j`e|q ziJABXcFEjxIb|J@pM0{A0Y2If&p#l-9JMU7;2YjV2{mapE(zuY3qEbd?lZfkHYqBz zr`1sdTG+uu;vGU1h9BAmIHMXtE z0W_e>luPK7FhO3s7R(zo6%C1^-SPG2F&xbc8{t%9I%#)~l$IcToB5h}%@0oN&c@x-X4}vF zY3#O7KN+KG*;3Jh$v^d9RbRqm^x)ci?ap-(>O@0~?vtmZgzKtRTa)Wgdxmf()WVY4 zPXbb$8dtUQyydO(Q5mhmxGyNF)5R6`Bs}~XqU#H7`D@1A3wcjm{;ZIY9f*1o-gpqe zyOq5xZO}fx+eZW95J5tF@S-GVZB@A*D=UQTHFDq7Fkxc-c`Hz`N{7(ROW^W4=F_=H zJKY%EcofMzNwsxsAJ!my%gPR6({q#E2ES>?Z=3Z*fB}Uh3eU~{z?)uZHQi8~2Z0{? z^0}Q0)U51xH2!b>&rJXGZQpNExveI+q?-2pJ+<{d6Hc~>4-RZiASmeuZQ)y>g?^c) zZPG*l+`-`@&OB)C66)DkwOt#qGQ&Y0Q612f<>rXPdC$d}d7>s!AMlURFSZOCHmyDE zzbk1jI69&}*jkj6G!XY*Gohf_sZsdl2^OB#{IpN@i!VM2r^{@C;iV!0x&0Wk+Jae5 z0%*0YKZAB~WJ~0(UkknQCaQh7A&8>*$VBH1plXCW%`>BqK-->(ma*+$AiLCbuBCUB ziBjCnZf3iLI%5w2gh!U{7QNvFLtQ-(T8MEmM;J%9nqgbH*vj-gZ-fWrx#c#pX1up{ zT5v}Xptx5E&=|+$t-!lCJ&~WPp;teK{CwFzNLoq@9%h*K;Yu#*3|t6jL3^5NyYnjalh=JjAclgGHOaFW#3`63ME=JX+!}!r zmie?7$U`#{_w%ogKKn-D{zDtt!+Y*P<_x71&T5+VV1PM3J6z8=lchY6{+Jzh7<{1| zB`R_i{-th6L_{wkwK~FYqOwuPUX&NLnurPk?$z;gH06hV_lJ>NJV2T?4dpJT*ISI9 zdde|*5}mwkNkw^KpE3tEqIqYGC>WPH$7>Lu+Mk3xc;UDSTje>z$|VS7r-32(+u*>S zz)TliaaVtHwPL%G@ub`c3&<)QD+vwvVYRJ_%s z>|sWL{aiGN&_DD zjfY2!vs_2wMmZjdfwsJ=P)<^=Az|*g39$rJ{Hg6sB;8UZ`|39HIQPt%nWtl#`{g)?DkgewSk+wG_tJ2;mt*$$ zFV)8lytIHFAW?14G&kAL+=EUbtg+M2H=T`i(mQ!ncV!u`a8tzZ6eGH^=u4^2S84;7 zZq7VpGMeUW?2@p)!lgBdpBfRpHvaLaI8|{EjRU^qrcOJJaLck)UL!N6Td}e#^^Rs6 z7e&cC}UH`7y=k-y5zA-(>(NiwM&2W0Yau@yVZYpVAy8aX|yQ*{Fx_>V_Z6o*W@wzaz zA6E0fmadb{*xcbA5*x@cS+3Ay0}^$){*jf{vMs_WT~jS6(`oC?CoLH-;02}?zCNA@p#8nxr;L40cG;g&JDw4{QO9ME;{E>4*j?AZq?kv@1=Z{gF6(>h z**p8@ytK-={&+pPT?YarzSfL|#k~FTKsfV!+wsSXats)_%=Z zx5>OSS8;IalhhwP4>DdDd4`XaHwnoHoZF+*C%Qmv^PU1@gS_*KODbY(eq}jiCaOL# zP_eLRjE?%KULN)1^Z~;~-$VmHA8GH#szDr|lj$Rzi5~r`R~zymQ_f8;m5#Dy zW5(QD_NumRdR%Ujka+al#hQD4!jYSA{4hDT^2MW?=N2a;LW6JJnWcSlyegmT5BcO> zi^tC8XYzdw5`XF5skqCR-^exVyVOI=`>VCic9CwcdOl`Zv1hzx;L9wTmTWnH$2}!? z(%Ym&>yN+W7ub=T^?Y^URJ-LqE6-%}GCkI(WPNq?8xx$UH|+hC#;7vizuP^!wRQUM zl8pRb^HT+X_t*XKw4BteyFsgWuAK11ZV z)Mc3seM8xMQxBVtIp_^VkR?jBN)g3ep2@a^|7_9T?k2=hA!E z`J3nUZMPg)RnB;Km2|dWWx;Y4*>U+Q-sx14j+S=sZzj(3ZRy?x5vN;g3gw?T*AAHK zSx79-u`p6lf9Nrv*?90+*q=6wUmJ(7DvNb^7EJ#=rA+skp)l7k#?l^x=5LBRYO_~= zclRjFzLMH5_x*(Lyz7c{*Nd)Lt}Oauonv=pUPhw)Qri<}HC>yQEDk?)j5#l1;s_3A z11>w(wR;{6a`v)5v6k=76gSrWcYl<-1CvPHc^~bKtauN78I;wyWW4Tmy@>nn#5Heu zRR``Br&lZdR(8-R>fGek-03{hF7m~vsKtFre2Qu;{do8-F+cr3%5@3X-0sB>dkDXl zU-Yq7b?>#@j_qXW)^|6Rq}|+HREvGx0}T33&;Af}H(7ky_MwHX;=x{5_;)q847*Jn ztpT4XW0W(|NdFiCO$%QEe#g)5G>MdjQDN~hX^UfnbuTK-SaEl~w&Z!P^S>n`luK$| zX`Y42x+#@dsvoXlt=dpXcwU z;2*fec;PdR<}Uh^JxgB9u5#)*A?QQfvLU@LYy8#7=Jh+vrzYnoL=SJ#n(bzC>twW$ zd;TfI&^JQkV0Qd`#ej6g3f(n)3cL;@4NTJmBBxrChp)!%@b7mjj}jc&Y?^=7F5uHP z$J6H=&D#+%I6<&l{>qi;hj z-tm18ifK2s>OMu?U65DwBu7=NI_-DSxBb(06*ipjrN%r;@Or9QUAs8MVawg=*-86O z{Lmjuzu@lXRQLd-2ioK|%KQP0ZKIjDt4&!FahBdw$ttd6tIZ<$l^Xl{d+N1*eHvG> z8R3rDv07@MP-H>3dHr}%%^$9pd2vRkNo(wjdo5#o9@!n9u3q|HKaJXGV6DH9*FWs` zdZECQ?V16LiCQuEO|H1ujlZmp%z!EG`-Rm_5!^TU+J}M6tJ=Zq< zRUlwOJ+M4^@cqhg)p612`_kg|@2jnvL+XWkKmX|5X_CqRP%?SEd2E|9&&o|V-X5?w z)H)qfXL#*)+VEMw(c`D8<+OiQTBQ2>R<+!t2rB4V1n(8^ES>vtc&%=SSa~V)*S7Ol zMj8ycZF3yshe}sQ`y4hJo_Xo<%fZhUmOcvKAK8_>>M=YvahB2b$BS}`E*@Levt>t` ziB#II*b&cL`;RcpOZV6?E9_Jn!s?O&n%>$l-(0$weEH{hhtlr;)vF)I#$JtFqgWhy zBYrIW*{S^^mAz6`&vwPkTK0T%A$Nk0Xvw$x>G$UMKKr%mOVY7g|H`>$25L{lcg

-mxsB4*esU(- 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 literal 0 HcmV?d00001 diff --git a/dev/config/lnd/regtest/lnd-outside-2.admin.macaroon.base64 b/dev/config/lnd/regtest/lnd-outside-2.admin.macaroon.base64 new file mode 100644 index 0000000000..826591de2e --- /dev/null +++ b/dev/config/lnd/regtest/lnd-outside-2.admin.macaroon.base64 @@ -0,0 +1 @@ +AgEDbG5kAvgBAwoQfKO82/iPT2zIwWYPrOXvABIBMBoWCgdhZGRyZXNzEgRyZWFkEgV3cml0ZRoTCgRpbmZvEgRyZWFkEgV3cml0ZRoXCghpbnZvaWNlcxIEcmVhZBIFd3JpdGUaIQoIbWFjYXJvb24SCGdlbmVyYXRlEgRyZWFkEgV3cml0ZRoWCgdtZXNzYWdlEgRyZWFkEgV3cml0ZRoXCghvZmZjaGFpbhIEcmVhZBIFd3JpdGUaFgoHb25jaGFpbhIEcmVhZBIFd3JpdGUaFAoFcGVlcnMSBHJlYWQSBXdyaXRlGhgKBnNpZ25lchIIZ2VuZXJhdGUSBHJlYWQAAAYg2XkV+4Z4inbfXGZivRoY+r7KHNZhgxkCEdKByxbeb/Q= \ No newline at end of file diff --git a/dev/config/lnd/regtest/lnd-outside-2.macaroons.db b/dev/config/lnd/regtest/lnd-outside-2.macaroons.db new file mode 100644 index 0000000000000000000000000000000000000000..a052db71f684432d43f9c5a0e538ee0c646eaf9e GIT binary patch literal 20480 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%0DFNs!cQbFOTk9O8I?MGS)E$ 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�Y?9VdT}U&5D#$$*3kvh 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 literal 0 HcmV?d00001 diff --git a/dev/config/lnd/regtest/lnd2.admin.macaroon b/dev/config/lnd/regtest/lnd2.admin.macaroon new file mode 100644 index 0000000000000000000000000000000000000000..f414781ae8bc23e2aeb7dcc82ba62a7aa6a41bb0 GIT binary patch literal 293 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%0A4-|2; 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 S22ci222ci22L69D@P7d7)Q#Q% literal 0 HcmV?d00001 diff --git a/dev/docker-compose.deps.yml b/dev/docker-compose.deps.yml index 9dcebc8895..f885eddae9 100644 --- a/dev/docker-compose.deps.yml +++ b/dev/docker-compose.deps.yml @@ -4,45 +4,45 @@ services: price: image: us.gcr.io/galoy-org/price:edge ports: - - 50051:50051 - - 9464:9464 + - 50051:50051 + - 9464:9464 price-history: image: us.gcr.io/galoy-org/price-history:edge ports: - - 50052:50052 + - 50052:50052 command: ./scripts/run-servers-dev.sh environment: - - DB_HOST=price-history-pg - - DB_PORT=5432 - - DB_USER=galoy-price-usr - - DB_PWD=galoy-price-pwd - - DB_DB=galoy-price-history - - DB_POOL_MIN=1 - - DB_POOL_MAX=5 - - DB_DEBUG=false + - DB_HOST=price-history-pg + - DB_PORT=5432 + - DB_USER=galoy-price-usr + - DB_PWD=galoy-price-pwd + - DB_DB=galoy-price-history + - DB_POOL_MIN=1 + - DB_POOL_MAX=5 + - DB_DEBUG=false depends_on: - - price-history-pg - - price-history-migrate + - price-history-pg + - price-history-migrate price-history-migrate: image: us.gcr.io/galoy-org/price-history-migrate:edge ports: [] environment: - - DB_HOST=price-history-pg - - DB_PORT=5432 - - DB_USER=galoy-price-usr - - DB_PWD=galoy-price-pwd - - DB_DB=galoy-price-history - - DB_POOL_MIN=1 - - DB_POOL_MAX=5 - - DB_DEBUG=false + - DB_HOST=price-history-pg + - DB_PORT=5432 + - DB_USER=galoy-price-usr + - DB_PWD=galoy-price-pwd + - DB_DB=galoy-price-history + - DB_POOL_MIN=1 + - DB_POOL_MAX=5 + - DB_DEBUG=false depends_on: - - price-history-pg + - price-history-pg price-history-pg: image: postgres:14.1 environment: - - POSTGRES_USER=galoy-price-usr - - POSTGRES_PASSWORD=galoy-price-pwd - - POSTGRES_DB=galoy-price-history + - POSTGRES_USER=galoy-price-usr + - POSTGRES_PASSWORD=galoy-price-pwd + - POSTGRES_DB=galoy-price-history api-keys-pg: image: postgres:14.1 environment: @@ -173,6 +173,66 @@ services: cp /root/.lnd/macaroons.db /root/.lnd/data/chain/bitcoin/regtest/macaroons.db cp /root/.lnd/admin.macaroon /root/.lnd/data/chain/bitcoin/regtest/admin.macaroon /bin/lnd + lnd2: + image: lightninglabs/lnd:v0.16.2-beta + ports: + - "10010:10009" + volumes: + - ${HOST_PROJECT_PATH:-.}/config/lnd/lnd.conf:/root/.lnd/lnd.conf + - ${HOST_PROJECT_PATH:-.}/config/lnd/tls.key:/root/.lnd/tls.key + - ${HOST_PROJECT_PATH:-.}/config/lnd/tls.cert:/root/.lnd/tls.cert + - ${HOST_PROJECT_PATH:-.}/config/lnd/regtest/lnd2.wallet.db:/root/.lnd/wallet.db + - ${HOST_PROJECT_PATH:-.}/config/lnd/regtest/lnd2.macaroons.db:/root/.lnd/macaroons.db + - ${HOST_PROJECT_PATH:-.}/config/lnd/regtest/lnd2.admin.macaroon:/root/.lnd/admin.macaroon + depends_on: [bitcoind] + entrypoint: ["/bin/sh", "-c"] + command: + - | + mkdir -p /root/.lnd/data/chain/bitcoin/regtest/ + cp /root/.lnd/wallet.db /root/.lnd/data/chain/bitcoin/regtest/wallet.db + cp /root/.lnd/macaroons.db /root/.lnd/data/chain/bitcoin/regtest/macaroons.db + cp /root/.lnd/admin.macaroon /root/.lnd/data/chain/bitcoin/regtest/admin.macaroon + /bin/lnd + lnd-outside-1: + image: lightninglabs/lnd:v0.16.2-beta + ports: + - "10012:10009" + volumes: + - ${HOST_PROJECT_PATH:-.}/config/lnd/lnd.conf:/root/.lnd/lnd.conf + - ${HOST_PROJECT_PATH:-.}/config/lnd/tls.key:/root/.lnd/tls.key + - ${HOST_PROJECT_PATH:-.}/config/lnd/tls.cert:/root/.lnd/tls.cert + - ${HOST_PROJECT_PATH:-.}/config/lnd/regtest/lnd-outside-1.wallet.db:/root/.lnd/wallet.db + - ${HOST_PROJECT_PATH:-.}/config/lnd/regtest/lnd-outside-1.macaroons.db:/root/.lnd/macaroons.db + - ${HOST_PROJECT_PATH:-.}/config/lnd/regtest/lnd-outside-1.admin.macaroon:/root/.lnd/admin.macaroon + entrypoint: ["/bin/sh", "-c"] + command: + - | + mkdir -p /root/.lnd/data/chain/bitcoin/regtest/ + cp /root/.lnd/wallet.db /root/.lnd/data/chain/bitcoin/regtest/wallet.db + cp /root/.lnd/macaroons.db /root/.lnd/data/chain/bitcoin/regtest/macaroons.db + cp /root/.lnd/admin.macaroon /root/.lnd/data/chain/bitcoin/regtest/admin.macaroon + /bin/lnd + depends_on: [bitcoind] + lnd-outside-2: + image: lightninglabs/lnd:v0.16.2-beta + ports: + - "10013:10009" + volumes: + - ${HOST_PROJECT_PATH:-.}/config/lnd/lnd.conf:/root/.lnd/lnd.conf + - ${HOST_PROJECT_PATH:-.}/config/lnd/tls.key:/root/.lnd/tls.key + - ${HOST_PROJECT_PATH:-.}/config/lnd/tls.cert:/root/.lnd/tls.cert + - ${HOST_PROJECT_PATH:-.}/config/lnd/regtest/lnd-outside-2.wallet.db:/root/.lnd/wallet.db + - ${HOST_PROJECT_PATH:-.}/config/lnd/regtest/lnd-outside-2.macaroons.db:/root/.lnd/macaroons.db + - ${HOST_PROJECT_PATH:-.}/config/lnd/regtest/lnd-outside-2.admin.macaroon:/root/.lnd/admin.macaroon + entrypoint: ["/bin/sh", "-c"] + command: + - | + mkdir -p /root/.lnd/data/chain/bitcoin/regtest/ + cp /root/.lnd/wallet.db /root/.lnd/data/chain/bitcoin/regtest/wallet.db + cp /root/.lnd/macaroons.db /root/.lnd/data/chain/bitcoin/regtest/macaroons.db + cp /root/.lnd/admin.macaroon /root/.lnd/data/chain/bitcoin/regtest/admin.macaroon + /bin/lnd + depends_on: [bitcoind] bria: image: us.gcr.io/galoy-org/bria:latest ports: @@ -284,4 +344,4 @@ services: - otel-agent restart: on-failure:10 volumes: - - ${HOST_PROJECT_PATH:-.}/:/repo \ No newline at end of file + - ${HOST_PROJECT_PATH:-.}/:/repo From eace0c8b1bf648f21ce6c89d13883535e1c63a62 Mon Sep 17 00:00:00 2001 From: Sandipan Dey Date: Mon, 27 Nov 2023 13:16:53 +0530 Subject: [PATCH 2/6] test: lnINnvoicePaymentSend tests ported --- bats/core/api/ln-send.bats | 228 +++++++++------------- bats/gql/ln-invoice-fee-probe.gql | 8 + bats/gql/ln-invoice-payment-send copy.gql | 8 + bats/gql/ln-invoice-payment-send.gql | 8 + bats/gql/ln-usd-invoice-fee-probe.gql | 8 + bats/helpers/ln.bash | 5 + 6 files changed, 133 insertions(+), 132 deletions(-) create mode 100644 bats/gql/ln-invoice-fee-probe.gql create mode 100644 bats/gql/ln-invoice-payment-send copy.gql create mode 100644 bats/gql/ln-invoice-payment-send.gql create mode 100644 bats/gql/ln-usd-invoice-fee-probe.gql diff --git a/bats/core/api/ln-send.bats b/bats/core/api/ln-send.bats index 66393af6df..da99acaca7 100644 --- a/bats/core/api/ln-send.bats +++ b/bats/core/api/ln-send.bats @@ -22,168 +22,132 @@ setup_file() { fund_user_lightning 'alice' 'btc_wallet' '5000000' } -@test "h1" { - exit 1 -} +btc_amount=1000 +usd_amount=50 -# amount_sent_for_ln_txn_by_hash() { -# token_name="$1" -# payment_hash="$2" +@test "ln-send: lightning settled - lnInvoicePaymentSend from btc" { + btc_wallet_name="alice.btc_wallet_id" -# first=20 -# txn_variables=$( -# jq -n \ -# --argjson first "$first" \ -# '{"first": $first}' -# ) -# exec_graphql "$token_name" 'transactions' "$txn_variables" > /dev/null - -# jq_query=' -# [ -# .data.me.defaultAccount.transactions.edges[] -# | select(.node.initiationVia.paymentHash == $payment_hash) -# | select(.node.direction == "SEND") -# ] -# | first .node.settlementAmount -# ' -# local amount=$(echo $output \ -# | jq -r \ -# --arg payment_hash "$payment_hash" \ -# "$jq_query" -# ) -# abs $amount -# } + initial_lnd1_balance=$(lnd_cli channelbalance | jq -r '.balance') -# btc_amount=1000 -# usd_amount=50 + invoice_response="$(lnd_outside_cli addinvoice --amt $btc_amount)" + payment_request="$(echo $invoice_response | jq -r '.payment_request')" + payment_hash=$(echo $invoice_response | jq -r '.r_hash') + [[ "${payment_request}" != "null" ]] || exit 1 -# @test "ln-send: lightning settled - lnInvoicePaymentSend from btc" { -# token_name="$ALICE_TOKEN_NAME" -# btc_wallet_name="$token_name.btc_wallet_id" + variables=$( + jq -n \ + --arg wallet_id "$(read_value $btc_wallet_name)" \ + --arg payment_request "$payment_request" \ + '{input: {walletId: $wallet_id, paymentRequest: $payment_request}}' + ) -# initial_lnd1_balance=$(lnd_cli channelbalance | jq -r '.balance') - -# invoice_response="$(lnd_outside_cli addinvoice --amt $btc_amount)" -# payment_request="$(echo $invoice_response | jq -r '.payment_request')" -# payment_hash=$(echo $invoice_response | jq -r '.r_hash') -# [[ "${payment_request}" != "null" ]] || exit 1 - -# variables=$( -# jq -n \ -# --arg wallet_id "$(read_value $btc_wallet_name)" \ -# --arg payment_request "$payment_request" \ -# '{input: {walletId: $wallet_id, paymentRequest: $payment_request}}' -# ) + exec_graphql "alice" 'ln-invoice-fee-probe' "$variables" + fee_amount="$(graphql_output '.data.lnInvoiceFeeProbe.amount')" + [[ "${fee_amount}" = "0" ]] || exit 1 -# exec_graphql "$token_name" 'ln-invoice-fee-probe' "$variables" -# fee_amount="$(graphql_output '.data.lnInvoiceFeeProbe.amount')" -# [[ "${fee_amount}" = "0" ]] || exit 1 + exec_graphql "alice" 'ln-invoice-payment-send' "$variables" + send_status="$(graphql_output '.data.lnInvoicePaymentSend.status')" + [[ "${send_status}" = "SUCCESS" ]] || exit 1 -# exec_graphql "$token_name" 'ln-invoice-payment-send' "$variables" -# send_status="$(graphql_output '.data.lnInvoicePaymentSend.status')" -# [[ "${send_status}" = "SUCCESS" ]] || exit 1 + # Check for settled + retry 15 1 check_for_ln_initiated_settled "alice" "$payment_hash" -# # Check for settled -# retry 15 1 check_for_ln_initiated_settled "$token_name" "$payment_hash" + final_lnd1_balance=$(lnd_cli channelbalance | jq -r '.balance') + lnd1_diff="$(( $initial_lnd1_balance - $final_lnd1_balance ))" + [[ "$lnd1_diff" == "$btc_amount" ]] || exit 1 +} -# final_lnd1_balance=$(lnd_cli channelbalance | jq -r '.balance') -# lnd1_diff="$(( $initial_lnd1_balance - $final_lnd1_balance ))" -# [[ "$lnd1_diff" == "$btc_amount" ]] || exit 1 -# } +@test "ln-send: lightning settled - lnInvoicePaymentSend from btc, no fee probe" { + btc_wallet_name="alice.btc_wallet_id" -# @test "ln-send: lightning settled - lnInvoicePaymentSend from btc, no fee probe" { -# token_name="$ALICE_TOKEN_NAME" -# btc_wallet_name="$token_name.btc_wallet_id" + initial_lnd1_balance=$(lnd_cli channelbalance | jq -r '.balance') -# initial_lnd1_balance=$(lnd_cli channelbalance | jq -r '.balance') + invoice_response="$(lnd_outside_cli addinvoice --amt $btc_amount)" + payment_request="$(echo $invoice_response | jq -r '.payment_request')" + payment_hash=$(echo $invoice_response | jq -r '.r_hash') + [[ "${payment_request}" != "null" ]] || exit 1 -# invoice_response="$(lnd_outside_cli addinvoice --amt $btc_amount)" -# payment_request="$(echo $invoice_response | jq -r '.payment_request')" -# payment_hash=$(echo $invoice_response | jq -r '.r_hash') -# [[ "${payment_request}" != "null" ]] || exit 1 + variables=$( + jq -n \ + --arg wallet_id "$(read_value $btc_wallet_name)" \ + --arg payment_request "$payment_request" \ + '{input: {walletId: $wallet_id, paymentRequest: $payment_request}}' + ) -# variables=$( -# jq -n \ -# --arg wallet_id "$(read_value $btc_wallet_name)" \ -# --arg payment_request "$payment_request" \ -# '{input: {walletId: $wallet_id, paymentRequest: $payment_request}}' -# ) - -# exec_graphql "$token_name" 'ln-invoice-payment-send' "$variables" -# send_status="$(graphql_output '.data.lnInvoicePaymentSend.status')" -# [[ "${send_status}" = "SUCCESS" ]] || exit 1 + exec_graphql "alice" 'ln-invoice-payment-send' "$variables" + send_status="$(graphql_output '.data.lnInvoicePaymentSend.status')" + [[ "${send_status}" = "SUCCESS" ]] || exit 1 -# # Check for settled -# retry 15 1 check_for_ln_initiated_settled "$token_name" "$payment_hash" + # Check for settled + retry 15 1 check_for_ln_initiated_settled "alice" "$payment_hash" -# final_lnd1_balance=$(lnd_cli channelbalance | jq -r '.balance') -# lnd1_diff="$(( $initial_lnd1_balance - $final_lnd1_balance ))" -# [[ "$lnd1_diff" == "$btc_amount" ]] || exit 1 -# } + final_lnd1_balance=$(lnd_cli channelbalance | jq -r '.balance') + lnd1_diff="$(( $initial_lnd1_balance - $final_lnd1_balance ))" + [[ "$lnd1_diff" == "$btc_amount" ]] || exit 1 +} -# @test "ln-send: lightning settled - lnInvoicePaymentSend from usd" { -# token_name="$ALICE_TOKEN_NAME" -# usd_wallet_name="$token_name.usd_wallet_id" +@test "ln-send: lightning settled - lnInvoicePaymentSend from usd" { + usd_wallet_name="alice.usd_wallet_id" -# initial_lnd1_balance=$(lnd_cli channelbalance | jq -r '.balance') + initial_lnd1_balance=$(lnd_cli channelbalance | jq -r '.balance') -# invoice_response="$(lnd_outside_cli addinvoice --amt $btc_amount)" -# payment_request="$(echo $invoice_response | jq -r '.payment_request')" -# payment_hash=$(echo $invoice_response | jq -r '.r_hash') -# [[ "${payment_request}" != "null" ]] || exit 1 + invoice_response="$(lnd_outside_cli addinvoice --amt $btc_amount)" + payment_request="$(echo $invoice_response | jq -r '.payment_request')" + payment_hash=$(echo $invoice_response | jq -r '.r_hash') + [[ "${payment_request}" != "null" ]] || exit 1 -# variables=$( -# jq -n \ -# --arg wallet_id "$(read_value $usd_wallet_name)" \ -# --arg payment_request "$payment_request" \ -# '{input: {walletId: $wallet_id, paymentRequest: $payment_request}}' -# ) + variables=$( + jq -n \ + --arg wallet_id "$(read_value $usd_wallet_name)" \ + --arg payment_request "$payment_request" \ + '{input: {walletId: $wallet_id, paymentRequest: $payment_request}}' + ) -# exec_graphql "$token_name" 'ln-usd-invoice-fee-probe' "$variables" -# fee_amount="$(graphql_output '.data.lnUsdInvoiceFeeProbe.amount')" -# [[ "${fee_amount}" = "0" ]] || exit 1 + exec_graphql "alice" 'ln-usd-invoice-fee-probe' "$variables" + fee_amount="$(graphql_output '.data.lnUsdInvoiceFeeProbe.amount')" + [[ "${fee_amount}" = "0" ]] || exit 1 -# exec_graphql "$token_name" 'ln-invoice-payment-send' "$variables" -# send_status="$(graphql_output '.data.lnInvoicePaymentSend.status')" -# [[ "${send_status}" = "SUCCESS" ]] || exit 1 + exec_graphql "alice" 'ln-invoice-payment-send' "$variables" + send_status="$(graphql_output '.data.lnInvoicePaymentSend.status')" + [[ "${send_status}" = "SUCCESS" ]] || exit 1 -# # Check for settled -# retry 15 1 check_for_ln_initiated_settled "$token_name" "$payment_hash" + # Check for settled + retry 15 1 check_for_ln_initiated_settled "alice" "$payment_hash" -# final_lnd1_balance=$(lnd_cli channelbalance | jq -r '.balance') -# lnd1_diff="$(( $initial_lnd1_balance - $final_lnd1_balance ))" -# [[ "$lnd1_diff" == "$btc_amount" ]] || exit 1 -# } + final_lnd1_balance=$(lnd_cli channelbalance | jq -r '.balance') + lnd1_diff="$(( $initial_lnd1_balance - $final_lnd1_balance ))" + [[ "$lnd1_diff" == "$btc_amount" ]] || exit 1 +} -# @test "ln-send: lightning settled - lnInvoicePaymentSend from usd, no fee probe" { -# token_name="$ALICE_TOKEN_NAME" -# usd_wallet_name="$token_name.usd_wallet_id" +@test "ln-send: lightning settled - lnInvoicePaymentSend from usd, no fee probe" { + usd_wallet_name="alice.usd_wallet_id" -# initial_lnd1_balance=$(lnd_cli channelbalance | jq -r '.balance') + initial_lnd1_balance=$(lnd_cli channelbalance | jq -r '.balance') -# invoice_response="$(lnd_outside_cli addinvoice --amt $btc_amount)" -# payment_request="$(echo $invoice_response | jq -r '.payment_request')" -# payment_hash=$(echo $invoice_response | jq -r '.r_hash') -# [[ "${payment_request}" != "null" ]] || exit 1 + invoice_response="$(lnd_outside_cli addinvoice --amt $btc_amount)" + payment_request="$(echo $invoice_response | jq -r '.payment_request')" + payment_hash=$(echo $invoice_response | jq -r '.r_hash') + [[ "${payment_request}" != "null" ]] || exit 1 -# variables=$( -# jq -n \ -# --arg wallet_id "$(read_value $usd_wallet_name)" \ -# --arg payment_request "$payment_request" \ -# '{input: {walletId: $wallet_id, paymentRequest: $payment_request}}' -# ) + variables=$( + jq -n \ + --arg wallet_id "$(read_value $usd_wallet_name)" \ + --arg payment_request "$payment_request" \ + '{input: {walletId: $wallet_id, paymentRequest: $payment_request}}' + ) -# exec_graphql "$token_name" 'ln-invoice-payment-send' "$variables" -# send_status="$(graphql_output '.data.lnInvoicePaymentSend.status')" -# [[ "${send_status}" = "SUCCESS" ]] || exit 1 + exec_graphql "alice" 'ln-invoice-payment-send' "$variables" + send_status="$(graphql_output '.data.lnInvoicePaymentSend.status')" + [[ "${send_status}" = "SUCCESS" ]] || exit 1 -# # Check for settled -# retry 15 1 check_for_ln_initiated_settled "$token_name" "$payment_hash" + # Check for settled + retry 15 1 check_for_ln_initiated_settled "alice" "$payment_hash" -# final_lnd1_balance=$(lnd_cli channelbalance | jq -r '.balance') -# lnd1_diff="$(( $initial_lnd1_balance - $final_lnd1_balance ))" -# [[ "$lnd1_diff" == "$btc_amount" ]] || exit 1 -# } + final_lnd1_balance=$(lnd_cli channelbalance | jq -r '.balance') + lnd1_diff="$(( $initial_lnd1_balance - $final_lnd1_balance ))" + [[ "$lnd1_diff" == "$btc_amount" ]] || exit 1 +} # @test "ln-send: lightning settled - lnNoAmountInvoicePaymentSend" { # token_name="$ALICE_TOKEN_NAME" diff --git a/bats/gql/ln-invoice-fee-probe.gql b/bats/gql/ln-invoice-fee-probe.gql new file mode 100644 index 0000000000..3064f585df --- /dev/null +++ b/bats/gql/ln-invoice-fee-probe.gql @@ -0,0 +1,8 @@ +mutation LnInvoiceFeeProbe($input: LnInvoiceFeeProbeInput!) { + lnInvoiceFeeProbe(input: $input) { + errors { + message + } + amount + } +} diff --git a/bats/gql/ln-invoice-payment-send copy.gql b/bats/gql/ln-invoice-payment-send copy.gql new file mode 100644 index 0000000000..cb66944ef0 --- /dev/null +++ b/bats/gql/ln-invoice-payment-send copy.gql @@ -0,0 +1,8 @@ +mutation lnInvoicePaymentSend($input: LnInvoicePaymentInput!) { + lnInvoicePaymentSend(input: $input) { + errors { + message + } + status + } +} diff --git a/bats/gql/ln-invoice-payment-send.gql b/bats/gql/ln-invoice-payment-send.gql new file mode 100644 index 0000000000..cb66944ef0 --- /dev/null +++ b/bats/gql/ln-invoice-payment-send.gql @@ -0,0 +1,8 @@ +mutation lnInvoicePaymentSend($input: LnInvoicePaymentInput!) { + lnInvoicePaymentSend(input: $input) { + errors { + message + } + status + } +} diff --git a/bats/gql/ln-usd-invoice-fee-probe.gql b/bats/gql/ln-usd-invoice-fee-probe.gql new file mode 100644 index 0000000000..1508e144aa --- /dev/null +++ b/bats/gql/ln-usd-invoice-fee-probe.gql @@ -0,0 +1,8 @@ +mutation lnUsdInvoiceFeeProbe($input: LnUsdInvoiceFeeProbeInput!) { + lnUsdInvoiceFeeProbe(input: $input) { + errors { + message + } + amount + } +} diff --git a/bats/helpers/ln.bash b/bats/helpers/ln.bash index e54033bdfc..60416e453b 100644 --- a/bats/helpers/ln.bash +++ b/bats/helpers/ln.bash @@ -190,3 +190,8 @@ get_from_transaction_by_ln_hash_and_status() { | jq -r "$property_query" \ | head -n 1 } + +mempool_not_empty() { + local txid="$(bitcoin_cli getrawmempool | jq -r ".[0]")" + [[ "$txid" != "null" ]] || exit 1 +} From 8c6f181ce35013ffbf93f216244298f422ae43f0 Mon Sep 17 00:00:00 2001 From: Sandipan Dey Date: Mon, 27 Nov 2023 13:19:30 +0530 Subject: [PATCH 3/6] test: lnNoAmounts --- bats/core/api/ln-send.bats | 100 +++++++++--------- bats/gql/ln-no-amount-invoice-fee-probe.gql | 8 ++ ...ln-no-amount-invoice-payment-send copy.gql | 8 ++ .../gql/ln-no-amount-invoice-payment-send.gql | 8 ++ 4 files changed, 73 insertions(+), 51 deletions(-) create mode 100644 bats/gql/ln-no-amount-invoice-fee-probe.gql create mode 100644 bats/gql/ln-no-amount-invoice-payment-send copy.gql create mode 100644 bats/gql/ln-no-amount-invoice-payment-send.gql diff --git a/bats/core/api/ln-send.bats b/bats/core/api/ln-send.bats index da99acaca7..0a4c23643e 100644 --- a/bats/core/api/ln-send.bats +++ b/bats/core/api/ln-send.bats @@ -149,71 +149,69 @@ usd_amount=50 [[ "$lnd1_diff" == "$btc_amount" ]] || exit 1 } -# @test "ln-send: lightning settled - lnNoAmountInvoicePaymentSend" { -# token_name="$ALICE_TOKEN_NAME" -# btc_wallet_name="$token_name.btc_wallet_id" +@test "ln-send: lightning settled - lnNoAmountInvoicePaymentSend" { + btc_wallet_name="alice.btc_wallet_id" -# initial_lnd1_balance=$(lnd_cli channelbalance | jq -r '.balance') + initial_lnd1_balance=$(lnd_cli channelbalance | jq -r '.balance') -# invoice_response="$(lnd_outside_cli addinvoice)" -# payment_request="$(echo $invoice_response | jq -r '.payment_request')" -# payment_hash=$(echo $invoice_response | jq -r '.r_hash') -# [[ "${payment_request}" != "null" ]] || exit 1 + invoice_response="$(lnd_outside_cli addinvoice)" + payment_request="$(echo $invoice_response | jq -r '.payment_request')" + payment_hash=$(echo $invoice_response | jq -r '.r_hash') + [[ "${payment_request}" != "null" ]] || exit 1 -# variables=$( -# jq -n \ -# --arg wallet_id "$(read_value $btc_wallet_name)" \ -# --arg payment_request "$payment_request" \ -# --arg amount $btc_amount \ -# '{input: {walletId: $wallet_id, paymentRequest: $payment_request, amount: $amount}}' -# ) + variables=$( + jq -n \ + --arg wallet_id "$(read_value $btc_wallet_name)" \ + --arg payment_request "$payment_request" \ + --arg amount $btc_amount \ + '{input: {walletId: $wallet_id, paymentRequest: $payment_request, amount: $amount}}' + ) -# exec_graphql "$token_name" 'ln-no-amount-invoice-fee-probe' "$variables" -# fee_amount="$(graphql_output '.data.lnNoAmountInvoiceFeeProbe.amount')" -# [[ "${fee_amount}" = "0" ]] || exit 1 + exec_graphql "alice" 'ln-no-amount-invoice-fee-probe' "$variables" + fee_amount="$(graphql_output '.data.lnNoAmountInvoiceFeeProbe.amount')" + [[ "${fee_amount}" = "0" ]] || exit 1 -# exec_graphql "$token_name" 'ln-no-amount-invoice-payment-send' "$variables" -# send_status="$(graphql_output '.data.lnNoAmountInvoicePaymentSend.status')" -# [[ "${send_status}" = "SUCCESS" ]] || exit 1 + exec_graphql "alice" 'ln-no-amount-invoice-payment-send' "$variables" + send_status="$(graphql_output '.data.lnNoAmountInvoicePaymentSend.status')" + [[ "${send_status}" = "SUCCESS" ]] || exit 1 -# # Check for settled -# retry 15 1 check_for_ln_initiated_settled "$token_name" "$payment_hash" + # Check for settled + retry 15 1 check_for_ln_initiated_settled "alice" "$payment_hash" -# final_lnd1_balance=$(lnd_cli channelbalance | jq -r '.balance') -# lnd1_diff="$(( $initial_lnd1_balance - $final_lnd1_balance ))" -# [[ "$lnd1_diff" == "$btc_amount" ]] || exit 1 -# } + final_lnd1_balance=$(lnd_cli channelbalance | jq -r '.balance') + lnd1_diff="$(( $initial_lnd1_balance - $final_lnd1_balance ))" + [[ "$lnd1_diff" == "$btc_amount" ]] || exit 1 +} -# @test "ln-send: lightning settled - lnNoAmountInvoicePaymentSend, no fee probe" { -# token_name="$ALICE_TOKEN_NAME" -# btc_wallet_name="$token_name.btc_wallet_id" +@test "ln-send: lightning settled - lnNoAmountInvoicePaymentSend, no fee probe" { + btc_wallet_name="alice.btc_wallet_id" -# initial_lnd1_balance=$(lnd_cli channelbalance | jq -r '.balance') + initial_lnd1_balance=$(lnd_cli channelbalance | jq -r '.balance') -# invoice_response="$(lnd_outside_cli addinvoice)" -# payment_request="$(echo $invoice_response | jq -r '.payment_request')" -# payment_hash=$(echo $invoice_response | jq -r '.r_hash') -# [[ "${payment_request}" != "null" ]] || exit 1 + invoice_response="$(lnd_outside_cli addinvoice)" + payment_request="$(echo $invoice_response | jq -r '.payment_request')" + payment_hash=$(echo $invoice_response | jq -r '.r_hash') + [[ "${payment_request}" != "null" ]] || exit 1 -# variables=$( -# jq -n \ -# --arg wallet_id "$(read_value $btc_wallet_name)" \ -# --arg payment_request "$payment_request" \ -# --arg amount $btc_amount \ -# '{input: {walletId: $wallet_id, paymentRequest: $payment_request, amount: $amount}}' -# ) + variables=$( + jq -n \ + --arg wallet_id "$(read_value $btc_wallet_name)" \ + --arg payment_request "$payment_request" \ + --arg amount $btc_amount \ + '{input: {walletId: $wallet_id, paymentRequest: $payment_request, amount: $amount}}' + ) -# exec_graphql "$token_name" 'ln-no-amount-invoice-payment-send' "$variables" -# send_status="$(graphql_output '.data.lnNoAmountInvoicePaymentSend.status')" -# [[ "${send_status}" = "SUCCESS" ]] || exit 1 + exec_graphql "alice" 'ln-no-amount-invoice-payment-send' "$variables" + send_status="$(graphql_output '.data.lnNoAmountInvoicePaymentSend.status')" + [[ "${send_status}" = "SUCCESS" ]] || exit 1 -# # Check for settled -# retry 15 1 check_for_ln_initiated_settled "$token_name" "$payment_hash" + # Check for settled + retry 15 1 check_for_ln_initiated_settled "alice" "$payment_hash" -# final_lnd1_balance=$(lnd_cli channelbalance | jq -r '.balance') -# lnd1_diff="$(( $initial_lnd1_balance - $final_lnd1_balance ))" -# [[ "$lnd1_diff" == "$btc_amount" ]] || exit 1 -# } + final_lnd1_balance=$(lnd_cli channelbalance | jq -r '.balance') + lnd1_diff="$(( $initial_lnd1_balance - $final_lnd1_balance ))" + [[ "$lnd1_diff" == "$btc_amount" ]] || exit 1 +} # @test "ln-send: lightning settled - lnNoAmountUsdInvoicePaymentSend" { # token_name="$ALICE_TOKEN_NAME" diff --git a/bats/gql/ln-no-amount-invoice-fee-probe.gql b/bats/gql/ln-no-amount-invoice-fee-probe.gql new file mode 100644 index 0000000000..cbd12026ac --- /dev/null +++ b/bats/gql/ln-no-amount-invoice-fee-probe.gql @@ -0,0 +1,8 @@ +mutation lnNoAmountInvoiceFeeProbe($input: LnNoAmountInvoiceFeeProbeInput!) { + lnNoAmountInvoiceFeeProbe(input: $input) { + errors { + message + } + amount + } +} diff --git a/bats/gql/ln-no-amount-invoice-payment-send copy.gql b/bats/gql/ln-no-amount-invoice-payment-send copy.gql new file mode 100644 index 0000000000..7131b589b4 --- /dev/null +++ b/bats/gql/ln-no-amount-invoice-payment-send copy.gql @@ -0,0 +1,8 @@ +mutation lnNoAmountInvoicePaymentSend($input: LnNoAmountInvoicePaymentInput!) { + lnNoAmountInvoicePaymentSend(input: $input) { + errors { + message + } + status + } +} diff --git a/bats/gql/ln-no-amount-invoice-payment-send.gql b/bats/gql/ln-no-amount-invoice-payment-send.gql new file mode 100644 index 0000000000..7131b589b4 --- /dev/null +++ b/bats/gql/ln-no-amount-invoice-payment-send.gql @@ -0,0 +1,8 @@ +mutation lnNoAmountInvoicePaymentSend($input: LnNoAmountInvoicePaymentInput!) { + lnNoAmountInvoicePaymentSend(input: $input) { + errors { + message + } + status + } +} From bb1a6bf911d5daab6712c6627c220a9a2ae5ba49 Mon Sep 17 00:00:00 2001 From: Sandipan Dey Date: Mon, 27 Nov 2023 13:24:07 +0530 Subject: [PATCH 4/6] test: lnNoAmountUsds --- bats/core/api/ln-send.bats | 236 +++++++++--------- .../ln-no-amount-usd-invoice-fee-probe.gql | 8 + .../ln-no-amount-usd-invoice-payment-send.gql | 8 + 3 files changed, 133 insertions(+), 119 deletions(-) create mode 100644 bats/gql/ln-no-amount-usd-invoice-fee-probe.gql create mode 100644 bats/gql/ln-no-amount-usd-invoice-payment-send.gql diff --git a/bats/core/api/ln-send.bats b/bats/core/api/ln-send.bats index 0a4c23643e..9f2fcf9c9d 100644 --- a/bats/core/api/ln-send.bats +++ b/bats/core/api/ln-send.bats @@ -213,85 +213,83 @@ usd_amount=50 [[ "$lnd1_diff" == "$btc_amount" ]] || exit 1 } -# @test "ln-send: lightning settled - lnNoAmountUsdInvoicePaymentSend" { -# token_name="$ALICE_TOKEN_NAME" -# usd_wallet_name="$token_name.usd_wallet_id" +@test "ln-send: lightning settled - lnNoAmountUsdInvoicePaymentSend" { + usd_wallet_name="alice.usd_wallet_id" -# initial_balance="$(balance_for_wallet $token_name 'USD')" -# initial_lnd1_balance=$(lnd_cli channelbalance | jq -r '.balance') + initial_balance="$(balance_for_wallet alice 'USD')" + initial_lnd1_balance=$(lnd_cli channelbalance | jq -r '.balance') -# invoice_response="$(lnd_outside_cli addinvoice)" -# payment_request="$(echo $invoice_response | jq -r '.payment_request')" -# payment_hash=$(echo $invoice_response | jq -r '.r_hash') -# [[ "${payment_request}" != "null" ]] || exit 1 + invoice_response="$(lnd_outside_cli addinvoice)" + payment_request="$(echo $invoice_response | jq -r '.payment_request')" + payment_hash=$(echo $invoice_response | jq -r '.r_hash') + [[ "${payment_request}" != "null" ]] || exit 1 -# variables=$( -# jq -n \ -# --arg wallet_id "$(read_value $usd_wallet_name)" \ -# --arg payment_request "$payment_request" \ -# --arg amount $usd_amount \ -# '{input: {walletId: $wallet_id, paymentRequest: $payment_request, amount: $amount}}' -# ) + variables=$( + jq -n \ + --arg wallet_id "$(read_value $usd_wallet_name)" \ + --arg payment_request "$payment_request" \ + --arg amount $usd_amount \ + '{input: {walletId: $wallet_id, paymentRequest: $payment_request, amount: $amount}}' + ) -# exec_graphql "$token_name" 'ln-no-amount-usd-invoice-fee-probe' "$variables" -# fee_amount="$(graphql_output '.data.lnNoAmountUsdInvoiceFeeProbe.amount')" -# [[ "${fee_amount}" = "0" ]] || exit 1 + exec_graphql "alice" 'ln-no-amount-usd-invoice-fee-probe' "$variables" + fee_amount="$(graphql_output '.data.lnNoAmountUsdInvoiceFeeProbe.amount')" + [[ "${fee_amount}" = "0" ]] || exit 1 -# exec_graphql "$token_name" 'ln-no-amount-usd-invoice-payment-send' "$variables" -# send_status="$(graphql_output '.data.lnNoAmountUsdInvoicePaymentSend.status')" -# [[ "${send_status}" = "SUCCESS" ]] || exit 1 + exec_graphql "alice" 'ln-no-amount-usd-invoice-payment-send' "$variables" + send_status="$(graphql_output '.data.lnNoAmountUsdInvoicePaymentSend.status')" + [[ "${send_status}" = "SUCCESS" ]] || exit 1 -# # Check for settled -# retry 15 1 check_for_ln_initiated_settled "$token_name" "$payment_hash" + # Check for settled + retry 15 1 check_for_ln_initiated_settled "alice" "$payment_hash" -# final_balance="$(balance_for_wallet $token_name 'USD')" -# wallet_diff="$(( $initial_balance - $final_balance ))" -# [[ "$wallet_diff" == "$usd_amount" ]] || exit 1 + final_balance="$(balance_for_wallet alice 'USD')" + wallet_diff="$(( $initial_balance - $final_balance ))" + [[ "$wallet_diff" == "$usd_amount" ]] || exit 1 -# final_lnd1_balance=$(lnd_cli channelbalance | jq -r '.balance') -# lnd1_diff="$(( $initial_lnd1_balance - $final_lnd1_balance ))" -# [[ "$lnd1_diff" -gt "0" ]] || exit 1 -# } + final_lnd1_balance=$(lnd_cli channelbalance | jq -r '.balance') + lnd1_diff="$(( $initial_lnd1_balance - $final_lnd1_balance ))" + [[ "$lnd1_diff" -gt "0" ]] || exit 1 +} -# @test "ln-send: lightning settled - lnNoAmountUsdInvoicePaymentSend, no fee probe" { -# token_name="$ALICE_TOKEN_NAME" -# usd_wallet_name="$token_name.usd_wallet_id" +@test "ln-send: lightning settled - lnNoAmountUsdInvoicePaymentSend, no fee probe" { + usd_wallet_name="alice.usd_wallet_id" -# initial_balance="$(balance_for_wallet $token_name 'USD')" -# initial_lnd1_balance=$(lnd_cli channelbalance | jq -r '.balance') + initial_balance="$(balance_for_wallet alice 'USD')" + initial_lnd1_balance=$(lnd_cli channelbalance | jq -r '.balance') -# invoice_response="$(lnd_outside_cli addinvoice)" -# payment_request="$(echo $invoice_response | jq -r '.payment_request')" -# payment_hash=$(echo $invoice_response | jq -r '.r_hash') -# [[ "${payment_request}" != "null" ]] || exit 1 + invoice_response="$(lnd_outside_cli addinvoice)" + payment_request="$(echo $invoice_response | jq -r '.payment_request')" + payment_hash=$(echo $invoice_response | jq -r '.r_hash') + [[ "${payment_request}" != "null" ]] || exit 1 -# variables=$( -# jq -n \ -# --arg wallet_id "$(read_value $usd_wallet_name)" \ -# --arg payment_request "$payment_request" \ -# --arg amount $usd_amount \ -# '{input: {walletId: $wallet_id, paymentRequest: $payment_request, amount: $amount}}' -# ) + variables=$( + jq -n \ + --arg wallet_id "$(read_value $usd_wallet_name)" \ + --arg payment_request "$payment_request" \ + --arg amount $usd_amount \ + '{input: {walletId: $wallet_id, paymentRequest: $payment_request, amount: $amount}}' + ) -# exec_graphql "$token_name" 'ln-no-amount-usd-invoice-payment-send' "$variables" -# send_status="$(graphql_output '.data.lnNoAmountUsdInvoicePaymentSend.status')" -# [[ "${send_status}" = "SUCCESS" ]] || exit 1 + exec_graphql "alice" 'ln-no-amount-usd-invoice-payment-send' "$variables" + send_status="$(graphql_output '.data.lnNoAmountUsdInvoicePaymentSend.status')" + [[ "${send_status}" = "SUCCESS" ]] || exit 1 -# # Check for settled -# retry 15 1 check_for_ln_initiated_settled "$token_name" "$payment_hash" + # Check for settled + retry 15 1 check_for_ln_initiated_settled "alice" "$payment_hash" -# final_balance="$(balance_for_wallet $token_name 'USD')" -# wallet_diff="$(( $initial_balance - $final_balance ))" -# [[ "$wallet_diff" == "$usd_amount" ]] || exit 1 + final_balance="$(balance_for_wallet alice 'USD')" + wallet_diff="$(( $initial_balance - $final_balance ))" + [[ "$wallet_diff" == "$usd_amount" ]] || exit 1 -# final_lnd1_balance=$(lnd_cli channelbalance | jq -r '.balance') -# lnd1_diff="$(( $initial_lnd1_balance - $final_lnd1_balance ))" -# [[ "$lnd1_diff" -gt "0" ]] || exit 1 -# } + final_lnd1_balance=$(lnd_cli channelbalance | jq -r '.balance') + lnd1_diff="$(( $initial_lnd1_balance - $final_lnd1_balance ))" + [[ "$lnd1_diff" -gt "0" ]] || exit 1 +} # @test "ln-send: intraledger settled - lnInvoicePaymentSend from btc to btc, with contacts check" { -# token_name="$ALICE_TOKEN_NAME" -# btc_wallet_name="$token_name.btc_wallet_id" +# +# btc_wallet_name="alice.btc_wallet_id" # recipient_token_name="user_$RANDOM" # recipient_phone="$(random_phone)" @@ -302,13 +300,13 @@ usd_amount=50 # user_update_username "$recipient_token_name" # btc_recipient_wallet_name="$recipient_token_name.btc_wallet_id" -# initial_balance="$(balance_for_wallet $token_name 'BTC')" +# initial_balance="$(balance_for_wallet alice 'BTC')" # initial_lnd1_balance=$(lnd_cli channelbalance | jq -r '.balance') # # Check is not contact before send -# run is_contact "$token_name" "$recipient_token_name" +# run is_contact "alice" "$recipient_token_name" # [[ "$status" -ne "0" ]] || exit 1 -# run is_contact "$recipient_token_name" "$token_name" +# run is_contact "$recipient_token_name" "alice" # [[ "$status" -ne "0" ]] || exit 1 # variables=$( @@ -332,15 +330,15 @@ usd_amount=50 # '{input: {walletId: $wallet_id, paymentRequest: $payment_request}}' # ) -# exec_graphql "$token_name" 'ln-invoice-payment-send' "$variables" +# exec_graphql "alice" 'ln-invoice-payment-send' "$variables" # send_status="$(graphql_output '.data.lnInvoicePaymentSend.status')" # [[ "${send_status}" = "SUCCESS" ]] || exit 1 # # Check for settled -# retry 15 1 check_for_ln_initiated_settled "$token_name" "$payment_hash" +# retry 15 1 check_for_ln_initiated_settled "alice" "$payment_hash" # check_for_ln_initiated_settled "$recipient_token_name" "$payment_hash" -# final_balance="$(balance_for_wallet $token_name 'BTC')" +# final_balance="$(balance_for_wallet alice 'BTC')" # wallet_diff="$(( $initial_balance - $final_balance ))" # [[ "$wallet_diff" == "$btc_amount" ]] || exit 1 @@ -349,15 +347,15 @@ usd_amount=50 # [[ "$lnd1_diff" == "0" ]] || exit 1 # # Check is contact after send -# run is_contact "$token_name" "$recipient_token_name" +# run is_contact "alice" "$recipient_token_name" # [[ "$status" == "0" ]] || exit 1 -# run is_contact "$recipient_token_name" "$token_name" +# run is_contact "$recipient_token_name" "alice" # [[ "$status" == "0" ]] || exit 1 # } # @test "ln-send: intraledger settled - lnInvoicePaymentSend from usd to btc" { -# token_name="$ALICE_TOKEN_NAME" -# usd_wallet_name="$token_name.usd_wallet_id" +# +# usd_wallet_name="alice.usd_wallet_id" # recipient_token_name="$BOB_TOKEN_NAME" # btc_recipient_wallet_name="$recipient_token_name.btc_wallet_id" @@ -386,16 +384,16 @@ usd_amount=50 # '{input: {walletId: $wallet_id, paymentRequest: $payment_request}}' # ) -# exec_graphql "$token_name" 'ln-usd-invoice-fee-probe' "$variables" +# exec_graphql "alice" 'ln-usd-invoice-fee-probe' "$variables" # fee_amount="$(graphql_output '.data.lnUsdInvoiceFeeProbe.amount')" # [[ "${fee_amount}" = "0" ]] || exit 1 -# exec_graphql "$token_name" 'ln-invoice-payment-send' "$variables" +# exec_graphql "alice" 'ln-invoice-payment-send' "$variables" # send_status="$(graphql_output '.data.lnInvoicePaymentSend.status')" # [[ "${send_status}" = "SUCCESS" ]] || exit 1 # # Check for settled -# retry 15 1 check_for_ln_initiated_settled "$token_name" "$payment_hash" +# retry 15 1 check_for_ln_initiated_settled "alice" "$payment_hash" # check_for_ln_initiated_settled "$recipient_token_name" "$payment_hash" # final_recipient_balance="$(balance_for_wallet $recipient_token_name 'BTC')" @@ -408,13 +406,13 @@ usd_amount=50 # } # @test "ln-send: intraledger settled - lnNoAmountInvoicePaymentSend from btc to usd" { -# token_name="$ALICE_TOKEN_NAME" -# btc_wallet_name="$token_name.btc_wallet_id" +# +# btc_wallet_name="alice.btc_wallet_id" # recipient_token_name="$BOB_TOKEN_NAME" # usd_recipient_wallet_name="$recipient_token_name.usd_wallet_id" -# initial_balance="$(balance_for_wallet $token_name 'BTC')" +# initial_balance="$(balance_for_wallet alice 'BTC')" # initial_lnd1_balance=$(lnd_cli channelbalance | jq -r '.balance') # variables=$( @@ -438,15 +436,15 @@ usd_amount=50 # '{input: {walletId: $wallet_id, paymentRequest: $payment_request, amount: $amount}}' # ) -# exec_graphql "$token_name" 'ln-no-amount-invoice-payment-send' "$variables" +# exec_graphql "alice" 'ln-no-amount-invoice-payment-send' "$variables" # send_status="$(graphql_output '.data.lnNoAmountInvoicePaymentSend.status')" # [[ "${send_status}" = "SUCCESS" ]] || exit 1 # # Check for settled -# retry 15 1 check_for_ln_initiated_settled "$token_name" "$payment_hash" +# retry 15 1 check_for_ln_initiated_settled "alice" "$payment_hash" # check_for_ln_initiated_settled "$recipient_token_name" "$payment_hash" -# final_balance="$(balance_for_wallet $token_name 'BTC')" +# final_balance="$(balance_for_wallet alice 'BTC')" # wallet_diff="$(( $initial_balance - $final_balance ))" # [[ "$wallet_diff" == "$btc_amount" ]] || exit 1 @@ -456,13 +454,13 @@ usd_amount=50 # } # @test "ln-send: intraledger settled - lnNoAmountUsdInvoicePaymentSend from usd to usd" { -# token_name="$ALICE_TOKEN_NAME" -# usd_wallet_name="$token_name.usd_wallet_id" +# +# usd_wallet_name="alice.usd_wallet_id" # recipient_token_name="$BOB_TOKEN_NAME" # usd_recipient_wallet_name="$recipient_token_name.usd_wallet_id" -# initial_balance="$(balance_for_wallet $token_name 'USD')" +# initial_balance="$(balance_for_wallet alice 'USD')" # initial_lnd1_balance=$(lnd_cli channelbalance | jq -r '.balance') # variables=$( @@ -486,15 +484,15 @@ usd_amount=50 # '{input: {walletId: $wallet_id, paymentRequest: $payment_request, amount: $amount}}' # ) -# exec_graphql "$token_name" 'ln-no-amount-usd-invoice-payment-send' "$variables" +# exec_graphql "alice" 'ln-no-amount-usd-invoice-payment-send' "$variables" # send_status="$(graphql_output '.data.lnNoAmountUsdInvoicePaymentSend.status')" # [[ "${send_status}" = "SUCCESS" ]] || exit 1 # # Check for settled -# retry 15 1 check_for_ln_initiated_settled "$token_name" "$payment_hash" +# retry 15 1 check_for_ln_initiated_settled "alice" "$payment_hash" # check_for_ln_initiated_settled "$recipient_token_name" "$payment_hash" -# final_balance="$(balance_for_wallet $token_name 'USD')" +# final_balance="$(balance_for_wallet alice 'USD')" # wallet_diff="$(( $initial_balance - $final_balance ))" # [[ "$wallet_diff" == "$usd_amount" ]] || exit 1 @@ -504,8 +502,8 @@ usd_amount=50 # } # @test "ln-send: ln settled - settle failed and then successful payment" { -# token_name="$ALICE_TOKEN_NAME" -# btc_wallet_name="$token_name.btc_wallet_id" +# +# btc_wallet_name="alice.btc_wallet_id" # threshold_amount=150000 # invoice_response="$(lnd_outside_2_cli addinvoice --amt $threshold_amount)" @@ -516,7 +514,7 @@ usd_amount=50 # check_num_txns() { # expected_num="$1" -# num_txns="$(num_txns_for_hash "$token_name" "$payment_hash")" +# num_txns="$(num_txns_for_hash "alice" "$payment_hash")" # [[ "$num_txns" == "$expected_num" ]] || exit 1 # } @@ -524,7 +522,7 @@ usd_amount=50 # rebalance_channel lnd_outside_cli lnd_outside_2_cli "$(( $threshold_amount - 1 ))" # # Try payment and check for fail -# initial_balance="$(balance_for_wallet $token_name 'BTC')" +# initial_balance="$(balance_for_wallet alice 'BTC')" # variables=$( # jq -n \ @@ -532,7 +530,7 @@ usd_amount=50 # --arg payment_request "$payment_request" \ # '{input: {walletId: $wallet_id, paymentRequest: $payment_request}}' # ) -# exec_graphql "$token_name" 'ln-invoice-payment-send' "$variables" +# exec_graphql "alice" 'ln-invoice-payment-send' "$variables" # send_status="$(graphql_output '.data.lnInvoicePaymentSend.status')" # error_msg="$(graphql_output '.data.lnInvoicePaymentSend.errors[0].message')" # [[ "${send_status}" = "FAILURE" ]] || exit 1 @@ -540,7 +538,7 @@ usd_amount=50 # # Check for txns # retry 15 1 check_num_txns "2" -# balance_after_fail="$(balance_for_wallet $token_name 'BTC')" +# balance_after_fail="$(balance_for_wallet alice 'BTC')" # [[ "$initial_balance" == "$balance_after_fail" ]] || exit 1 # # Rebalance last hop so same payment will succeed @@ -548,27 +546,27 @@ usd_amount=50 # lnd_cli resetmc # # Retry payment and check for success -# exec_graphql "$token_name" 'ln-invoice-fee-probe' "$variables" +# exec_graphql "alice" 'ln-invoice-fee-probe' "$variables" # num_errors="$(graphql_output '.data.lnInvoiceFeeProbe.errors | length')" # fee_amount="$(graphql_output '.data.lnInvoiceFeeProbe.amount')" # [[ "$num_errors" == "0" ]] || exit 1 # [[ "${fee_amount}" -gt "0" ]] || exit 1 -# exec_graphql "$token_name" 'ln-invoice-payment-send' "$variables" +# exec_graphql "alice" 'ln-invoice-payment-send' "$variables" # send_status="$(graphql_output '.data.lnInvoicePaymentSend.status')" # [[ "${send_status}" = "SUCCESS" ]] || exit 1 # # Check for txns # retry 15 1 check_num_txns "3" -# balance_after_success="$(balance_for_wallet $token_name 'BTC')" +# balance_after_success="$(balance_for_wallet alice 'BTC')" # [[ "$balance_after_success" -lt "$initial_balance" ]] || exit 1 # } # @test "ln-send: ln settled - settle failed and then pending-to-failed payment" { # skip "missing xxd dep, failing on concourse" -# token_name="$ALICE_TOKEN_NAME" -# btc_wallet_name="$token_name.btc_wallet_id" +# +# btc_wallet_name="alice.btc_wallet_id" # threshold_amount=150000 # secret=$(xxd -l 32 -p /dev/urandom) @@ -580,7 +578,7 @@ usd_amount=50 # check_num_txns() { # expected_num="$1" -# num_txns="$(num_txns_for_hash "$token_name" "$payment_hash")" +# num_txns="$(num_txns_for_hash "alice" "$payment_hash")" # [[ "$num_txns" == "$expected_num" ]] || exit 1 # } @@ -588,7 +586,7 @@ usd_amount=50 # rebalance_channel lnd_outside_cli lnd_outside_2_cli "$(( $threshold_amount - 1 ))" # # Try payment and check for fail -# initial_balance="$(balance_for_wallet $token_name 'BTC')" +# initial_balance="$(balance_for_wallet alice 'BTC')" # variables=$( # jq -n \ @@ -596,7 +594,7 @@ usd_amount=50 # --arg payment_request "$payment_request" \ # '{input: {walletId: $wallet_id, paymentRequest: $payment_request}}' # ) -# exec_graphql "$token_name" 'ln-invoice-payment-send' "$variables" +# exec_graphql "alice" 'ln-invoice-payment-send' "$variables" # send_status="$(graphql_output '.data.lnInvoicePaymentSend.status')" # error_msg="$(graphql_output '.data.lnInvoicePaymentSend.errors[0].message')" # [[ "${send_status}" = "FAILURE" ]] || exit 1 @@ -604,7 +602,7 @@ usd_amount=50 # # Check for txns # retry 15 1 check_num_txns "2" -# balance_after_fail="$(balance_for_wallet $token_name 'BTC')" +# balance_after_fail="$(balance_for_wallet alice 'BTC')" # [[ "$initial_balance" == "$balance_after_fail" ]] || exit 1 # # Rebalance last hop so same payment will succeed @@ -612,34 +610,34 @@ usd_amount=50 # lnd_cli resetmc # # Retry payment and check for pending -# exec_graphql "$token_name" 'ln-invoice-payment-send' "$variables" +# exec_graphql "alice" 'ln-invoice-payment-send' "$variables" # send_status="$(graphql_output '.data.lnInvoicePaymentSend.status')" # [[ "${send_status}" = "PENDING" ]] || exit 1 # # Check for txns # retry 15 1 check_num_txns "3" -# check_for_ln_initiated_pending "$token_name" "$payment_hash" "10" \ +# check_for_ln_initiated_pending "alice" "$payment_hash" "10" \ # || exit 1 -# balance_while_pending="$(balance_for_wallet $token_name 'BTC')" +# balance_while_pending="$(balance_for_wallet alice 'BTC')" # [[ "$balance_while_pending" -lt "$initial_balance" ]] || exit 1 # # Cancel hodl invoice # lnd_outside_2_cli cancelinvoice "$payment_hash" # retry 15 1 check_num_txns "4" -# balance_after_pending_failed="$(balance_for_wallet $token_name 'BTC')" +# balance_after_pending_failed="$(balance_for_wallet alice 'BTC')" # [[ "$balance_after_pending_failed" == "$initial_balance" ]] || exit 1 -# run check_for_ln_initiated_pending "$token_name" "$payment_hash" "10" +# run check_for_ln_initiated_pending "alice" "$payment_hash" "10" # [[ "$status" -ne 0 ]] || exit 1 # } # @test "ln-send: ln settled - pending-to-failed usd payment" { # skip "missing xxd dep, failing on concourse" -# token_name="$ALICE_TOKEN_NAME" -# btc_wallet_name="$token_name.btc_wallet_id" -# usd_wallet_name="$token_name.usd_wallet_id" +# +# btc_wallet_name="alice.btc_wallet_id" +# usd_wallet_name="alice.usd_wallet_id" # threshold_amount=150000 # secret=$(xxd -l 32 -p /dev/urandom) @@ -651,12 +649,12 @@ usd_amount=50 # check_num_txns() { # expected_num="$1" -# num_txns="$(num_txns_for_hash "$token_name" "$payment_hash")" +# num_txns="$(num_txns_for_hash "alice" "$payment_hash")" # [[ "$num_txns" == "$expected_num" ]] || exit 1 # } -# initial_btc_balance="$(balance_for_wallet $token_name 'BTC')" -# initial_usd_balance="$(balance_for_wallet $token_name 'USD')" +# initial_btc_balance="$(balance_for_wallet alice 'BTC')" +# initial_usd_balance="$(balance_for_wallet alice 'USD')" # # Rebalance last hop so payment will succeed # rebalance_channel lnd_outside_cli lnd_outside_2_cli "$(( $threshold_amount * 2 ))" @@ -669,16 +667,16 @@ usd_amount=50 # --arg payment_request "$payment_request" \ # '{input: {walletId: $wallet_id, paymentRequest: $payment_request}}' # ) -# exec_graphql "$token_name" 'ln-invoice-payment-send' "$variables" +# exec_graphql "alice" 'ln-invoice-payment-send' "$variables" # send_status="$(graphql_output '.data.lnInvoicePaymentSend.status')" # [[ "${send_status}" = "PENDING" ]] || exit 1 # # Check for txns # retry 15 1 check_num_txns "1" -# check_for_ln_initiated_pending "$token_name" "$payment_hash" "10" \ +# check_for_ln_initiated_pending "alice" "$payment_hash" "10" \ # || exit 1 -# btc_balance_while_pending="$(balance_for_wallet $token_name 'BTC')" -# usd_balance_while_pending="$(balance_for_wallet $token_name 'USD')" +# btc_balance_while_pending="$(balance_for_wallet alice 'BTC')" +# usd_balance_while_pending="$(balance_for_wallet alice 'USD')" # [[ "$btc_balance_while_pending" == "$initial_btc_balance" ]] || exit 1 # [[ "$usd_balance_while_pending" -lt "$initial_usd_balance" ]] || exit 1 @@ -686,11 +684,11 @@ usd_amount=50 # lnd_outside_2_cli cancelinvoice "$payment_hash" # retry 15 1 check_num_txns "2" -# btc_balance_after_pending_failed="$(balance_for_wallet $token_name 'BTC')" -# usd_balance_after_pending_failed="$(balance_for_wallet $token_name 'USD')" +# btc_balance_after_pending_failed="$(balance_for_wallet alice 'BTC')" +# usd_balance_after_pending_failed="$(balance_for_wallet alice 'USD')" # [[ "$btc_balance_after_pending_failed" -gt "$btc_balance_while_pending" ]] || exit 1 # [[ "$usd_balance_after_pending_failed" == "$usd_balance_while_pending" ]] || exit 1 -# run check_for_ln_initiated_pending "$token_name" "$payment_hash" "10" +# run check_for_ln_initiated_pending "alice" "$payment_hash" "10" # [[ "$status" -ne 0 ]] || exit 1 # } diff --git a/bats/gql/ln-no-amount-usd-invoice-fee-probe.gql b/bats/gql/ln-no-amount-usd-invoice-fee-probe.gql new file mode 100644 index 0000000000..00bde20e62 --- /dev/null +++ b/bats/gql/ln-no-amount-usd-invoice-fee-probe.gql @@ -0,0 +1,8 @@ +mutation lnNoAmountUsdInvoiceFeeProbe($input: LnNoAmountUsdInvoiceFeeProbeInput!) { + lnNoAmountUsdInvoiceFeeProbe(input: $input) { + errors { + message + } + amount + } +} diff --git a/bats/gql/ln-no-amount-usd-invoice-payment-send.gql b/bats/gql/ln-no-amount-usd-invoice-payment-send.gql new file mode 100644 index 0000000000..a34ccee880 --- /dev/null +++ b/bats/gql/ln-no-amount-usd-invoice-payment-send.gql @@ -0,0 +1,8 @@ +mutation lnNoAmountUsdInvoicePaymentSend($input: LnNoAmountUsdInvoicePaymentInput!) { + lnNoAmountUsdInvoicePaymentSend(input: $input) { + errors { + message + } + status + } +} From 81dc32b20719bdf4ddf5b993dc633badae916e0b Mon Sep 17 00:00:00 2001 From: Sandipan Dey Date: Tue, 28 Nov 2023 13:57:10 +0530 Subject: [PATCH 5/6] test: all ln sends --- bats/core/api/ln-send.bats | 793 ++++++++++++++++----------------- bats/gql/ln-invoice-create.gql | 11 + bats/helpers/_common.bash | 17 + bats/helpers/ln.bash | 58 +++ 4 files changed, 473 insertions(+), 406 deletions(-) create mode 100644 bats/gql/ln-invoice-create.gql diff --git a/bats/core/api/ln-send.bats b/bats/core/api/ln-send.bats index 9f2fcf9c9d..bfb1ca5ff5 100644 --- a/bats/core/api/ln-send.bats +++ b/bats/core/api/ln-send.bats @@ -19,7 +19,8 @@ setup_file() { fund_user_onchain 'bob' 'btc_wallet' fund_user_onchain 'bob' 'usd_wallet' - fund_user_lightning 'alice' 'btc_wallet' '5000000' + fund_user_lightning 'alice' 'btc_wallet' '500000' + fund_user_lightning 'bob' 'btc_wallet' '500000' } btc_amount=1000 @@ -287,408 +288,388 @@ usd_amount=50 [[ "$lnd1_diff" -gt "0" ]] || exit 1 } -# @test "ln-send: intraledger settled - lnInvoicePaymentSend from btc to btc, with contacts check" { -# -# btc_wallet_name="alice.btc_wallet_id" - -# recipient_token_name="user_$RANDOM" -# recipient_phone="$(random_phone)" -# login_user \ -# "$recipient_token_name" \ -# "$recipient_phone" \ -# "$CODE" -# user_update_username "$recipient_token_name" -# btc_recipient_wallet_name="$recipient_token_name.btc_wallet_id" - -# initial_balance="$(balance_for_wallet alice 'BTC')" -# initial_lnd1_balance=$(lnd_cli channelbalance | jq -r '.balance') - -# # Check is not contact before send -# run is_contact "alice" "$recipient_token_name" -# [[ "$status" -ne "0" ]] || exit 1 -# run is_contact "$recipient_token_name" "alice" -# [[ "$status" -ne "0" ]] || exit 1 - -# variables=$( -# jq -n \ -# --arg wallet_id "$(read_value $btc_recipient_wallet_name)" \ -# --arg amount "$btc_amount" \ -# '{input: {walletId: $wallet_id, amount: $amount}}' -# ) -# exec_graphql "$recipient_token_name" 'ln-invoice-create' "$variables" -# invoice="$(graphql_output '.data.lnInvoiceCreate.invoice')" - -# payment_request="$(echo $invoice | jq -r '.paymentRequest')" -# [[ "${payment_request}" != "null" ]] || exit 1 -# payment_hash="$(echo $invoice | jq -r '.paymentHash')" -# [[ "${payment_hash}" != "null" ]] || exit 1 - -# variables=$( -# jq -n \ -# --arg wallet_id "$(read_value $btc_wallet_name)" \ -# --arg payment_request "$payment_request" \ -# '{input: {walletId: $wallet_id, paymentRequest: $payment_request}}' -# ) - -# exec_graphql "alice" 'ln-invoice-payment-send' "$variables" -# send_status="$(graphql_output '.data.lnInvoicePaymentSend.status')" -# [[ "${send_status}" = "SUCCESS" ]] || exit 1 - -# # Check for settled -# retry 15 1 check_for_ln_initiated_settled "alice" "$payment_hash" -# check_for_ln_initiated_settled "$recipient_token_name" "$payment_hash" - -# final_balance="$(balance_for_wallet alice 'BTC')" -# wallet_diff="$(( $initial_balance - $final_balance ))" -# [[ "$wallet_diff" == "$btc_amount" ]] || exit 1 - -# final_lnd1_balance=$(lnd_cli channelbalance | jq -r '.balance') -# lnd1_diff="$(( $initial_lnd1_balance - $final_lnd1_balance ))" -# [[ "$lnd1_diff" == "0" ]] || exit 1 - -# # Check is contact after send -# run is_contact "alice" "$recipient_token_name" -# [[ "$status" == "0" ]] || exit 1 -# run is_contact "$recipient_token_name" "alice" -# [[ "$status" == "0" ]] || exit 1 -# } - -# @test "ln-send: intraledger settled - lnInvoicePaymentSend from usd to btc" { -# -# usd_wallet_name="alice.usd_wallet_id" - -# recipient_token_name="$BOB_TOKEN_NAME" -# btc_recipient_wallet_name="$recipient_token_name.btc_wallet_id" - -# initial_recipient_balance="$(balance_for_wallet $recipient_token_name 'BTC')" -# initial_lnd1_balance=$(lnd_cli channelbalance | jq -r '.balance') - -# variables=$( -# jq -n \ -# --arg wallet_id "$(read_value $btc_recipient_wallet_name)" \ -# --arg amount "$btc_amount" \ -# '{input: {walletId: $wallet_id, amount: $amount}}' -# ) -# exec_graphql "$recipient_token_name" 'ln-invoice-create' "$variables" -# invoice="$(graphql_output '.data.lnInvoiceCreate.invoice')" - -# payment_request="$(echo $invoice | jq -r '.paymentRequest')" -# [[ "${payment_request}" != "null" ]] || exit 1 -# payment_hash="$(echo $invoice | jq -r '.paymentHash')" -# [[ "${payment_hash}" != "null" ]] || exit 1 - -# variables=$( -# jq -n \ -# --arg wallet_id "$(read_value $usd_wallet_name)" \ -# --arg payment_request "$payment_request" \ -# '{input: {walletId: $wallet_id, paymentRequest: $payment_request}}' -# ) - -# exec_graphql "alice" 'ln-usd-invoice-fee-probe' "$variables" -# fee_amount="$(graphql_output '.data.lnUsdInvoiceFeeProbe.amount')" -# [[ "${fee_amount}" = "0" ]] || exit 1 - -# exec_graphql "alice" 'ln-invoice-payment-send' "$variables" -# send_status="$(graphql_output '.data.lnInvoicePaymentSend.status')" -# [[ "${send_status}" = "SUCCESS" ]] || exit 1 - -# # Check for settled -# retry 15 1 check_for_ln_initiated_settled "alice" "$payment_hash" -# check_for_ln_initiated_settled "$recipient_token_name" "$payment_hash" - -# final_recipient_balance="$(balance_for_wallet $recipient_token_name 'BTC')" -# recipient_wallet_diff="$(( $final_recipient_balance - $initial_recipient_balance ))" -# [[ "$recipient_wallet_diff" == "$btc_amount" ]] || exit 1 - -# final_lnd1_balance=$(lnd_cli channelbalance | jq -r '.balance') -# lnd1_diff="$(( $initial_lnd1_balance - $final_lnd1_balance ))" -# [[ "$lnd1_diff" == "0" ]] || exit 1 -# } - -# @test "ln-send: intraledger settled - lnNoAmountInvoicePaymentSend from btc to usd" { -# -# btc_wallet_name="alice.btc_wallet_id" - -# recipient_token_name="$BOB_TOKEN_NAME" -# usd_recipient_wallet_name="$recipient_token_name.usd_wallet_id" - -# initial_balance="$(balance_for_wallet alice 'BTC')" -# initial_lnd1_balance=$(lnd_cli channelbalance | jq -r '.balance') - -# variables=$( -# jq -n \ -# --arg wallet_id "$(read_value $usd_recipient_wallet_name)" \ -# '{input: {walletId: $wallet_id}}' -# ) -# exec_graphql "$recipient_token_name" 'ln-no-amount-invoice-create' "$variables" -# invoice="$(graphql_output '.data.lnNoAmountInvoiceCreate.invoice')" - -# payment_request="$(echo $invoice | jq -r '.paymentRequest')" -# [[ "${payment_request}" != "null" ]] || exit 1 -# payment_hash="$(echo $invoice | jq -r '.paymentHash')" -# [[ "${payment_hash}" != "null" ]] || exit 1 - -# variables=$( -# jq -n \ -# --arg wallet_id "$(read_value $btc_wallet_name)" \ -# --arg payment_request "$payment_request" \ -# --arg amount $btc_amount \ -# '{input: {walletId: $wallet_id, paymentRequest: $payment_request, amount: $amount}}' -# ) - -# exec_graphql "alice" 'ln-no-amount-invoice-payment-send' "$variables" -# send_status="$(graphql_output '.data.lnNoAmountInvoicePaymentSend.status')" -# [[ "${send_status}" = "SUCCESS" ]] || exit 1 - -# # Check for settled -# retry 15 1 check_for_ln_initiated_settled "alice" "$payment_hash" -# check_for_ln_initiated_settled "$recipient_token_name" "$payment_hash" - -# final_balance="$(balance_for_wallet alice 'BTC')" -# wallet_diff="$(( $initial_balance - $final_balance ))" -# [[ "$wallet_diff" == "$btc_amount" ]] || exit 1 - -# final_lnd1_balance=$(lnd_cli channelbalance | jq -r '.balance') -# lnd1_diff="$(( $initial_lnd1_balance - $final_lnd1_balance ))" -# [[ "$lnd1_diff" == "0" ]] || exit 1 -# } - -# @test "ln-send: intraledger settled - lnNoAmountUsdInvoicePaymentSend from usd to usd" { -# -# usd_wallet_name="alice.usd_wallet_id" - -# recipient_token_name="$BOB_TOKEN_NAME" -# usd_recipient_wallet_name="$recipient_token_name.usd_wallet_id" - -# initial_balance="$(balance_for_wallet alice 'USD')" -# initial_lnd1_balance=$(lnd_cli channelbalance | jq -r '.balance') - -# variables=$( -# jq -n \ -# --arg wallet_id "$(read_value $usd_recipient_wallet_name)" \ -# '{input: {walletId: $wallet_id}}' -# ) -# exec_graphql "$recipient_token_name" 'ln-no-amount-invoice-create' "$variables" -# invoice="$(graphql_output '.data.lnNoAmountInvoiceCreate.invoice')" - -# payment_request="$(echo $invoice | jq -r '.paymentRequest')" -# [[ "${payment_request}" != "null" ]] || exit 1 -# payment_hash="$(echo $invoice | jq -r '.paymentHash')" -# [[ "${payment_hash}" != "null" ]] || exit 1 - -# variables=$( -# jq -n \ -# --arg wallet_id "$(read_value $usd_wallet_name)" \ -# --arg payment_request "$payment_request" \ -# --arg amount $usd_amount \ -# '{input: {walletId: $wallet_id, paymentRequest: $payment_request, amount: $amount}}' -# ) - -# exec_graphql "alice" 'ln-no-amount-usd-invoice-payment-send' "$variables" -# send_status="$(graphql_output '.data.lnNoAmountUsdInvoicePaymentSend.status')" -# [[ "${send_status}" = "SUCCESS" ]] || exit 1 - -# # Check for settled -# retry 15 1 check_for_ln_initiated_settled "alice" "$payment_hash" -# check_for_ln_initiated_settled "$recipient_token_name" "$payment_hash" - -# final_balance="$(balance_for_wallet alice 'USD')" -# wallet_diff="$(( $initial_balance - $final_balance ))" -# [[ "$wallet_diff" == "$usd_amount" ]] || exit 1 - -# final_lnd1_balance=$(lnd_cli channelbalance | jq -r '.balance') -# lnd1_diff="$(( $initial_lnd1_balance - $final_lnd1_balance ))" -# [[ "$lnd1_diff" == "0" ]] || exit 1 -# } - -# @test "ln-send: ln settled - settle failed and then successful payment" { -# -# btc_wallet_name="alice.btc_wallet_id" - -# threshold_amount=150000 -# invoice_response="$(lnd_outside_2_cli addinvoice --amt $threshold_amount)" -# payment_request="$(echo $invoice_response | jq -r '.payment_request')" -# payment_hash=$(echo $invoice_response | jq -r '.r_hash') -# [[ "${payment_request}" != "null" ]] || exit 1 - -# check_num_txns() { -# expected_num="$1" - -# num_txns="$(num_txns_for_hash "alice" "$payment_hash")" -# [[ "$num_txns" == "$expected_num" ]] || exit 1 -# } - -# # Rebalance last hop so payment will fail -# rebalance_channel lnd_outside_cli lnd_outside_2_cli "$(( $threshold_amount - 1 ))" - -# # Try payment and check for fail -# initial_balance="$(balance_for_wallet alice 'BTC')" - -# variables=$( -# jq -n \ -# --arg wallet_id "$(read_value $btc_wallet_name)" \ -# --arg payment_request "$payment_request" \ -# '{input: {walletId: $wallet_id, paymentRequest: $payment_request}}' -# ) -# exec_graphql "alice" 'ln-invoice-payment-send' "$variables" -# send_status="$(graphql_output '.data.lnInvoicePaymentSend.status')" -# error_msg="$(graphql_output '.data.lnInvoicePaymentSend.errors[0].message')" -# [[ "${send_status}" = "FAILURE" ]] || exit 1 -# [[ "${error_msg}" == "Unable to find a route for payment." ]] || exit 1 - -# # Check for txns -# retry 15 1 check_num_txns "2" -# balance_after_fail="$(balance_for_wallet alice 'BTC')" -# [[ "$initial_balance" == "$balance_after_fail" ]] || exit 1 - -# # Rebalance last hop so same payment will succeed -# rebalance_channel lnd_outside_cli lnd_outside_2_cli "$(( $threshold_amount * 2 ))" -# lnd_cli resetmc - -# # Retry payment and check for success -# exec_graphql "alice" 'ln-invoice-fee-probe' "$variables" -# num_errors="$(graphql_output '.data.lnInvoiceFeeProbe.errors | length')" -# fee_amount="$(graphql_output '.data.lnInvoiceFeeProbe.amount')" -# [[ "$num_errors" == "0" ]] || exit 1 -# [[ "${fee_amount}" -gt "0" ]] || exit 1 - -# exec_graphql "alice" 'ln-invoice-payment-send' "$variables" -# send_status="$(graphql_output '.data.lnInvoicePaymentSend.status')" -# [[ "${send_status}" = "SUCCESS" ]] || exit 1 - -# # Check for txns -# retry 15 1 check_num_txns "3" -# balance_after_success="$(balance_for_wallet alice 'BTC')" -# [[ "$balance_after_success" -lt "$initial_balance" ]] || exit 1 -# } - -# @test "ln-send: ln settled - settle failed and then pending-to-failed payment" { -# skip "missing xxd dep, failing on concourse" - -# -# btc_wallet_name="alice.btc_wallet_id" - -# threshold_amount=150000 -# secret=$(xxd -l 32 -p /dev/urandom) -# payment_hash=$(echo -n $secret | xxd -r -p | sha256sum | cut -d ' ' -f1) -# invoice_response="$(lnd_outside_2_cli addholdinvoice $payment_hash --amt $threshold_amount)" -# payment_request="$(echo $invoice_response | jq -r '.payment_request')" -# [[ "${payment_request}" != "null" ]] || exit 1 - -# check_num_txns() { -# expected_num="$1" - -# num_txns="$(num_txns_for_hash "alice" "$payment_hash")" -# [[ "$num_txns" == "$expected_num" ]] || exit 1 -# } - -# # Rebalance last hop so payment will fail -# rebalance_channel lnd_outside_cli lnd_outside_2_cli "$(( $threshold_amount - 1 ))" - -# # Try payment and check for fail -# initial_balance="$(balance_for_wallet alice 'BTC')" - -# variables=$( -# jq -n \ -# --arg wallet_id "$(read_value $btc_wallet_name)" \ -# --arg payment_request "$payment_request" \ -# '{input: {walletId: $wallet_id, paymentRequest: $payment_request}}' -# ) -# exec_graphql "alice" 'ln-invoice-payment-send' "$variables" -# send_status="$(graphql_output '.data.lnInvoicePaymentSend.status')" -# error_msg="$(graphql_output '.data.lnInvoicePaymentSend.errors[0].message')" -# [[ "${send_status}" = "FAILURE" ]] || exit 1 -# [[ "${error_msg}" == "Unable to find a route for payment." ]] || exit 1 - -# # Check for txns -# retry 15 1 check_num_txns "2" -# balance_after_fail="$(balance_for_wallet alice 'BTC')" -# [[ "$initial_balance" == "$balance_after_fail" ]] || exit 1 - -# # Rebalance last hop so same payment will succeed -# rebalance_channel lnd_outside_cli lnd_outside_2_cli "$(( $threshold_amount * 2 ))" -# lnd_cli resetmc - -# # Retry payment and check for pending -# exec_graphql "alice" 'ln-invoice-payment-send' "$variables" -# send_status="$(graphql_output '.data.lnInvoicePaymentSend.status')" -# [[ "${send_status}" = "PENDING" ]] || exit 1 - -# # Check for txns -# retry 15 1 check_num_txns "3" -# check_for_ln_initiated_pending "alice" "$payment_hash" "10" \ -# || exit 1 -# balance_while_pending="$(balance_for_wallet alice 'BTC')" -# [[ "$balance_while_pending" -lt "$initial_balance" ]] || exit 1 - -# # Cancel hodl invoice -# lnd_outside_2_cli cancelinvoice "$payment_hash" - -# retry 15 1 check_num_txns "4" -# balance_after_pending_failed="$(balance_for_wallet alice 'BTC')" -# [[ "$balance_after_pending_failed" == "$initial_balance" ]] || exit 1 - -# run check_for_ln_initiated_pending "alice" "$payment_hash" "10" -# [[ "$status" -ne 0 ]] || exit 1 -# } - -# @test "ln-send: ln settled - pending-to-failed usd payment" { -# skip "missing xxd dep, failing on concourse" - -# -# btc_wallet_name="alice.btc_wallet_id" -# usd_wallet_name="alice.usd_wallet_id" - -# threshold_amount=150000 -# secret=$(xxd -l 32 -p /dev/urandom) -# payment_hash=$(echo -n $secret | xxd -r -p | sha256sum | cut -d ' ' -f1) -# invoice_response="$(lnd_outside_2_cli addholdinvoice $payment_hash --amt $threshold_amount)" -# payment_request="$(echo $invoice_response | jq -r '.payment_request')" -# [[ "${payment_request}" != "null" ]] || exit 1 - -# check_num_txns() { -# expected_num="$1" - -# num_txns="$(num_txns_for_hash "alice" "$payment_hash")" -# [[ "$num_txns" == "$expected_num" ]] || exit 1 -# } - -# initial_btc_balance="$(balance_for_wallet alice 'BTC')" -# initial_usd_balance="$(balance_for_wallet alice 'USD')" - -# # Rebalance last hop so payment will succeed -# rebalance_channel lnd_outside_cli lnd_outside_2_cli "$(( $threshold_amount * 2 ))" -# lnd_cli resetmc - -# # Try payment and check for pending -# variables=$( -# jq -n \ -# --arg wallet_id "$(read_value $usd_wallet_name)" \ -# --arg payment_request "$payment_request" \ -# '{input: {walletId: $wallet_id, paymentRequest: $payment_request}}' -# ) -# exec_graphql "alice" 'ln-invoice-payment-send' "$variables" -# send_status="$(graphql_output '.data.lnInvoicePaymentSend.status')" -# [[ "${send_status}" = "PENDING" ]] || exit 1 - -# # Check for txns -# retry 15 1 check_num_txns "1" -# check_for_ln_initiated_pending "alice" "$payment_hash" "10" \ -# || exit 1 -# btc_balance_while_pending="$(balance_for_wallet alice 'BTC')" -# usd_balance_while_pending="$(balance_for_wallet alice 'USD')" -# [[ "$btc_balance_while_pending" == "$initial_btc_balance" ]] || exit 1 -# [[ "$usd_balance_while_pending" -lt "$initial_usd_balance" ]] || exit 1 - -# # Cancel hodl invoice -# lnd_outside_2_cli cancelinvoice "$payment_hash" - -# retry 15 1 check_num_txns "2" -# btc_balance_after_pending_failed="$(balance_for_wallet alice 'BTC')" -# usd_balance_after_pending_failed="$(balance_for_wallet alice 'USD')" -# [[ "$btc_balance_after_pending_failed" -gt "$btc_balance_while_pending" ]] || exit 1 -# [[ "$usd_balance_after_pending_failed" == "$usd_balance_while_pending" ]] || exit 1 - -# run check_for_ln_initiated_pending "alice" "$payment_hash" "10" -# [[ "$status" -ne 0 ]] || exit 1 -# } +@test "ln-send: intraledger settled - lnInvoicePaymentSend from btc to btc, with contacts check" { + btc_wallet_name="alice.btc_wallet_id" + btc_recipient_wallet_name="bob.btc_wallet_id" + + initial_balance="$(balance_for_wallet alice 'BTC')" + initial_lnd1_balance=$(lnd_cli channelbalance | jq -r '.balance') + + # Check is not contact before send + run is_contact "alice" "bob" + [[ "$status" -ne "0" ]] || exit 1 + run is_contact "bob" "alice" + [[ "$status" -ne "0" ]] || exit 1 + + variables=$( + jq -n \ + --arg wallet_id "$(read_value $btc_recipient_wallet_name)" \ + --arg amount "$btc_amount" \ + '{input: {walletId: $wallet_id, amount: $amount}}' + ) + exec_graphql "bob" 'ln-invoice-create' "$variables" + invoice="$(graphql_output '.data.lnInvoiceCreate.invoice')" + + payment_request="$(echo $invoice | jq -r '.paymentRequest')" + [[ "${payment_request}" != "null" ]] || exit 1 + payment_hash="$(echo $invoice | jq -r '.paymentHash')" + [[ "${payment_hash}" != "null" ]] || exit 1 + + variables=$( + jq -n \ + --arg wallet_id "$(read_value $btc_wallet_name)" \ + --arg payment_request "$payment_request" \ + '{input: {walletId: $wallet_id, paymentRequest: $payment_request}}' + ) + + exec_graphql "alice" 'ln-invoice-payment-send' "$variables" + send_status="$(graphql_output '.data.lnInvoicePaymentSend.status')" + [[ "${send_status}" = "SUCCESS" ]] || exit 1 + + # Check for settled + retry 30 1 check_for_ln_initiated_settled "alice" "$payment_hash" + check_for_ln_initiated_settled "bob" "$payment_hash" + + final_balance="$(balance_for_wallet alice 'BTC')" + wallet_diff="$(( $initial_balance - $final_balance ))" + [[ "$wallet_diff" == "$btc_amount" ]] || exit 1 + + final_lnd1_balance=$(lnd_cli channelbalance | jq -r '.balance') + lnd1_diff="$(( $initial_lnd1_balance - $final_lnd1_balance ))" + [[ "$lnd1_diff" == "0" ]] || exit 1 + + # Check is contact after send + run is_contact "alice" "bob" + [[ "$status" == "0" ]] || exit 1 + run is_contact "bob" "alice" + [[ "$status" == "0" ]] || exit 1 +} + +@test "ln-send: intraledger settled - lnInvoicePaymentSend from usd to btc" { + usd_wallet_name="alice.usd_wallet_id" + btc_recipient_wallet_name="bob.btc_wallet_id" + + initial_recipient_balance="$(balance_for_wallet bob 'BTC')" + initial_lnd1_balance=$(lnd_cli channelbalance | jq -r '.balance') + + variables=$( + jq -n \ + --arg wallet_id "$(read_value $btc_recipient_wallet_name)" \ + --arg amount "$btc_amount" \ + '{input: {walletId: $wallet_id, amount: $amount}}' + ) + exec_graphql "bob" 'ln-invoice-create' "$variables" + invoice="$(graphql_output '.data.lnInvoiceCreate.invoice')" + + payment_request="$(echo $invoice | jq -r '.paymentRequest')" + [[ "${payment_request}" != "null" ]] || exit 1 + payment_hash="$(echo $invoice | jq -r '.paymentHash')" + [[ "${payment_hash}" != "null" ]] || exit 1 + + variables=$( + jq -n \ + --arg wallet_id "$(read_value $usd_wallet_name)" \ + --arg payment_request "$payment_request" \ + '{input: {walletId: $wallet_id, paymentRequest: $payment_request}}' + ) + + exec_graphql "alice" 'ln-usd-invoice-fee-probe' "$variables" + fee_amount="$(graphql_output '.data.lnUsdInvoiceFeeProbe.amount')" + [[ "${fee_amount}" = "0" ]] || exit 1 + + exec_graphql "alice" 'ln-invoice-payment-send' "$variables" + send_status="$(graphql_output '.data.lnInvoicePaymentSend.status')" + [[ "${send_status}" = "SUCCESS" ]] || exit 1 + + # Check for settled + retry 15 1 check_for_ln_initiated_settled "alice" "$payment_hash" + check_for_ln_initiated_settled "bob" "$payment_hash" + + final_recipient_balance="$(balance_for_wallet bob 'BTC')" + recipient_wallet_diff="$(( $final_recipient_balance - $initial_recipient_balance ))" + [[ "$recipient_wallet_diff" == "$btc_amount" ]] || exit 1 + + final_lnd1_balance=$(lnd_cli channelbalance | jq -r '.balance') + lnd1_diff="$(( $initial_lnd1_balance - $final_lnd1_balance ))" + [[ "$lnd1_diff" == "0" ]] || exit 1 +} + +@test "ln-send: intraledger settled - lnNoAmountInvoicePaymentSend from btc to usd" { + btc_wallet_name="alice.btc_wallet_id" + usd_recipient_wallet_name="bob.usd_wallet_id" + + initial_balance="$(balance_for_wallet alice 'BTC')" + initial_lnd1_balance=$(lnd_cli channelbalance | jq -r '.balance') + + variables=$( + jq -n \ + --arg wallet_id "$(read_value $usd_recipient_wallet_name)" \ + '{input: {walletId: $wallet_id}}' + ) + exec_graphql "bob" 'ln-no-amount-invoice-create' "$variables" + invoice="$(graphql_output '.data.lnNoAmountInvoiceCreate.invoice')" + + payment_request="$(echo $invoice | jq -r '.paymentRequest')" + [[ "${payment_request}" != "null" ]] || exit 1 + payment_hash="$(echo $invoice | jq -r '.paymentHash')" + [[ "${payment_hash}" != "null" ]] || exit 1 + + variables=$( + jq -n \ + --arg wallet_id "$(read_value $btc_wallet_name)" \ + --arg payment_request "$payment_request" \ + --arg amount $btc_amount \ + '{input: {walletId: $wallet_id, paymentRequest: $payment_request, amount: $amount}}' + ) + + exec_graphql "alice" 'ln-no-amount-invoice-payment-send' "$variables" + send_status="$(graphql_output '.data.lnNoAmountInvoicePaymentSend.status')" + [[ "${send_status}" = "SUCCESS" ]] || exit 1 + + # Check for settled + retry 15 1 check_for_ln_initiated_settled "alice" "$payment_hash" + check_for_ln_initiated_settled "bob" "$payment_hash" + + final_balance="$(balance_for_wallet alice 'BTC')" + wallet_diff="$(( $initial_balance - $final_balance ))" + [[ "$wallet_diff" == "$btc_amount" ]] || exit 1 + + final_lnd1_balance=$(lnd_cli channelbalance | jq -r '.balance') + lnd1_diff="$(( $initial_lnd1_balance - $final_lnd1_balance ))" + [[ "$lnd1_diff" == "0" ]] || exit 1 +} + +@test "ln-send: intraledger settled - lnNoAmountUsdInvoicePaymentSend from usd to usd" { + usd_wallet_name="alice.usd_wallet_id" + usd_recipient_wallet_name="bob.usd_wallet_id" + + initial_balance="$(balance_for_wallet alice 'USD')" + initial_lnd1_balance=$(lnd_cli channelbalance | jq -r '.balance') + + variables=$( + jq -n \ + --arg wallet_id "$(read_value $usd_recipient_wallet_name)" \ + '{input: {walletId: $wallet_id}}' + ) + exec_graphql "bob" 'ln-no-amount-invoice-create' "$variables" + invoice="$(graphql_output '.data.lnNoAmountInvoiceCreate.invoice')" + + payment_request="$(echo $invoice | jq -r '.paymentRequest')" + [[ "${payment_request}" != "null" ]] || exit 1 + payment_hash="$(echo $invoice | jq -r '.paymentHash')" + [[ "${payment_hash}" != "null" ]] || exit 1 + + variables=$( + jq -n \ + --arg wallet_id "$(read_value $usd_wallet_name)" \ + --arg payment_request "$payment_request" \ + --arg amount $usd_amount \ + '{input: {walletId: $wallet_id, paymentRequest: $payment_request, amount: $amount}}' + ) + + exec_graphql "alice" 'ln-no-amount-usd-invoice-payment-send' "$variables" + send_status="$(graphql_output '.data.lnNoAmountUsdInvoicePaymentSend.status')" + [[ "${send_status}" = "SUCCESS" ]] || exit 1 + + # Check for settled + retry 15 1 check_for_ln_initiated_settled "alice" "$payment_hash" + check_for_ln_initiated_settled "bob" "$payment_hash" + + final_balance="$(balance_for_wallet alice 'USD')" + wallet_diff="$(( $initial_balance - $final_balance ))" + [[ "$wallet_diff" == "$usd_amount" ]] || exit 1 + + final_lnd1_balance=$(lnd_cli channelbalance | jq -r '.balance') + lnd1_diff="$(( $initial_lnd1_balance - $final_lnd1_balance ))" + [[ "$lnd1_diff" == "0" ]] || exit 1 +} + +@test "ln-send: ln settled - settle failed and then successful payment" { + btc_wallet_name="alice.btc_wallet_id" + + threshold_amount=150000 + invoice_response="$(lnd_outside_2_cli addinvoice --amt $threshold_amount)" + payment_request="$(echo $invoice_response | jq -r '.payment_request')" + payment_hash=$(echo $invoice_response | jq -r '.r_hash') + [[ "${payment_request}" != "null" ]] || exit 1 + + check_num_txns() { + expected_num="$1" + + num_txns="$(num_txns_for_hash "alice" "$payment_hash")" + [[ "$num_txns" == "$expected_num" ]] || exit 1 + } + + # Rebalance last hop so payment will fail + rebalance_channel lnd_outside_cli lnd_outside_2_cli "$(( $threshold_amount - 1 ))" + + # Try payment and check for fail + initial_balance="$(balance_for_wallet alice 'BTC')" + + variables=$( + jq -n \ + --arg wallet_id "$(read_value $btc_wallet_name)" \ + --arg payment_request "$payment_request" \ + '{input: {walletId: $wallet_id, paymentRequest: $payment_request}}' + ) + exec_graphql "alice" 'ln-invoice-payment-send' "$variables" + send_status="$(graphql_output '.data.lnInvoicePaymentSend.status')" + error_msg="$(graphql_output '.data.lnInvoicePaymentSend.errors[0].message')" + [[ "${send_status}" = "FAILURE" ]] || exit 1 + [[ "${error_msg}" == "Unable to find a route for payment." ]] || exit 1 + + # Check for txns + retry 15 1 check_num_txns "2" + balance_after_fail="$(balance_for_wallet alice 'BTC')" + [[ "$initial_balance" == "$balance_after_fail" ]] || exit 1 + + # Rebalance last hop so same payment will succeed + rebalance_channel lnd_outside_cli lnd_outside_2_cli "$(( $threshold_amount * 2 ))" + lnd_cli resetmc + + # Retry payment and check for success + exec_graphql "alice" 'ln-invoice-fee-probe' "$variables" + num_errors="$(graphql_output '.data.lnInvoiceFeeProbe.errors | length')" + fee_amount="$(graphql_output '.data.lnInvoiceFeeProbe.amount')" + [[ "$num_errors" == "0" ]] || exit 1 + [[ "${fee_amount}" -gt "0" ]] || exit 1 + + exec_graphql "alice" 'ln-invoice-payment-send' "$variables" + send_status="$(graphql_output '.data.lnInvoicePaymentSend.status')" + [[ "${send_status}" = "SUCCESS" ]] || exit 1 + + # Check for txns + retry 15 1 check_num_txns "3" + balance_after_success="$(balance_for_wallet alice 'BTC')" + [[ "$balance_after_success" -lt "$initial_balance" ]] || exit 1 +} + +@test "ln-send: ln settled - settle failed and then pending-to-failed payment" { + skip "missing xxd dep, failing on concourse" + + btc_wallet_name="alice.btc_wallet_id" + + threshold_amount=150000 + secret=$(xxd -l 32 -p /dev/urandom) + payment_hash=$(echo -n $secret | xxd -r -p | sha256sum | cut -d ' ' -f1) + invoice_response="$(lnd_outside_2_cli addholdinvoice $payment_hash --amt $threshold_amount)" + payment_request="$(echo $invoice_response | jq -r '.payment_request')" + [[ "${payment_request}" != "null" ]] || exit 1 + + check_num_txns() { + expected_num="$1" + + num_txns="$(num_txns_for_hash "alice" "$payment_hash")" + [[ "$num_txns" == "$expected_num" ]] || exit 1 + } + + # Rebalance last hop so payment will fail + rebalance_channel lnd_outside_cli lnd_outside_2_cli "$(( $threshold_amount - 1 ))" + + # Try payment and check for fail + initial_balance="$(balance_for_wallet alice 'BTC')" + + variables=$( + jq -n \ + --arg wallet_id "$(read_value $btc_wallet_name)" \ + --arg payment_request "$payment_request" \ + '{input: {walletId: $wallet_id, paymentRequest: $payment_request}}' + ) + exec_graphql "alice" 'ln-invoice-payment-send' "$variables" + send_status="$(graphql_output '.data.lnInvoicePaymentSend.status')" + error_msg="$(graphql_output '.data.lnInvoicePaymentSend.errors[0].message')" + [[ "${send_status}" = "FAILURE" ]] || exit 1 + [[ "${error_msg}" == "Unable to find a route for payment." ]] || exit 1 + + # Check for txns + retry 15 1 check_num_txns "2" + balance_after_fail="$(balance_for_wallet alice 'BTC')" + [[ "$initial_balance" == "$balance_after_fail" ]] || exit 1 + + # Rebalance last hop so same payment will succeed + rebalance_channel lnd_outside_cli lnd_outside_2_cli "$(( $threshold_amount * 2 ))" + lnd_cli resetmc + + # Retry payment and check for pending + exec_graphql "alice" 'ln-invoice-payment-send' "$variables" + send_status="$(graphql_output '.data.lnInvoicePaymentSend.status')" + [[ "${send_status}" = "PENDING" ]] || exit 1 + + # Check for txns + retry 15 1 check_num_txns "3" + check_for_ln_initiated_pending "alice" "$payment_hash" "10" \ + || exit 1 + balance_while_pending="$(balance_for_wallet alice 'BTC')" + [[ "$balance_while_pending" -lt "$initial_balance" ]] || exit 1 + + # Cancel hodl invoice + lnd_outside_2_cli cancelinvoice "$payment_hash" + + retry 15 1 check_num_txns "4" + balance_after_pending_failed="$(balance_for_wallet alice 'BTC')" + [[ "$balance_after_pending_failed" == "$initial_balance" ]] || exit 1 + + run check_for_ln_initiated_pending "alice" "$payment_hash" "10" + [[ "$status" -ne 0 ]] || exit 1 +} + +@test "ln-send: ln settled - pending-to-failed usd payment" { + skip "missing xxd dep, failing on concourse" + + + btc_wallet_name="alice.btc_wallet_id" + usd_wallet_name="alice.usd_wallet_id" + + threshold_amount=150000 + secret=$(xxd -l 32 -p /dev/urandom) + payment_hash=$(echo -n $secret | xxd -r -p | sha256sum | cut -d ' ' -f1) + invoice_response="$(lnd_outside_2_cli addholdinvoice $payment_hash --amt $threshold_amount)" + payment_request="$(echo $invoice_response | jq -r '.payment_request')" + [[ "${payment_request}" != "null" ]] || exit 1 + + check_num_txns() { + expected_num="$1" + + num_txns="$(num_txns_for_hash "alice" "$payment_hash")" + [[ "$num_txns" == "$expected_num" ]] || exit 1 + } + + initial_btc_balance="$(balance_for_wallet alice 'BTC')" + initial_usd_balance="$(balance_for_wallet alice 'USD')" + + # Rebalance last hop so payment will succeed + rebalance_channel lnd_outside_cli lnd_outside_2_cli "$(( $threshold_amount * 2 ))" + lnd_cli resetmc + + # Try payment and check for pending + variables=$( + jq -n \ + --arg wallet_id "$(read_value $usd_wallet_name)" \ + --arg payment_request "$payment_request" \ + '{input: {walletId: $wallet_id, paymentRequest: $payment_request}}' + ) + exec_graphql "alice" 'ln-invoice-payment-send' "$variables" + send_status="$(graphql_output '.data.lnInvoicePaymentSend.status')" + [[ "${send_status}" = "PENDING" ]] || exit 1 + + # Check for txns + retry 15 1 check_num_txns "1" + check_for_ln_initiated_pending "alice" "$payment_hash" "10" \ + || exit 1 + btc_balance_while_pending="$(balance_for_wallet alice 'BTC')" + usd_balance_while_pending="$(balance_for_wallet alice 'USD')" + [[ "$btc_balance_while_pending" == "$initial_btc_balance" ]] || exit 1 + [[ "$usd_balance_while_pending" -lt "$initial_usd_balance" ]] || exit 1 + + # Cancel hodl invoice + lnd_outside_2_cli cancelinvoice "$payment_hash" + + retry 15 1 check_num_txns "2" + btc_balance_after_pending_failed="$(balance_for_wallet alice 'BTC')" + usd_balance_after_pending_failed="$(balance_for_wallet alice 'USD')" + [[ "$btc_balance_after_pending_failed" -gt "$btc_balance_while_pending" ]] || exit 1 + [[ "$usd_balance_after_pending_failed" == "$usd_balance_while_pending" ]] || exit 1 + + run check_for_ln_initiated_pending "alice" "$payment_hash" "10" + [[ "$status" -ne 0 ]] || exit 1 +} diff --git a/bats/gql/ln-invoice-create.gql b/bats/gql/ln-invoice-create.gql new file mode 100644 index 0000000000..3e3a27d0a0 --- /dev/null +++ b/bats/gql/ln-invoice-create.gql @@ -0,0 +1,11 @@ +mutation lnInvoiceCreateInput($input: LnInvoiceCreateInput!) { + lnInvoiceCreate(input: $input) { + invoice { + paymentRequest + paymentHash + } + errors { + message + } + } +} diff --git a/bats/helpers/_common.bash b/bats/helpers/_common.bash index 96080dc52c..5eb6778920 100644 --- a/bats/helpers/_common.bash +++ b/bats/helpers/_common.bash @@ -53,6 +53,23 @@ retry() { false } +is_number() { + if ! [[ $1 =~ ^-?[0-9]+$ ]]; then + echo "Error: $2 input is not a number: $1" + exit 1 + fi +} + +abs() { + is_number $1 || return 1 + + if [[ $1 -lt 0 ]]; then + echo "$((- $1))" + else + echo "$1" + fi +} + gql_query() { cat "$(gql_file "$1")" | tr '\n' ' ' | sed 's/"/\\"/g' } diff --git a/bats/helpers/ln.bash b/bats/helpers/ln.bash index 60416e453b..ff57a08814 100644 --- a/bats/helpers/ln.bash +++ b/bats/helpers/ln.bash @@ -195,3 +195,61 @@ mempool_not_empty() { local txid="$(bitcoin_cli getrawmempool | jq -r ".[0]")" [[ "$txid" != "null" ]] || exit 1 } + +num_txns_for_hash() { + token_name="$1" + payment_hash="$2" + + first=20 + txn_variables=$( + jq -n \ + --argjson first "$first" \ + '{"first": $first}' + ) + exec_graphql "$token_name" 'transactions' "$txn_variables" > /dev/null + + jq_query=' + [ + .data.me.defaultAccount.transactions.edges[] + | select(.node.initiationVia.paymentHash == $payment_hash) + ] + | length + ' + echo $output \ + | jq -r \ + --arg payment_hash "$payment_hash" \ + "$jq_query" +} + + +rebalance_channel() { + lnd_cli_value="$1" + lnd_partner_cli_value="$2" + target_local_balance="$3" + + local_pubkey="$(run_with_lnd $lnd_cli_value getinfo | jq -r '.identity_pubkey')" + remote_pubkey="$(run_with_lnd $lnd_partner_cli_value getinfo | jq -r '.identity_pubkey')" + + partner_channel_filter=' + [ + .channels[]? + | select(.remote_pubkey == $remote_pubkey) + ] | first + ' + + channel=$( + run_with_lnd "$lnd_cli_value" listchannels \ + | jq -r \ + --arg remote_pubkey "$remote_pubkey" \ + "$partner_channel_filter" + ) + [[ "$channel" != "null" ]] + + actual_local_balance=$(echo $channel | jq -r '.local_balance') + diff="$(( $actual_local_balance - $target_local_balance ))" + if [[ "$diff" -gt 0 ]]; then + run_with_lnd "$lnd_cli_value" sendpayment --dest=$remote_pubkey --amt=$diff --keysend + elif [[ "$diff" -lt 0 ]]; then + run_with_lnd "$lnd_partner_cli_value" sendpayment --dest=$local_pubkey --amt="$(abs $diff)" --keysend + fi +} From c4610c8a15fd0c70bbb5c70e4f4076e60ff7bf39 Mon Sep 17 00:00:00 2001 From: Sandipan Dey Date: Wed, 29 Nov 2023 14:15:13 +0530 Subject: [PATCH 6/6] test: all ln receives --- bats/core/api/ln-receive.bats | 380 ++++++++++++++++++ bats/gql/account-details.gql | 8 + .../invoice-for-wallet-by-payment-hash.gql | 17 + bats/gql/ln-usd-invoice-create.gql | 11 + bats/gql/my-updates-sub.gql | 57 +++ bats/gql/transaction-for-wallet-by-id.gql | 54 +++ ...ransactions-for-wallet-by-payment-hash.gql | 57 +++ bats/helpers/callback.bash | 31 ++ bats/helpers/callback/BUCK | 9 + bats/helpers/callback/package.json | 10 + bats/helpers/callback/pnpm-lock.yaml | 285 +++++++++++++ bats/helpers/callback/pnpm-workspace.yaml | 1 + .../helpers/callback/src/callback.ts | 2 +- bats/helpers/ln.bash | 18 + core/api/test/bats/helpers/ln.bash | 20 + 15 files changed, 959 insertions(+), 1 deletion(-) create mode 100644 bats/core/api/ln-receive.bats create mode 100644 bats/gql/account-details.gql create mode 100644 bats/gql/invoice-for-wallet-by-payment-hash.gql create mode 100644 bats/gql/ln-usd-invoice-create.gql create mode 100644 bats/gql/my-updates-sub.gql create mode 100644 bats/gql/transaction-for-wallet-by-id.gql create mode 100644 bats/gql/transactions-for-wallet-by-payment-hash.gql create mode 100644 bats/helpers/callback.bash create mode 100644 bats/helpers/callback/BUCK create mode 100644 bats/helpers/callback/package.json create mode 100644 bats/helpers/callback/pnpm-lock.yaml create mode 100644 bats/helpers/callback/pnpm-workspace.yaml rename core/api/test/bats/helpers/callback.js => bats/helpers/callback/src/callback.ts (92%) diff --git a/bats/core/api/ln-receive.bats b/bats/core/api/ln-receive.bats new file mode 100644 index 0000000000..6e906111a6 --- /dev/null +++ b/bats/core/api/ln-receive.bats @@ -0,0 +1,380 @@ +#!/usr/bin/env bats + +load "../../helpers/cli.bash" +load "../../helpers/user.bash" +load "../../helpers/onchain.bash" +load "../../helpers/ln.bash" +load "../../helpers/wallet.bash" +load "../../helpers/callback.bash" +load "../../helpers/subscriber.bash" + +setup_file() { + lnds_init + + create_user 'alice' + user_update_username 'alice' + fund_user_onchain 'alice' 'btc_wallet' + fund_user_onchain 'alice' 'usd_wallet' + add_callback 'alice' + + fund_user_lightning 'alice' 'btc_wallet' '500000' + + subscribe_to 'alice' my-updates-sub + sleep 3 +} + +btc_amount=1000 +usd_amount=50 + +@test "ln-receive: settle via ln for BTC wallet, invoice with amount" { + btc_wallet_name="alice.btc_wallet_id" + + # Check callback events before + exec_graphql "alice" 'account-details' + account_id="$(graphql_output '.data.me.defaultAccount.id')" + [[ "$account_id" != "null" ]] || exit 1 + + start_callback + num_callback_events_before=$(cat $CALLBACK_LOG_FILE | grep "$account_id" | wc -l) + + # Generate invoice + variables=$( + jq -n \ + --arg wallet_id "$(read_value $btc_wallet_name)" \ + --arg amount "$btc_amount" \ + '{input: {walletId: $wallet_id, amount: $amount}}' + ) + exec_graphql "alice" 'ln-invoice-create' "$variables" + invoice="$(graphql_output '.data.lnInvoiceCreate.invoice')" + + payment_request="$(echo $invoice | jq -r '.paymentRequest')" + [[ "${payment_request}" != "null" ]] || exit 1 + payment_hash="$(echo $invoice | jq -r '.paymentHash')" + [[ "${payment_hash}" != "null" ]] || exit 1 + + # Get invoice by hash + variables=$( + jq -n \ + --arg wallet_id "$(read_value $btc_wallet_name)" \ + --arg payment_hash "$payment_hash" \ + '{walletId: $wallet_id, paymentHash: $payment_hash}' + ) + exec_graphql "alice" 'invoice-for-wallet-by-payment-hash' "$variables" + query_payment_hash="$(graphql_output '.data.me.defaultAccount.walletById.invoiceByPaymentHash.paymentHash')" + invoice_status="$(graphql_output '.data.me.defaultAccount.walletById.invoiceByPaymentHash.paymentStatus')" + [[ "${query_payment_hash}" == "${payment_hash}" ]] || exit 1 + [[ "${invoice_status}" == "PENDING" ]] || exit 1 + + # Receive payment + lnd_outside_cli payinvoice -f \ + --pay_req "$payment_request" + + # Check for settled + retry 15 1 check_for_ln_initiated_settled "alice" "$payment_hash" + + # Check for subscriber event + check_for_ln_update "$payment_hash" || exit 1 + + # Get transaction by hash + variables=$( + jq -n \ + --arg wallet_id "$(read_value $btc_wallet_name)" \ + --arg payment_hash "$payment_hash" \ + '{walletId: $wallet_id, paymentHash: $payment_hash}' + ) + + exec_graphql "alice" 'transactions-for-wallet-by-payment-hash' "$variables" + query_payment_hash="$(graphql_output '.data.me.defaultAccount.walletById.transactionsByPaymentHash[0].initiationVia.paymentHash')" + [[ "${query_payment_hash}" == "${payment_hash}" ]] || exit 1 + transaction_id="$(graphql_output '.data.me.defaultAccount.walletById.transactionsByPaymentHash[0].id')" + + # Get transaction by tx id + variables=$( + jq -n \ + --arg wallet_id "$(read_value $btc_wallet_name)" \ + --arg transaction_id "$transaction_id" \ + '{walletId: $wallet_id, transactionId: $transaction_id}' + ) + exec_graphql "alice" 'transaction-for-wallet-by-id' "$variables" + query_transaction_id="$(graphql_output '.data.me.defaultAccount.walletById.transactionById.id')" + [[ "${query_transaction_id}" == "${transaction_id}" ]] || exit 1 + + # Ensure invoice status is paid + variables=$( + jq -n \ + --arg wallet_id "$(read_value $btc_wallet_name)" \ + --arg payment_hash "$payment_hash" \ + '{walletId: $wallet_id, paymentHash: $payment_hash}' + ) + exec_graphql "alice" 'invoice-for-wallet-by-payment-hash' "$variables" + invoice_status="$(graphql_output '.data.me.defaultAccount.walletById.invoiceByPaymentHash.paymentStatus')" + [[ "${invoice_status}" == "PAID" ]] || exit 1 + + # Check for callback + num_callback_events_after=$(cat $CALLBACK_LOG_FILE | grep "$account_id" | wc -l) + [[ "$num_callback_events_after" -gt "$num_callback_events_before" ]] || exit 1 + + stop_callback +} + +@test "ln-receive: settle via ln for USD wallet, invoice with amount" { + # Generate invoice + usd_wallet_name="alice.usd_wallet_id" + + variables=$( + jq -n \ + --arg wallet_id "$(read_value $usd_wallet_name)" \ + --arg amount "$usd_amount" \ + '{input: {walletId: $wallet_id, amount: $amount}}' + ) + exec_graphql "alice" 'ln-usd-invoice-create' "$variables" + invoice="$(graphql_output '.data.lnUsdInvoiceCreate.invoice')" + + payment_request="$(echo $invoice | jq -r '.paymentRequest')" + [[ "${payment_request}" != "null" ]] || exit 1 + payment_hash="$(echo $invoice | jq -r '.paymentHash')" + [[ "${payment_hash}" != "null" ]] || exit 1 + + # Receive payment + lnd_outside_cli payinvoice -f \ + --pay_req "$payment_request" + + # Check for settled + retry 15 1 check_for_ln_initiated_settled "alice" "$payment_hash" + + # Check for subscriber event + check_for_ln_update "$payment_hash" || exit 1 +} + +@test "ln-receive: settle via ln for BTC wallet, amountless invoice" { + btc_wallet_name="alice.btc_wallet_id" + + # Generate invoice + variables=$( + jq -n \ + --arg wallet_id "$(read_value $btc_wallet_name)" \ + '{input: {walletId: $wallet_id}}' + ) + exec_graphql "alice" 'ln-no-amount-invoice-create' "$variables" + invoice="$(graphql_output '.data.lnNoAmountInvoiceCreate.invoice')" + + payment_request="$(echo $invoice | jq -r '.paymentRequest')" + [[ "${payment_request}" != "null" ]] || exit 1 + payment_hash="$(echo $invoice | jq -r '.paymentHash')" + [[ "${payment_hash}" != "null" ]] || exit 1 + + # Receive payment + lnd_outside_cli payinvoice -f \ + --pay_req "$payment_request" \ + --amt "$btc_amount" + + # Check for settled + retry 15 1 check_for_ln_initiated_settled "alice" "$payment_hash" + + # Check for subscriber event + check_for_ln_update "$payment_hash" || exit 1 +} + +@test "ln-receive: handle less-than-1-sat ln payment for BTC wallet" { + btc_wallet_name="alice.btc_wallet_id" + + # Generate amountless invoice + invoice_variables=$( + jq -n \ + --arg wallet_id "$(read_value $btc_wallet_name)" \ + '{input: {walletId: $wallet_id}}' + ) + exec_graphql "alice" 'ln-no-amount-invoice-create' "$invoice_variables" + invoice="$(graphql_output '.data.lnNoAmountInvoiceCreate.invoice')" + + payment_request="$(echo $invoice | jq -r '.paymentRequest')" + [[ "${payment_request}" != "null" ]] || exit 1 + payment_hash="$(echo $invoice | jq -r '.paymentHash')" + [[ "${payment_hash}" != "null" ]] || exit 1 + + # Check that invoice is retrievable from lnd1 + invoice_from_lnd=$(lnd_cli lookupinvoice "$payment_hash") + [[ -n $invoice_from_lnd ]] || exit 1 + + # Receive less-than-1-sat payment + pay_variables=$( + jq -n \ + --arg payment_request "$payment_request" \ + --arg amt_msat "995" \ + --arg timeout_seconds "5" \ + '{payment_request: $payment_request, amt_msat: $amt_msat, timeout_seconds: $timeout_seconds}'\ + | tr -d '[:space:]') + lnd_outside_rest "v2/router/send" "$pay_variables" + + # Check that payment fails + response=$(tail -n 1 "$LNDS_REST_LOG") + [[ -n $response ]] || exit 1 + pay_status=$(echo $response | jq -r '.result.status') + [[ "$pay_status" == "FAILED" ]] || exit 1 + failure_reason=$(echo $response | jq -r '.result.failure_reason') + [[ "$failure_reason" == "FAILURE_REASON_INCORRECT_PAYMENT_DETAILS" ]] || exit 1 + + # Check that invoice is removed from lnd1 + invoice_from_lnd=$(lnd_cli lookupinvoice "$payment_hash") || true + [[ -z $invoice_from_lnd ]] || exit 1 +} + +@test "ln-receive: settle via ln for USD wallet, amountless invoice" { + # Generate invoice + usd_wallet_name="alice.usd_wallet_id" + + variables=$( + jq -n \ + --arg wallet_id "$(read_value $usd_wallet_name)" \ + '{input: {walletId: $wallet_id}}' + ) + exec_graphql "alice" 'ln-no-amount-invoice-create' "$variables" + invoice="$(graphql_output '.data.lnNoAmountInvoiceCreate.invoice')" + + payment_request="$(echo $invoice | jq -r '.paymentRequest')" + [[ "${payment_request}" != "null" ]] || exit 1 + payment_hash="$(echo $invoice | jq -r '.paymentHash')" + [[ "${payment_hash}" != "null" ]] || exit 1 + + # Receive payment + lnd_outside_cli payinvoice -f \ + --pay_req "$payment_request" \ + --amt "$btc_amount" + + # Check for settled + retry 15 1 check_for_ln_initiated_settled "alice" "$payment_hash" + + # Check for subscriber event + check_for_ln_update "$payment_hash" || exit 1 +} + +@test "ln-receive: settles btc-wallet invoices created while trigger down" { + token_name="$ALICE_TOKEN_NAME" + btc_wallet_name="alice.btc_wallet_id" + + # Stop trigger + # stop_trigger + + # Generate invoice + variables=$( + jq -n \ + --arg wallet_id "$(read_value $btc_wallet_name)" \ + '{input: {walletId: $wallet_id}}' + ) + exec_graphql "alice" 'ln-no-amount-invoice-create' "$variables" + invoice="$(graphql_output '.data.lnNoAmountInvoiceCreate.invoice')" + + payment_request="$(echo $invoice | jq -r '.paymentRequest')" + [[ "${payment_request}" != "null" ]] || exit 1 + payment_hash="$(echo $invoice | jq -r '.paymentHash')" + [[ "${payment_hash}" != "null" ]] || exit 1 + + # Start trigger + # start_trigger + sleep 5 + + # Pay invoice & check for settled + lnd_outside_cli payinvoice -f \ + --pay_req "$payment_request" \ + --amt "$btc_amount" + + retry 15 1 check_for_ln_initiated_settled "alice" "$payment_hash" +} + +@test "ln-receive: settles usd-wallet invoices created while trigger down" { + usd_wallet_name="alice.usd_wallet_id" + + # Stop trigger + # stop_trigger + + # Generate invoice + variables=$( + jq -n \ + --arg wallet_id "$(read_value $usd_wallet_name)" \ + '{input: {walletId: $wallet_id}}' + ) + exec_graphql "alice" 'ln-no-amount-invoice-create' "$variables" + invoice="$(graphql_output '.data.lnNoAmountInvoiceCreate.invoice')" + + payment_request="$(echo $invoice | jq -r '.paymentRequest')" + [[ "${payment_request}" != "null" ]] || exit 1 + payment_hash="$(echo $invoice | jq -r '.paymentHash')" + [[ "${payment_hash}" != "null" ]] || exit 1 + + # Start trigger + # start_trigger + sleep 5 + + # Pay invoice & check for settled + lnd_outside_cli payinvoice -f \ + --pay_req "$payment_request" \ + --amt "$btc_amount" + + retry 15 1 check_for_ln_initiated_settled "alice" "$payment_hash" +} + +@test "ln-receive: settles btc-wallet invoices created & paid while trigger down" { + btc_wallet_name="alice.btc_wallet_id" + + # Stop trigger + # stop_trigger + + # Generate invoice + variables=$( + jq -n \ + --arg wallet_id "$(read_value $btc_wallet_name)" \ + '{input: {walletId: $wallet_id}}' + ) + exec_graphql "alice" 'ln-no-amount-invoice-create' "$variables" + invoice="$(graphql_output '.data.lnNoAmountInvoiceCreate.invoice')" + + payment_request="$(echo $invoice | jq -r '.paymentRequest')" + [[ "${payment_request}" != "null" ]] || exit 1 + payment_hash="$(echo $invoice | jq -r '.paymentHash')" + [[ "${payment_hash}" != "null" ]] || exit 1 + + # Pay invoice + lnd_outside_cli payinvoice -f \ + --pay_req "$payment_request" \ + --amt "$btc_amount" \ + & + + # Start trigger + # start_trigger + + # Check for settled + retry 15 1 check_for_ln_initiated_settled "alice" "$payment_hash" +} + +@test "ln-receive: settles usd-wallet invoices created & paid while trigger down" { + usd_wallet_name="alice.usd_wallet_id" + + # Stop trigger + # stop_trigger + + # Generate invoice + variables=$( + jq -n \ + --arg wallet_id "$(read_value $usd_wallet_name)" \ + '{input: {walletId: $wallet_id}}' + ) + exec_graphql "alice" 'ln-no-amount-invoice-create' "$variables" + invoice="$(graphql_output '.data.lnNoAmountInvoiceCreate.invoice')" + + payment_request="$(echo $invoice | jq -r '.paymentRequest')" + [[ "${payment_request}" != "null" ]] || exit 1 + payment_hash="$(echo $invoice | jq -r '.paymentHash')" + [[ "${payment_hash}" != "null" ]] || exit 1 + + # Pay invoice + lnd_outside_cli payinvoice -f \ + --pay_req "$payment_request" \ + --amt "$btc_amount" \ + & + + # Start trigger + # start_trigger + + # Check for settled + retry 15 1 check_for_ln_initiated_settled "alice" "$payment_hash" +} diff --git a/bats/gql/account-details.gql b/bats/gql/account-details.gql new file mode 100644 index 0000000000..adc71fd240 --- /dev/null +++ b/bats/gql/account-details.gql @@ -0,0 +1,8 @@ +query me { + me { + defaultAccount { + id + level + } + } +} diff --git a/bats/gql/invoice-for-wallet-by-payment-hash.gql b/bats/gql/invoice-for-wallet-by-payment-hash.gql new file mode 100644 index 0000000000..147bb65714 --- /dev/null +++ b/bats/gql/invoice-for-wallet-by-payment-hash.gql @@ -0,0 +1,17 @@ +query me($walletId: WalletId!, $paymentHash: PaymentHash!) { + me { + defaultAccount { + id + walletById(walletId: $walletId) { + id + invoiceByPaymentHash(paymentHash: $paymentHash) { + paymentHash + paymentStatus + ... on LnInvoice { + satoshis + } + } + } + } + } +} diff --git a/bats/gql/ln-usd-invoice-create.gql b/bats/gql/ln-usd-invoice-create.gql new file mode 100644 index 0000000000..270e9ef009 --- /dev/null +++ b/bats/gql/ln-usd-invoice-create.gql @@ -0,0 +1,11 @@ +mutation lnUsdInvoiceCreate($input: LnUsdInvoiceCreateInput!) { + lnUsdInvoiceCreate(input: $input) { + invoice { + paymentRequest + paymentHash + } + errors { + message + } + } +} diff --git a/bats/gql/my-updates-sub.gql b/bats/gql/my-updates-sub.gql new file mode 100644 index 0000000000..94297df873 --- /dev/null +++ b/bats/gql/my-updates-sub.gql @@ -0,0 +1,57 @@ +subscription myUpdates { + myUpdates { + errors { + message + } + me { + id + defaultAccount { + id + wallets { + id + walletCurrency + balance + } + } + } + update { + type: __typename + ... on Price { + base + offset + currencyUnit + formattedAmount + } + ... on RealtimePrice { + id + timestamp + denominatorCurrency + btcSatPrice { + base + offset + currencyUnit + } + usdCentPrice { + base + offset + currencyUnit + } + } + ... on LnUpdate { + paymentHash + status + } + ... on OnChainUpdate { + txNotificationType + txHash + amount + usdPerSat + } + ... on IntraLedgerUpdate { + txNotificationType + amount + usdPerSat + } + } + } +} diff --git a/bats/gql/transaction-for-wallet-by-id.gql b/bats/gql/transaction-for-wallet-by-id.gql new file mode 100644 index 0000000000..cc5c946f05 --- /dev/null +++ b/bats/gql/transaction-for-wallet-by-id.gql @@ -0,0 +1,54 @@ +query transactionForWalletById($walletId: WalletId!, $transactionId: ID!) { + me { + defaultAccount { + id + displayCurrency + walletById(walletId: $walletId) { + transactionById(transactionId: $transactionId) { + __typename + id + status + direction + memo + createdAt + settlementAmount + settlementFee + settlementDisplayAmount + settlementDisplayFee + settlementDisplayCurrency + settlementCurrency + settlementPrice { + base + offset + } + initiationVia { + __typename + ... on InitiationViaIntraLedger { + counterPartyWalletId + counterPartyUsername + } + ... on InitiationViaLn { + paymentHash + } + ... on InitiationViaOnChain { + address + } + } + settlementVia { + __typename + ... on SettlementViaIntraLedger { + counterPartyWalletId + counterPartyUsername + } + ... on SettlementViaLn { + preImage + } + ... on SettlementViaOnChain { + transactionHash + } + } + } + } + } + } +} diff --git a/bats/gql/transactions-for-wallet-by-payment-hash.gql b/bats/gql/transactions-for-wallet-by-payment-hash.gql new file mode 100644 index 0000000000..515d08232f --- /dev/null +++ b/bats/gql/transactions-for-wallet-by-payment-hash.gql @@ -0,0 +1,57 @@ +query transactionsForWalletByPaymentHash( + $walletId: WalletId! + $paymentHash: PaymentHash! +) { + me { + defaultAccount { + displayCurrency + walletById(walletId: $walletId) { + id + transactionsByPaymentHash(paymentHash: $paymentHash) { + __typename + id + status + direction + memo + createdAt + settlementAmount + settlementFee + settlementDisplayAmount + settlementDisplayFee + settlementDisplayCurrency + settlementCurrency + settlementPrice { + base + offset + } + initiationVia { + __typename + ... on InitiationViaIntraLedger { + counterPartyWalletId + counterPartyUsername + } + ... on InitiationViaLn { + paymentHash + } + ... on InitiationViaOnChain { + address + } + } + settlementVia { + __typename + ... on SettlementViaIntraLedger { + counterPartyWalletId + counterPartyUsername + } + ... on SettlementViaLn { + preImage + } + ... on SettlementViaOnChain { + transactionHash + } + } + } + } + } + } +} diff --git a/bats/helpers/callback.bash b/bats/helpers/callback.bash new file mode 100644 index 0000000000..86b7c347db --- /dev/null +++ b/bats/helpers/callback.bash @@ -0,0 +1,31 @@ +CURRENT_FILE=${BASH_SOURCE:-bats/helpers/.} +source "$(dirname "$CURRENT_FILE")/_common.bash" + +export CALLBACK_PID_FILE="${BATS_ROOT_DIR}/.gql_subscriber_pid" +export CALLBACK_LOG_FILE="${BATS_ROOT_DIR}/.e2e-callback.log" + +add_callback() { + local token_name=$1 + + local variables=$( + jq -n \ + --arg url "$SVIX_CALLBACK_URL" \ + '{input: {url: $url}}' + ) + exec_graphql "$token_name" 'callback-endpoint-add' "$variables" +} + +start_callback() { + stop_callback > /dev/null 2>&1 || true + rm -f "$CALLBACK_LOG_FILE" "$CALLBACK_PID_FILE" || true + + background \ + buck2 run //bats/helpers/callback:run + > "${CALLBACK_LOG_FILE}" + echo $! > "$CALLBACK_PID_FILE" +} + +stop_callback() { + [[ -f "$CALLBACK_PID_FILE" ]] && kill $(cat $CALLBACK_PID_FILE) > /dev/null || true +} + diff --git a/bats/helpers/callback/BUCK b/bats/helpers/callback/BUCK new file mode 100644 index 0000000000..3b3edbff06 --- /dev/null +++ b/bats/helpers/callback/BUCK @@ -0,0 +1,9 @@ +load( + "@toolchains//workspace-pnpm:macros.bzl", + "dev_pnpm_task_binary", +) + +dev_pnpm_task_binary( + name = "run", + command = "callback", +) diff --git a/bats/helpers/callback/package.json b/bats/helpers/callback/package.json new file mode 100644 index 0000000000..0daf3d7ded --- /dev/null +++ b/bats/helpers/callback/package.json @@ -0,0 +1,10 @@ +{ + "name": "callback", + "scripts": { + "callback": "tsx src/callback.ts" + }, + "devDependencies": { + "@types/node": "^20.8.7", + "tsx": "^4.2.0" + } +} diff --git a/bats/helpers/callback/pnpm-lock.yaml b/bats/helpers/callback/pnpm-lock.yaml new file mode 100644 index 0000000000..931aa202ec --- /dev/null +++ b/bats/helpers/callback/pnpm-lock.yaml @@ -0,0 +1,285 @@ +lockfileVersion: '6.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + devDependencies: + '@types/node': + specifier: ^20.8.7 + version: 20.10.0 + tsx: + specifier: ^4.2.0 + version: 4.6.0 + +packages: + + /@esbuild/android-arm64@0.18.20: + resolution: {integrity: sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/android-arm@0.18.20: + resolution: {integrity: sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/android-x64@0.18.20: + resolution: {integrity: sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/darwin-arm64@0.18.20: + resolution: {integrity: sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@esbuild/darwin-x64@0.18.20: + resolution: {integrity: sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@esbuild/freebsd-arm64@0.18.20: + resolution: {integrity: sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/freebsd-x64@0.18.20: + resolution: {integrity: sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-arm64@0.18.20: + resolution: {integrity: sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-arm@0.18.20: + resolution: {integrity: sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-ia32@0.18.20: + resolution: {integrity: sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-loong64@0.18.20: + resolution: {integrity: sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-mips64el@0.18.20: + resolution: {integrity: sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-ppc64@0.18.20: + resolution: {integrity: sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-riscv64@0.18.20: + resolution: {integrity: sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-s390x@0.18.20: + resolution: {integrity: sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-x64@0.18.20: + resolution: {integrity: sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/netbsd-x64@0.18.20: + resolution: {integrity: sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/openbsd-x64@0.18.20: + resolution: {integrity: sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/sunos-x64@0.18.20: + resolution: {integrity: sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-arm64@0.18.20: + resolution: {integrity: sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-ia32@0.18.20: + resolution: {integrity: sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-x64@0.18.20: + resolution: {integrity: sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@types/node@20.10.0: + resolution: {integrity: sha512-D0WfRmU9TQ8I9PFx9Yc+EBHw+vSpIub4IDvQivcp26PtPrdMGAq5SDcpXEo/epqa/DXotVpekHiLNTg3iaKXBQ==} + dependencies: + undici-types: 5.26.5 + dev: true + + /esbuild@0.18.20: + resolution: {integrity: sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==} + engines: {node: '>=12'} + hasBin: true + requiresBuild: true + optionalDependencies: + '@esbuild/android-arm': 0.18.20 + '@esbuild/android-arm64': 0.18.20 + '@esbuild/android-x64': 0.18.20 + '@esbuild/darwin-arm64': 0.18.20 + '@esbuild/darwin-x64': 0.18.20 + '@esbuild/freebsd-arm64': 0.18.20 + '@esbuild/freebsd-x64': 0.18.20 + '@esbuild/linux-arm': 0.18.20 + '@esbuild/linux-arm64': 0.18.20 + '@esbuild/linux-ia32': 0.18.20 + '@esbuild/linux-loong64': 0.18.20 + '@esbuild/linux-mips64el': 0.18.20 + '@esbuild/linux-ppc64': 0.18.20 + '@esbuild/linux-riscv64': 0.18.20 + '@esbuild/linux-s390x': 0.18.20 + '@esbuild/linux-x64': 0.18.20 + '@esbuild/netbsd-x64': 0.18.20 + '@esbuild/openbsd-x64': 0.18.20 + '@esbuild/sunos-x64': 0.18.20 + '@esbuild/win32-arm64': 0.18.20 + '@esbuild/win32-ia32': 0.18.20 + '@esbuild/win32-x64': 0.18.20 + dev: true + + /fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /get-tsconfig@4.7.2: + resolution: {integrity: sha512-wuMsz4leaj5hbGgg4IvDU0bqJagpftG5l5cXIAvo8uZrqn0NJqwtfupTN00VnkQJPcIRrxYrm1Ue24btpCha2A==} + dependencies: + resolve-pkg-maps: 1.0.0 + dev: true + + /resolve-pkg-maps@1.0.0: + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + dev: true + + /tsx@4.6.0: + resolution: {integrity: sha512-HLHaDQ78mly4Pd5co6tWQOiNVYoYYAPUcwSSZK4bcs3zSEsg+/67LS/ReHook0E7DKPfe1J5jc0ocIhUrnaR4w==} + engines: {node: '>=18.0.0'} + hasBin: true + dependencies: + esbuild: 0.18.20 + get-tsconfig: 4.7.2 + optionalDependencies: + fsevents: 2.3.3 + dev: true + + /undici-types@5.26.5: + resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} + dev: true diff --git a/bats/helpers/callback/pnpm-workspace.yaml b/bats/helpers/callback/pnpm-workspace.yaml new file mode 100644 index 0000000000..ed97d539c0 --- /dev/null +++ b/bats/helpers/callback/pnpm-workspace.yaml @@ -0,0 +1 @@ +--- diff --git a/core/api/test/bats/helpers/callback.js b/bats/helpers/callback/src/callback.ts similarity index 92% rename from core/api/test/bats/helpers/callback.js rename to bats/helpers/callback/src/callback.ts index 2ed7673d68..5179aad96c 100644 --- a/core/api/test/bats/helpers/callback.js +++ b/bats/helpers/callback/src/callback.ts @@ -1,4 +1,4 @@ -const http = require("http") +import http from "http" const PORT = 8080 diff --git a/bats/helpers/ln.bash b/bats/helpers/ln.bash index ff57a08814..82a3015e23 100644 --- a/bats/helpers/ln.bash +++ b/bats/helpers/ln.bash @@ -1,6 +1,7 @@ CURRENT_FILE=${BASH_SOURCE:-bats/helpers/.} source "$(dirname "$CURRENT_FILE")/_common.bash" source "$(dirname "$CURRENT_FILE")/cli.bash" +source "$(dirname "$CURRENT_FILE")/subscriber.bash" fund_user_lightning() { local token_name=$1 @@ -253,3 +254,20 @@ rebalance_channel() { run_with_lnd "$lnd_partner_cli_value" sendpayment --dest=$local_pubkey --amt="$(abs $diff)" --keysend fi } + +check_for_ln_update() { + payment_hash=$1 + + retry 10 1 \ + grep "Data.*LnUpdate.*$payment_hash" "$SUBSCRIBER_LOG_FILE" \ + | awk '{print $2}' \ + | jq -r --arg hash "$payment_hash" 'select(.data.myUpdates.update.paymentHash == $hash)' + + paid_status=$( \ + grep 'Data.*LnUpdate' "$SUBSCRIBER_LOG_FILE" \ + | awk '{print $2}' \ + | jq -r --arg hash "$payment_hash" 'select(.data.myUpdates.update.paymentHash == $hash) .data.myUpdates.update.status' + ) + + [[ "$paid_status" == "PAID" ]] || exit 1 +} diff --git a/core/api/test/bats/helpers/ln.bash b/core/api/test/bats/helpers/ln.bash index 27a46870f3..2232f75f73 100644 --- a/core/api/test/bats/helpers/ln.bash +++ b/core/api/test/bats/helpers/ln.bash @@ -334,3 +334,23 @@ num_txns_for_hash() { --arg payment_hash "$payment_hash" \ "$jq_query" } + +lnd_outside_rest() { + local route=$1 + local endpoint="https://localhost:8080/$route" + + local data=$2 + + local macaroon_hex=$( + docker exec "${COMPOSE_PROJECT_NAME}-lnd-outside-1-1" \ + xxd -p -c 10000 /root/.lnd/admin.macaroon + ) + + docker exec "${COMPOSE_PROJECT_NAME}-lnd-outside-1-1" \ + curl -s \ + --cacert /root/.lnd/tls.cert \ + -H "Grpc-Metadata-macaroon: $macaroon_hex" \ + ${data:+ -X POST -d $data} \ + "$endpoint" \ + > "$LNDS_REST_LOG" +}