Skip to content

Commit d02f8ee

Browse files
authored
Merge pull request #10 from algorandfoundation/feat/add-qr-code
feat: adds QR code capability ENG-593 ENG-595 ENG-596
2 parents 4e48c39 + 6295d64 commit d02f8ee

File tree

16 files changed

+766
-35
lines changed

16 files changed

+766
-35
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ bin
2525
go.work
2626
go.work.sum
2727

28+
# IDE
29+
.vscode/
30+
2831
# env file
2932
.env
3033

api/lf.go

Lines changed: 487 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cmd/root.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@ package cmd
33
import (
44
"context"
55
"encoding/json"
6+
"io"
7+
"os"
8+
"strings"
9+
610
"github.com/algorandfoundation/hack-tui/api"
711
"github.com/algorandfoundation/hack-tui/internal"
812
"github.com/algorandfoundation/hack-tui/ui"
@@ -11,9 +15,6 @@ import (
1115
"github.com/oapi-codegen/oapi-codegen/v2/pkg/securityprovider"
1216
"github.com/spf13/cobra"
1317
"github.com/spf13/viper"
14-
"io"
15-
"os"
16-
"strings"
1718
)
1819

1920
const BANNER = `
@@ -60,7 +61,7 @@ var (
6061
},
6162
ParticipationKeys: partkeys,
6263
}
63-
state.Accounts = internal.AccountsFromState(&state)
64+
state.Accounts = internal.AccountsFromState(&state, client)
6465

6566
// Fetch current state
6667
err = state.Status.Fetch(context.Background(), client)

generate.yaml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,5 @@ output-options:
1717
- DeleteParticipationKeyByID
1818
- GetParticipationKeyByID
1919
- AppendKeys
20-
- GetBlock
20+
- GetBlock
21+
- AccountInformation

go.mod

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ go 1.22.0
55
toolchain go1.23.1
66

77
require (
8+
github.com/algorandfoundation/algourl v0.0.0-20241023193235-8bbf72ad0b37
89
github.com/charmbracelet/bubbles v0.20.0
910
github.com/charmbracelet/bubbletea v1.1.1
1011
github.com/charmbracelet/lipgloss v0.13.0
@@ -16,7 +17,12 @@ require (
1617
github.com/spf13/viper v1.19.0
1718
)
1819

20+
require gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
21+
1922
require (
23+
github.com/algorand/go-algorand-sdk/v2 v2.6.0
24+
github.com/algorand/go-codec/codec v1.1.10 // indirect
25+
github.com/algorandfoundation/go-tinyqr v0.0.0-20241018103413-2082a3d637eb // indirect
2026
github.com/apapsch/go-jsonmerge/v2 v2.0.0 // indirect
2127
github.com/atotto/clipboard v0.1.4 // indirect
2228
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
@@ -27,6 +33,7 @@ require (
2733
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect
2834
github.com/fsnotify/fsnotify v1.7.0 // indirect
2935
github.com/go-logfmt/logfmt v0.6.0 // indirect
36+
github.com/google/go-querystring v1.1.0 // indirect
3037
github.com/google/uuid v1.6.0 // indirect
3138
github.com/hashicorp/hcl v1.0.0 // indirect
3239
github.com/inconshreveable/mousetrap v1.1.0 // indirect
@@ -50,11 +57,11 @@ require (
5057
github.com/spf13/pflag v1.0.5 // indirect
5158
github.com/subosito/gotenv v1.6.0 // indirect
5259
go.uber.org/multierr v1.11.0 // indirect
60+
golang.org/x/crypto v0.28.0 // indirect
5361
golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 // indirect
5462
golang.org/x/sync v0.8.0 // indirect
5563
golang.org/x/sys v0.26.0 // indirect
5664
golang.org/x/text v0.19.0 // indirect
57-
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
5865
gopkg.in/ini.v1 v1.67.0 // indirect
5966
gopkg.in/yaml.v3 v3.0.1 // indirect
6067
)

go.sum

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,12 @@
11
github.com/RaveNoX/go-jsoncommentstrip v1.0.0/go.mod h1:78ihd09MekBnJnxpICcwzCMzGrKSKYe4AqU6PDYYpjk=
2+
github.com/algorand/go-algorand-sdk/v2 v2.6.0 h1:pfL8lloEi26l6PwAFicmPUguWgKpy1eZZTMlQcci5h0=
3+
github.com/algorand/go-algorand-sdk/v2 v2.6.0/go.mod h1:4ayerzjoWChm3kuVhbgFgURTbaYTtlj0c41eP3av5lw=
4+
github.com/algorand/go-codec/codec v1.1.10 h1:zmWYU1cp64jQVTOG8Tw8wa+k0VfwgXIPbnDfiVa+5QA=
5+
github.com/algorand/go-codec/codec v1.1.10/go.mod h1:YkEx5nmr/zuCeaDYOIhlDg92Lxju8tj2d2NrYqP7g7k=
6+
github.com/algorandfoundation/algourl v0.0.0-20241023193235-8bbf72ad0b37 h1:zt00SDlTcFiYPvq+Wo/ZDmRwM2gBRW/VhOQ/zaplBAk=
7+
github.com/algorandfoundation/algourl v0.0.0-20241023193235-8bbf72ad0b37/go.mod h1:o91gtX3JDwJpS10P5cm6dwUsArtNtX+3kDshhelHTJ8=
8+
github.com/algorandfoundation/go-tinyqr v0.0.0-20241018103413-2082a3d637eb h1:NFKjd5BKatUpYUXiofxvWd0VqVoinsVzugtQw/W+vKs=
9+
github.com/algorandfoundation/go-tinyqr v0.0.0-20241018103413-2082a3d637eb/go.mod h1:j4+scGl0Oz2rw+bnoPxfmvregASzMapI5ydPrGzTDBU=
210
github.com/apapsch/go-jsonmerge/v2 v2.0.0 h1:axGnT1gRIfimI7gJifB699GoE/oq+F2MU7Dml6nw9rQ=
311
github.com/apapsch/go-jsonmerge/v2 v2.0.0/go.mod h1:lvDnEdqiQrp0O42VQGgmlKpxL1AP2+08jFMw88y4klk=
412
github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z4=
@@ -37,8 +45,11 @@ github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nos
3745
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
3846
github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4=
3947
github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
48+
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
4049
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
4150
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
51+
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
52+
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
4253
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
4354
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
4455
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
@@ -109,18 +120,46 @@ github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsT
109120
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
110121
github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=
111122
github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
123+
github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
112124
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
113125
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
126+
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
127+
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
128+
golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw=
129+
golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U=
114130
golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 h1:e66Fs6Z+fZTbFBAxKfP3PALWBtpfqks2bwGcexMxgtk=
115131
golang.org/x/exp v0.0.0-20240909161429-701f63a606c0/go.mod h1:2TbTHSBQa924w8M6Xs1QcRcFwyucIwBGpK1p2f1YFFY=
132+
golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY=
133+
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
134+
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
135+
golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
136+
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
137+
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
116138
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
117139
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
140+
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
141+
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
142+
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
143+
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
118144
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
145+
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
119146
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
120147
golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo=
121148
golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
149+
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
150+
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
151+
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
152+
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
153+
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
122154
golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM=
123155
golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
156+
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
157+
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
158+
golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E=
159+
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
160+
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
161+
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
162+
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
124163
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
125164
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
126165
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=

internal/accounts.go

Lines changed: 37 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,19 @@
11
package internal
22

33
import (
4+
"context"
5+
"errors"
6+
"fmt"
47
"time"
8+
9+
"github.com/algorandfoundation/hack-tui/api"
510
)
611

712
// Account represents a user's account, including address, status, balance, and number of keys.
813
type Account struct {
914
// Account Address is the algorand encoded address
1015
Address string
11-
// Status is general information about the account
16+
// Status is the Online/Offline/"NotParticipating" status of the account
1217
Status string
1318
// Balance is the current holdings in ALGO for the address.
1419
// the balance should be tracked infrequently and use an appropriate distance from the
@@ -22,21 +27,47 @@ type Account struct {
2227
LastModified int
2328
}
2429

25-
type Accounts map[string]Account
30+
// Get Online Status of Account
31+
func getAccountOnlineStatus(client *api.ClientWithResponses, address string) (string, error) {
32+
var format api.AccountInformationParamsFormat = "json"
33+
r, err := client.AccountInformationWithResponse(
34+
context.Background(),
35+
address,
36+
&api.AccountInformationParams{
37+
Format: &format,
38+
})
39+
40+
if err != nil {
41+
return "N/A", err
42+
}
43+
44+
if r.StatusCode() != 200 {
45+
return "N/A", errors.New(fmt.Sprintf("Failed to get account information. Received error code: %d", r.StatusCode()))
46+
}
2647

27-
// AccountsFromState maps the StateModel to a keyed map of Account
28-
func AccountsFromState(state *StateModel) Accounts {
48+
return r.JSON200.Status, nil
49+
}
50+
51+
// AccountsFromParticipationKeys maps an array of api.ParticipationKey to a keyed map of Account
52+
func AccountsFromState(state *StateModel, client *api.ClientWithResponses) map[string]Account {
2953
values := make(map[string]Account)
3054
if state == nil || state.ParticipationKeys == nil {
3155
return values
3256
}
3357
for _, key := range *state.ParticipationKeys {
3458
val, ok := values[key.Address]
3559
if !ok {
36-
// TODO: update from State
60+
61+
statusOnline, err := getAccountOnlineStatus(client, key.Address)
62+
63+
if err != nil {
64+
// TODO: Logging
65+
panic(err)
66+
}
67+
3768
values[key.Address] = Account{
3869
Address: key.Address,
39-
Status: "NA",
70+
Status: statusOnline,
4071
Balance: 0,
4172
Expires: time.Unix(0, 0),
4273
Keys: 1,

internal/state.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package internal
33
import (
44
"context"
55
"errors"
6+
67
"github.com/algorandfoundation/hack-tui/api"
78
)
89

@@ -80,8 +81,8 @@ func (s *StateModel) UpdateMetricsFromRPC(ctx context.Context, client *api.Clien
8081
s.Metrics.RX = res["algod_network_received_bytes_total"]
8182
}
8283
}
83-
func (s *StateModel) UpdateAccounts() {
84-
s.Accounts = AccountsFromState(s)
84+
func (s *StateModel) UpdateAccounts(client *api.ClientWithResponses) {
85+
s.Accounts = AccountsFromState(s, client)
8586
}
8687

8788
func (s *StateModel) UpdateKeys(ctx context.Context, client *api.ClientWithResponses) {
@@ -92,6 +93,6 @@ func (s *StateModel) UpdateKeys(ctx context.Context, client *api.ClientWithRespo
9293
}
9394
if err == nil {
9495
s.Admin = true
95-
s.UpdateAccounts()
96+
s.UpdateAccounts(client)
9697
}
9798
}

internal/status.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package internal
33
import (
44
"context"
55
"fmt"
6+
67
"github.com/algorandfoundation/hack-tui/api"
78
)
89

@@ -33,7 +34,6 @@ func (m *StatusModel) Fetch(ctx context.Context, client *api.ClientWithResponses
3334
}
3435
m.Network = v.JSON200.GenesisId
3536
m.Version = fmt.Sprintf("v%d.%d.%d-%s", v.JSON200.Build.Major, v.JSON200.Build.Minor, v.JSON200.Build.BuildNumber, v.JSON200.Build.Channel)
36-
3737
}
3838

3939
s, err := client.GetStatusWithResponse(ctx)

ui/pages/accounts/model.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
package accounts
22

33
import (
4+
"sort"
5+
"strconv"
6+
47
"github.com/algorandfoundation/hack-tui/internal"
58
"github.com/algorandfoundation/hack-tui/ui/controls"
69
"github.com/algorandfoundation/hack-tui/ui/pages"
710
"github.com/charmbracelet/bubbles/table"
811
"github.com/charmbracelet/lipgloss"
9-
"sort"
10-
"strconv"
1112
)
1213

1314
type ViewModel struct {

0 commit comments

Comments
 (0)