Offer LNURL QR code for download on Lightning info page #135

Merged
raucao merged 5 commits from feature/lightning_donation_qr_codes into master 2023-06-20 16:44:59 +00:00
5 changed files with 89 additions and 12 deletions

View File

@ -57,6 +57,7 @@ gem "sentry-rails"
# Services # Services
gem 'discourse_api' gem 'discourse_api'
gem "lnurl"
gem 'nostr', git: 'https://gitea.kosmos.org/kosmos/nostr-gem.git', branch: 'feature/ruby_2.7_compat' gem 'nostr', git: 'https://gitea.kosmos.org/kosmos/nostr-gem.git', branch: 'feature/ruby_2.7_compat'
group :development, :test do group :development, :test do

View File

@ -206,6 +206,8 @@ GEM
listen (3.8.0) listen (3.8.0)
rb-fsevent (~> 0.10, >= 0.10.3) rb-fsevent (~> 0.10, >= 0.10.3)
rb-inotify (~> 0.9, >= 0.9.10) rb-inotify (~> 0.9, >= 0.9.10)
lnurl (1.0.1)
bech32 (~> 1.1)
lockbox (1.2.0) lockbox (1.2.0)
loofah (2.21.3) loofah (2.21.3)
crass (~> 1.0.2) crass (~> 1.0.2)
@ -430,6 +432,7 @@ DEPENDENCIES
letter_opener letter_opener
letter_opener_web letter_opener_web
listen (~> 3.2) listen (~> 3.2)
lnurl
lockbox lockbox
net-ldap net-ldap
nostr! nostr!

View File

@ -1,4 +1,5 @@
require "rqrcode" require "rqrcode"
require "lnurl"
class Services::LightningController < ApplicationController class Services::LightningController < ApplicationController
before_action :authenticate_user! before_action :authenticate_user!
@ -8,9 +9,56 @@ class Services::LightningController < ApplicationController
def index def index
@wallet_url = "lndhub://#{current_user.ln_account}:#{current_user.ln_password}@#{ENV['LNDHUB_PUBLIC_URL']}" @wallet_url = "lndhub://#{current_user.ln_account}:#{current_user.ln_password}@#{ENV['LNDHUB_PUBLIC_URL']}"
initialize_lndhub_qr_code
end
qrcode = RQRCode::QRCode.new(@wallet_url) def transactions
@svg = qrcode.as_svg( @transactions = fetch_transactions
end
def qr_lnurlp
lnurlp_url = "https://kosmos.org/.well-known/lnurlp/#{current_user.cn}"
lnurlp_bech32 = Lnurl.new(lnurlp_url).to_bech32
qr_code = RQRCode::QRCode.new("lightning:" + lnurlp_bech32)
respond_to do |format|
raucao marked this conversation as resolved Outdated
Outdated
Review

why don't you use respond_to here?

why don't you use `respond_to` here?

Good question. Should've done so to begin with. Refactored and pushed.

Good question. Should've done so to begin with. Refactored and pushed.
Outdated
Review

I'd move the logic out of this block and only have

lnurlp_url = "https://kosmos.org/.well-known/lnurlp/#{current_user.cn}"
lnurlp_bech32 = Lnurl.new(lnurlp_url).to_bech32
qr_code = RQRCode::QRCode.new("lightning:" + lnurlp_bech32)
      
respond_to do |format|
  format.svg ...
  format.png ...
end
I'd move the logic out of this block and only have ``` lnurlp_url = "https://kosmos.org/.well-known/lnurlp/#{current_user.cn}" lnurlp_bech32 = Lnurl.new(lnurlp_url).to_bech32 qr_code = RQRCode::QRCode.new("lightning:" + lnurlp_bech32) respond_to do |format| format.svg ... format.png ... end ```
format.svg do
qr_svg = qr_code.as_svg(
color: "000",
shape_rendering: "crispEdges",
module_size: 6,
standalone: true,
use_path: true,
svg_attributes: {
class: 'inline-block'
}
)
send_data(
qr_svg,
filename: "bitcoin-lightning-#{current_user.address}.svg",
raucao marked this conversation as resolved Outdated
Outdated
Review

does this need a disposition attribute? 🤔

does this need a `disposition` attribute? 🤔

Disposition should default to attachment, i.e. download. It works exactly as intended in FF, maybe you could test manually in another browser?

Disposition should default to attachment, i.e. download. It works exactly as intended in FF, maybe you could test manually in another browser?
type: "image/svg+xml"
)
end
format.png do
qr_png = qr_code.as_png(
fill: "white",
color: "black",
size: 1024,
)
send_data(
qr_png,
filename: "bitcoin-lightning-#{current_user.address}.png",
type: "image/png"
)
end
end
end
private
def initialize_lndhub_qr_code
qr_code = RQRCode::QRCode.new(@wallet_url)
@lndhub_qr_svg = qr_code.as_svg(
color: "000", color: "000",
shape_rendering: "crispEdges", shape_rendering: "crispEdges",
module_size: 6, module_size: 6,
@ -22,12 +70,6 @@ class Services::LightningController < ApplicationController
) )
end end
def transactions
@transactions = fetch_transactions
end
private
def authenticate_with_lndhub(options={}) def authenticate_with_lndhub(options={})
if session[:ln_auth_token].present? && !options[:force_reauth] if session[:ln_auth_token].present? && !options[:force_reauth]
@ln_auth_token = session[:ln_auth_token] @ln_auth_token = session[:ln_auth_token]

View File

@ -7,13 +7,25 @@
<section> <section>
<h3>Lightning Address</h3> <h3>Lightning Address</h3>
<p> <p class="mb-6">
Your Kosmos user address is also a Your Kosmos user address is also a
<a class="ks-text-link" href="https://lightningaddress.com/" target="_blank">Lightning Address</a>! <a class="ks-text-link" href="https://lightningaddress.com/" target="_blank">Lightning Address</a>!
The easiest way to receive sats is by just giving out your address: The easiest way to receive sats is by just giving out your address:
</p> </p>
<p> <p data-controller="clipboard" class="flex gap-1 sm:w-2/5">
<strong><%= current_user.address %></strong> <input type="text" id="user_address" class="grow"
value=<%= current_user.address %> disabled="disabled"
data-clipboard-target="source" />
<button id="copy-user-address" class="btn-md btn-icon btn-blue shrink-0"
data-clipboard-target="trigger" data-action="clipboard#copy"
title="Copy to clipboard">
<span class="content-initial">
<%= render partial: "icons/copy", locals: { custom_class: "text-white h-4 w-4 inline" } %>
</span>
<span class="content-active hidden">
<%= render partial: "icons/check", locals: { custom_class: "text-white h-4 w-4 inline" } %>
</span>
</button>
</p> </p>
</section> </section>
@ -39,7 +51,7 @@
<button id="hide-setup-code" class="hidden btn-md btn-blue w-full sm:w-auto">Hide setup QR code</button> <button id="hide-setup-code" class="hidden btn-md btn-blue w-full sm:w-auto">Hide setup QR code</button>
</p> </p>
<p id="setup-code" class="hidden my-10 w-full text-center"> <p id="setup-code" class="hidden my-10 w-full text-center">
<%= raw @svg %> <%= raw @lndhub_qr_svg %>
</p> </p>
</section> </section>
@ -88,6 +100,24 @@
</p> </p>
</div> </div>
</section> </section>
<section class="mb-12">
<h3>QR Code for Donations/Tips</h3>
<p>
You can print out or publish a QR code for people to scan with their
wallet apps, so they can send you sats without a direct personal
interaction (for example at a concert, or on your website).
</p>
<p class="my-6 text-center md:text-left">
<%= link_to "Download SVG file",
qr_lnurlp_services_lightning_index_path(format: "svg"),
class: "btn-md btn-blue w-full sm:w-auto"%>
<span class="mx-2 my-2 md:my-0 block md:inline">or</span>
<%= link_to "Download PNG file",
qr_lnurlp_services_lightning_index_path(format: "png"),
class: "btn-md btn-blue w-full sm:w-auto"%>
</p>
</section>
<% end %> <% end %>
<script type="text/javascript"> <script type="text/javascript">

View File

@ -24,6 +24,7 @@ Rails.application.routes.draw do
resources :lightning, only: [:index] do resources :lightning, only: [:index] do
collection do collection do
get 'transactions' get 'transactions'
get 'qr_lnurlp'
end end
end end
end end