Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

webserver/ui: Generate QR codes for deposit address #1483

Merged
merged 2 commits into from
Feb 22, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 56 additions & 0 deletions client/webserver/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,14 @@ import (
"strings"
"time"

"image/color"

"decred.org/dcrdex/client/asset"
"decred.org/dcrdex/client/core"
"decred.org/dcrdex/dex"
"decred.org/dcrdex/dex/encode"
"decred.org/dcrdex/dex/order"
qrcode "github.com/skip2/go-qrcode"
)

const (
Expand Down Expand Up @@ -198,6 +201,59 @@ func (s *WebServer) handleWalletLogFile(w http.ResponseWriter, r *http.Request)
}
}

// handleGenerateQRCode is the handler for the '/generateqrcode' page request
func (s *WebServer) handleGenerateQRCode(w http.ResponseWriter, r *http.Request) {
err := r.ParseForm()
if err != nil {
log.Errorf("error parsing form for generate qr code: %v", err)
http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
return
}

address := r.Form["address"]
if len(address) != 1 || len(address[0]) == 0 {
log.Error("form for generating qr code does not contain address")
http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
return
}

var darkMode bool
dark := r.Form["dark"]
if len(dark) >= 1 && len(dark[0]) > 0 {
darkMode, _ = strconv.ParseBool(dark[0])
}

qr, err := qrcode.New(address[0], qrcode.Medium)
if err != nil {
log.Error("error generating qr code: %v", err)
http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
return
}

if darkMode {
qr.BackgroundColor = color.Black
qr.ForegroundColor = color.White
} else {
qr.BackgroundColor = color.White
qr.ForegroundColor = color.Black
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have tried this with two scanners, and one is fine, but one cannot pick up the white qr code on black background. Can they always be white background with black foreground?

Copy link
Contributor

@ukane-philemon ukane-philemon Feb 22, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, I tried both qr code on two scanners and they work well. Maybe scanner related issue?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They both work for me too. If it turns out to be a more widespread issue, we can have the light mode version always displayed by using a white/light patch behind it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They both work fine for me too. In the QR code library's docs there was an example with a black background and white foreground so I thought it would be fine, but now I'm doing some research and it's recommended that the foreground should be darker than the background.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Screen Shot 2022-02-22 at 9 53 50 AM

Actually it might even look better.

png, err := qr.PNG(200)
if err != nil {
log.Error("error generating png: %v", err)
http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
return
}

w.Header().Set("Content-Type", "image/png")
w.Header().Set("Content-Length", strconv.Itoa(len(png)))
w.WriteHeader(http.StatusOK)

_, err = w.Write(png)
if err != nil {
log.Errorf("error writing qr code image: %v", err)
}
}

// handleSettings is the handler for the '/settings' page request.
func (s *WebServer) handleSettings(w http.ResponseWriter, r *http.Request) {
data := &struct {
Expand Down
5 changes: 4 additions & 1 deletion client/webserver/site/src/html/wallets.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,10 @@
<span id="depositName"></span>
<div class="form-closer hoverbg"><span class="ico-cross"></span></div>
</div>
<div class="mono d-inline bg0 p-2 fs15" id="depositAddress"></div>
<div class="d-inline">
<img class="mb-3" id="qrcode" />
<div class="mono bg0 p-2 fs15" id="depositAddress"></div>
</div>
<div class="my-3">
<button id="newDepAddrBttn" type="button" class=" px-2 justify-content-center fs15 bg2 selected">[[[New Deposit Address]]]</button>
</div>
Expand Down
2 changes: 2 additions & 0 deletions client/webserver/site/src/js/wallets.js
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,7 @@ export default class WalletsPage extends BasePage {
await this.hideBox()
page.depositName.textContent = asset.info.name
page.depositAddress.textContent = wallet.address
page.qrcode.src = `/generateqrcode?address=${wallet.address}&dark=${State.isDark()}`
if ((wallet.traits & traitNewAddresser) !== 0) Doc.show(page.newDepAddrBttn)
else Doc.hide(page.newDepAddrBttn)
this.animation = this.showBox(box)
Expand All @@ -385,6 +386,7 @@ export default class WalletsPage extends BasePage {
return
}
page.depositAddress.textContent = res.address
page.qrcode.src = `/generateqrcode?address=${res.address}&dark=${State.isDark()}`
}

/* Show the form to withdraw funds. */
Expand Down
5 changes: 4 additions & 1 deletion client/webserver/site/src/localized_html/en-US/wallets.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,10 @@
<span id="depositName"></span>
<div class="form-closer hoverbg"><span class="ico-cross"></span></div>
</div>
<div class="mono d-inline bg0 p-2 fs15" id="depositAddress"></div>
<div class="d-inline">
<img class="mb-3" id="qrcode" />
<div class="mono bg0 p-2 fs15" id="depositAddress"></div>
</div>
<div class="my-3">
<button id="newDepAddrBttn" type="button" class=" px-2 justify-content-center fs15 bg2 selected">New Deposit Address</button>
</div>
Expand Down
5 changes: 4 additions & 1 deletion client/webserver/site/src/localized_html/pl-PL/wallets.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,10 @@
<span id="depositName"></span>
<div class="form-closer hoverbg"><span class="ico-cross"></span></div>
</div>
<div class="mono d-inline bg0 p-2 fs15" id="depositAddress"></div>
<div class="d-inline">
<img class="mb-3" id="qrcode" />
<div class="mono bg0 p-2 fs15" id="depositAddress"></div>
</div>
<div class="my-3">
<button id="newDepAddrBttn" type="button" class=" px-2 justify-content-center fs15 bg2 selected">Nowy adres do depozytów</button>
</div>
Expand Down
5 changes: 4 additions & 1 deletion client/webserver/site/src/localized_html/pt-BR/wallets.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,10 @@
<span id="depositName"></span>
<div class="form-closer hoverbg"><span class="ico-cross"></span></div>
</div>
<div class="mono d-inline bg0 p-2 fs15" id="depositAddress"></div>
<div class="d-inline">
<img class="mb-3" id="qrcode" />
<div class="mono bg0 p-2 fs15" id="depositAddress"></div>
</div>
<div class="my-3">
<button id="newDepAddrBttn" type="button" class=" px-2 justify-content-center fs15 bg2 selected">Novo endereço de depósito</button>
</div>
Expand Down
5 changes: 4 additions & 1 deletion client/webserver/site/src/localized_html/zh-CN/wallets.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,10 @@
<span id="depositName"></span>
<div class="form-closer hoverbg"><span class="ico-cross"></span></div>
</div>
<div class="mono d-inline bg0 p-2 fs15" id="depositAddress"></div>
<div class="d-inline">
<img class="mb-3" id="qrcode" />
<div class="mono bg0 p-2 fs15" id="depositAddress"></div>
</div>
<div class="my-3">
<button id="newDepAddrBttn" type="button" class=" px-2 justify-content-center fs15 bg2 selected">新存款地址</button>
</div>
Expand Down
2 changes: 2 additions & 0 deletions client/webserver/webserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,8 @@ func New(cfg *Config) (*WebServer, error) {
web.Get(registerRoute, s.handleRegister)
web.Get(settingsRoute, s.handleSettings)

web.Get("/generateqrcode", s.handleGenerateQRCode)

// The rest of the web handlers require initialization.
web.Group(func(webInit chi.Router) {
webInit.Use(s.requireInit)
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ require (
github.com/jrick/logrotate v1.0.0
github.com/lib/pq v1.10.3
github.com/lightninglabs/neutrino v0.13.1-0.20211214231330-53b628ce1756
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e
go.etcd.io/bbolt v1.3.5
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -513,6 +513,8 @@ github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible h1
github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e h1:MRM5ITcdelLK2j1vwZ3Je0FKVCfqOLp5zO6trqMLYs0=
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e/go.mod h1:XV66xRDqSt+GTGFMVlhk3ULuV0y9ZmzeVGR4mloJI3M=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s=
Expand Down