From f2287c11860b5339a186dcf66af3beb00ca1d6c6 Mon Sep 17 00:00:00 2001 From: Sebastian Kippe Date: Mon, 23 May 2022 18:49:05 +0200 Subject: [PATCH 1/6] Remove separate development credentials files --- config/credentials/development.key | 1 - config/credentials/development.yml.enc | 1 - 2 files changed, 2 deletions(-) delete mode 100644 config/credentials/development.key delete mode 100644 config/credentials/development.yml.enc diff --git a/config/credentials/development.key b/config/credentials/development.key deleted file mode 100644 index ce648c5..0000000 --- a/config/credentials/development.key +++ /dev/null @@ -1 +0,0 @@ -2a8a17892dd9f41ea50c61310c83240b \ No newline at end of file diff --git a/config/credentials/development.yml.enc b/config/credentials/development.yml.enc deleted file mode 100644 index d2f41cb..0000000 --- a/config/credentials/development.yml.enc +++ /dev/null @@ -1 +0,0 @@ -zdpQvlbfqXzaExLzw2LGZkXj97HH42jWZFSTlINpf/HlFr6NubPxLkVxeGsittJj5rm8yL+V21zPxp30Z7Q7R45qyCKFtevtVeqb+u1nZ/FsVfkwb/7wDW9scurgXw==--SB6C0aaNf8qPdteG--9hP+6tpsMnyiAVVvAIq+7w== \ No newline at end of file From 9b3386de304e13e0c699a2f2d9c0dda7993e7b0b Mon Sep 17 00:00:00 2001 From: Sebastian Kippe Date: Mon, 23 May 2022 18:49:37 +0200 Subject: [PATCH 2/6] Update credentials --- config/credentials.yml.enc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/credentials.yml.enc b/config/credentials.yml.enc index a49b81a..c3dc2e3 100644 --- a/config/credentials.yml.enc +++ b/config/credentials.yml.enc @@ -1 +1 @@ -PRI1laGy6XiLpsII0ixFOTCpzzDbrRpIQ7GJ2flvA+UEEiPVQQ4e/pt6ZjumaZ/geTBHCRZklLtS1u6HjucVKHGSR4K/lE1q7u6nfi/wAvwGQdCTJeKf8PetdlsiVZg2OW4Wi2YF7qtb1ipGS/uRlOeLP8JOwp5BNVS1J6tvNX4T5gA7rrB4Cvtfwp1dwLWODHiXbeZK7SN2j7V3NPGZl0LbNg2jquC4DzQOBhMOlwu1IAgOAcqKbHh9tDabpVOcOD5pNSaVaoBO01P8ObbX8x0S0Ug7BPkM5nnyJTQdNH7LHKvtNmrUEk7+fd+VZR6WqEp6SFBoAA7XxvOLy9dIOqvXbAYnrNZX7iI4IpgZWRNIQ7G1qSBjpyPLKC7+nSPmvd4IcgCHVUBdYp0+yYDxLzwuuhPVtyAY4JAIdZY1mhYxx7BzGNiMc3p8AlMS6hPeO9lVQZykViBGnTjR+iah9OQYAihX9FYywtBkNvMXLiYqsVZmv6em9Uk/ivKSIsaFwNwrelCI5H4Q/+/hKFJ1JaMjbYheXCJgcGgfhiC+fIHig/8y8rXd9lWGa1T+PrpA8akcq/K8I6gbxYxpLWcy5Vnz/SyaMurLPVfCq4cD/JfpLSfy0HophaiycZ7D6dr43rnHsPfrt6kveDOgWUK9d7CqHxsWdXbCpJeBoh8/1usIsGsmyhfwHq0dEpRx78bR2EJeM4LOAuQgf69/5rFJydIbXq76l1BftTls1Pgh--OI8c/RQGQ30wT1Ff--M/ltnmdl+FRdlNliTb79lg== \ No newline at end of file +oDf4FcihlyfHQuf9SUwfr+UVA0kXoECtHV3vEwtBp2TktCWkWz7SPbSZ2cLT0+EknOKhuI9xutrs311YDU2EzqZba4fZ0+a6/ohVH4jUbk1XfiHZWBp4zh+9TZ5m5Tp2RxcXpdcWPY38mP4zHWFzobTOR/brLjuemozvh8MiBSPY4NN5NR6rbFo87auK6fvYO8ik/1Qwf6pQMoVDjcTh2983po1RU/gSevUmaYsmTTHcQ5T9O9wMIBc101iZyKhkAZG46a6eNYok8yqRm18AHWr+De2j7LlBaqYSz/BZA385RWhhqoeONArwyo3Az30Bv74VttUSJAPurkRg2wDF9t8A+cvf8CeYkZ6u398JLSJbZZ6YdQS5T4IcrnONRXtp3d/m+yw+XEzpluK3MvFbV02AhZk/xzkGK6xonhaTSh1ek9hXoYrUTBzu8HBzXwKjJMnvrAodldu++/rMwLsgVmFHqXC3dydVogatLev8z6ziuGkmeMAR1d9kzGBHM3FWgsWLD7j0Ug7MTMyNWioI3r6J2QTnxkyJGh3pKBlq8Fb/Q0ypERxOfSZVQQh2gB79RMEDIemdCmN5mCU3ojsxqAAip4v9C1BZMWPtom1sHLYQSd9Bh6i0nncrNEtZXcxe5Z8JCWQolHvvfoIF2rfJh2oXYLxNx5n/1fzaoSqBdLBgvsAMA0ZWfV1wa/5V/DCa9vaJjumzHYKcfCCYbVz9PjN9OUSfwrE3nWZu8Y0awsNgmeRQwI10j2+oYYSBp040I05Vj5FM7nCgHLpdupctwaH2/VlIq83OVI6VlbzxYEay7+R5ANmpiJ+vC466DzLv8LAeFOqh/XeNeOITUm9EzhGSgf98yuDc7vsi3gmc2g7atgQ3gpSje6vEfhigm3ukydaGfA==--IYQBMD+Tar1g+srm--01E5mujYFWvcpT8Qd9HxiA== \ No newline at end of file From e1ff5c479e2dff70105a0de1f91225bf39a56104 Mon Sep 17 00:00:00 2001 From: Sebastian Kippe Date: Mon, 23 May 2022 18:49:55 +0200 Subject: [PATCH 3/6] Initial BTCPay integration --- .env.example | 1 + .env.production | 1 + app/services/btc_pay.rb | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 34 insertions(+) create mode 100644 app/services/btc_pay.rb diff --git a/.env.example b/.env.example index ed6e513..99cc4ad 100644 --- a/.env.example +++ b/.env.example @@ -1,3 +1,4 @@ EJABBERD_API_URL='https://xmpp.kosmos.org/api' +BTCPAY_API_URL='http://localhost:23001' LNDHUB_API_URL='http://localhost:3023' LNDHUB_PUBLIC_URL='https://lndhub.kosmos.org' diff --git a/.env.production b/.env.production index e9bd695..8b61513 100644 --- a/.env.production +++ b/.env.production @@ -1,3 +1,4 @@ EJABBERD_API_URL='https://xmpp.kosmos.org:5443/api' +BTCPAY_API_URL='http://10.1.1.163:23001' LNDHUB_API_URL='http://10.1.1.163:3023' LNDHUB_PUBLIC_URL='https://lndhub.kosmos.org' diff --git a/app/services/btc_pay.rb b/app/services/btc_pay.rb new file mode 100644 index 0000000..05c8d82 --- /dev/null +++ b/app/services/btc_pay.rb @@ -0,0 +1,32 @@ +# +# API Docs: https://docs.btcpayserver.org/API/Greenfield/v1/ +# +class BtcPay + def initialize + @base_url = "#{ENV["BTCPAY_API_URL"]}/api/v1" + @store_id = Rails.application.credentials.btcpay[:store_id] + @auth_token = Rails.application.credentials.btcpay[:auth_token] + end + + def onchain_wallet_balance + wallet_info = get "stores/#{@store_id}/payment-methods/onchain/BTC/wallet" + + { + balance: wallet_info["balance"].to_f, + unconfirmed_balance: wallet_info["unconfirmedBalance"].to_f, + confirmed_balance: wallet_info["confirmedBalance"].to_f + } + end + + private + + def get(endpoint) + res = Faraday.get("#{@base_url}/#{endpoint}", {}, { + "Content-Type" => "application/json", + "Accept" => "application/json", + "Authorization" => "token #{@auth_token}" + }) + + JSON.parse(res.body) + end +end From caea2d01213892c086f2a5e86ca7f71164145b0a Mon Sep 17 00:00:00 2001 From: Sebastian Kippe Date: Mon, 23 May 2022 22:47:08 +0200 Subject: [PATCH 4/6] Add kredits API with wallet balance endpoint --- .env.test | 1 + app/controllers/api/base_controller.rb | 5 +++ app/controllers/api/kredits_controller.rb | 12 +++++++ app/services/btc_pay.rb | 8 ++--- config/credentials/test.yml.enc | 2 +- config/routes.rb | 4 +++ spec/requests/api/kredits_spec.rb | 43 +++++++++++++++++++++++ 7 files changed, 70 insertions(+), 5 deletions(-) create mode 100644 app/controllers/api/base_controller.rb create mode 100644 app/controllers/api/kredits_controller.rb create mode 100644 spec/requests/api/kredits_spec.rb diff --git a/.env.test b/.env.test index 4d17742..64e2fd5 100644 --- a/.env.test +++ b/.env.test @@ -1,3 +1,4 @@ EJABBERD_API_URL='http://xmpp.example.com/api' +BTCPAY_API_URL='http://btcpay.example.com' LNDHUB_API_URL='http://localhost:3023' LNDHUB_PUBLIC_URL='https://lndhub.kosmos.org' diff --git a/app/controllers/api/base_controller.rb b/app/controllers/api/base_controller.rb new file mode 100644 index 0000000..d788c58 --- /dev/null +++ b/app/controllers/api/base_controller.rb @@ -0,0 +1,5 @@ +class Api::BaseController < ApplicationController + + layout false + +end diff --git a/app/controllers/api/kredits_controller.rb b/app/controllers/api/kredits_controller.rb new file mode 100644 index 0000000..3b8768f --- /dev/null +++ b/app/controllers/api/kredits_controller.rb @@ -0,0 +1,12 @@ +class Api::KreditsController < Api::BaseController + + def onchain_btc_balance + btcpay = BtcPay.new + balance = btcpay.onchain_wallet_balance + render json: balance + rescue + render json: { error: 'Failed to fetch wallet balance' }, + status: 500 + end + +end diff --git a/app/services/btc_pay.rb b/app/services/btc_pay.rb index 05c8d82..5abcb4d 100644 --- a/app/services/btc_pay.rb +++ b/app/services/btc_pay.rb @@ -9,12 +9,12 @@ class BtcPay end def onchain_wallet_balance - wallet_info = get "stores/#{@store_id}/payment-methods/onchain/BTC/wallet" + res = get "stores/#{@store_id}/payment-methods/onchain/BTC/wallet" { - balance: wallet_info["balance"].to_f, - unconfirmed_balance: wallet_info["unconfirmedBalance"].to_f, - confirmed_balance: wallet_info["confirmedBalance"].to_f + balance: res["balance"].to_f, + unconfirmed_balance: res["unconfirmedBalance"].to_f, + confirmed_balance: res["confirmedBalance"].to_f } end diff --git a/config/credentials/test.yml.enc b/config/credentials/test.yml.enc index 416ee0e..5a1530a 100644 --- a/config/credentials/test.yml.enc +++ b/config/credentials/test.yml.enc @@ -1 +1 @@ -xgPOFd8315z7lFtTR5/nD6WDBM2M6Grt/pmkCPdaqlw0WAmFKzbiRGFsXoUQ02JNzvT1/FVtBSsAcyK1Pdr1QQztlWC+/ywaflloMBS4//D8IEXvEgCK6uff5gcf1A==--WbFrw9advCJ4mqsK--HTVHZqO0ddG1toFpY0KKgQ== \ No newline at end of file +IIjYiPSeZeMFhH8i8v8akXN4JrtGU+OsMQ8GAao/gVdesggriCBAQ8z+Vd0cmTf1SKYeT3OQDgygEekupr325P4eD9fZ+yi56EA/UMXQXMDVZAvZw7iwvKaOXpqisbWdJnomr1GXrHyR415Ce/Fxft3fgXDwMHJW2u+dDJgpE09uORnB9GXycFwHQmoIdXo=--iQ/Vcm0VcwHgUkwQ--tKHQW/45gM/s/NplqGPaxw== \ No newline at end of file diff --git a/config/routes.rb b/config/routes.rb index 8ecb38b..b0cf70e 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -25,6 +25,10 @@ Rails.application.routes.draw do get 'lnurlpay/:address', to: 'lnurlpay#index', constraints: { address: /[^\/]+/} get 'lnurlpay/:address/invoice', to: 'lnurlpay#invoice', constraints: { address: /[^\/]+/} + namespace :api do + get 'kredits/onchain_btc_balance', to: 'kredits#onchain_btc_balance' + end + namespace :admin do root to: 'dashboard#index' get 'invitations', to: 'invitations#index' diff --git a/spec/requests/api/kredits_spec.rb b/spec/requests/api/kredits_spec.rb new file mode 100644 index 0000000..0e1e464 --- /dev/null +++ b/spec/requests/api/kredits_spec.rb @@ -0,0 +1,43 @@ +require 'rails_helper' +require 'webmock/rspec' + +RSpec.describe "/api/kredits", type: :request do + + describe "GET /onchain_btc_balance" do + before do + stub_request(:get, "http://btcpay.example.com/api/v1/stores/123456/payment-methods/onchain/BTC/wallet") + .to_return(status: 200, headers: {}, body: { + balance: 0.91108606, + unconfirmedBalance: 0, + confirmedBalance: 0.91108606 + }.to_json) + end + + it "returns a formatted result for the onchain wallet balance" do + get api_kredits_onchain_btc_balance_path + + expect(response).to have_http_status(:ok) + + res = JSON.parse(response.body) + expect(res["balance"]).to eq(0.91108606) + expect(res["unconfirmed_balance"]).to eq(0) + expect(res["confirmed_balance"]).to eq(0.91108606) + end + + context "upstream request error" do + before do + stub_request(:get, "http://btcpay.example.com/api/v1/stores/123456/payment-methods/onchain/BTC/wallet") + .to_return(status: 500, headers: {}, body: "") + end + + it "returns a formatted error" do + get api_kredits_onchain_btc_balance_path + + expect(response).to have_http_status(:server_error) + + res = JSON.parse(response.body) + expect(res["error"]).not_to be_nil + end + end + end +end From 897b5bf4ea6eae285b6967ca2a4b22e39f581ab6 Mon Sep 17 00:00:00 2001 From: Sebastian Kippe Date: Mon, 23 May 2022 22:49:39 +0200 Subject: [PATCH 5/6] Specify whole API base URL in config --- .env.example | 2 +- .env.production | 2 +- .env.test | 2 +- app/services/btc_pay.rb | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.env.example b/.env.example index 99cc4ad..99df7d4 100644 --- a/.env.example +++ b/.env.example @@ -1,4 +1,4 @@ EJABBERD_API_URL='https://xmpp.kosmos.org/api' -BTCPAY_API_URL='http://localhost:23001' +BTCPAY_API_URL='http://localhost:23001/api/v1' LNDHUB_API_URL='http://localhost:3023' LNDHUB_PUBLIC_URL='https://lndhub.kosmos.org' diff --git a/.env.production b/.env.production index 8b61513..228cf57 100644 --- a/.env.production +++ b/.env.production @@ -1,4 +1,4 @@ EJABBERD_API_URL='https://xmpp.kosmos.org:5443/api' -BTCPAY_API_URL='http://10.1.1.163:23001' +BTCPAY_API_URL='http://10.1.1.163:23001/api/v1' LNDHUB_API_URL='http://10.1.1.163:3023' LNDHUB_PUBLIC_URL='https://lndhub.kosmos.org' diff --git a/.env.test b/.env.test index 64e2fd5..103f43d 100644 --- a/.env.test +++ b/.env.test @@ -1,4 +1,4 @@ EJABBERD_API_URL='http://xmpp.example.com/api' -BTCPAY_API_URL='http://btcpay.example.com' +BTCPAY_API_URL='http://btcpay.example.com/api/v1' LNDHUB_API_URL='http://localhost:3023' LNDHUB_PUBLIC_URL='https://lndhub.kosmos.org' diff --git a/app/services/btc_pay.rb b/app/services/btc_pay.rb index 5abcb4d..becd506 100644 --- a/app/services/btc_pay.rb +++ b/app/services/btc_pay.rb @@ -3,7 +3,7 @@ # class BtcPay def initialize - @base_url = "#{ENV["BTCPAY_API_URL"]}/api/v1" + @base_url = ENV["BTCPAY_API_URL"] @store_id = Rails.application.credentials.btcpay[:store_id] @auth_token = Rails.application.credentials.btcpay[:auth_token] end From 03dc6c7a9c5373c852c2e1f37a2adf5587c8b5aa Mon Sep 17 00:00:00 2001 From: Sebastian Kippe Date: Tue, 24 May 2022 13:41:27 +0200 Subject: [PATCH 6/6] Log unexpected kredits API errors --- app/controllers/api/kredits_controller.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/controllers/api/kredits_controller.rb b/app/controllers/api/kredits_controller.rb index 3b8768f..e54993d 100644 --- a/app/controllers/api/kredits_controller.rb +++ b/app/controllers/api/kredits_controller.rb @@ -4,7 +4,8 @@ class Api::KreditsController < Api::BaseController btcpay = BtcPay.new balance = btcpay.onchain_wallet_balance render json: balance - rescue + rescue => error + Rails.logger.warn "Failed to fetch kredits BTC wallet balance: #{error.message}" render json: { error: 'Failed to fetch wallet balance' }, status: 500 end