Skip to content

Commit

Permalink
Merge branch 'main' into feat/generate-modal-validation
Browse files Browse the repository at this point in the history
  • Loading branch information
PhearZero committed Dec 3, 2024
2 parents eb69ff9 + 83a31a1 commit 03895ba
Show file tree
Hide file tree
Showing 11 changed files with 197 additions and 122 deletions.
9 changes: 9 additions & 0 deletions codecov.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
coverage:
status:
project:
default:
target: 60%
threshold: 10%
patch:
default:
target: 60%
30 changes: 21 additions & 9 deletions internal/accounts.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import (
// Account represents a user's account, including address, status, balance, and number of keys.
type Account struct {
Participation *api.AccountParticipation
// IncentiveEligible determines the minimum fee
IncentiveEligible bool
// Account Address is the algorand encoded address
Address string
// Status is the Online/Offline/"NotParticipating" status of the account
Expand Down Expand Up @@ -70,9 +72,10 @@ func AccountsFromState(state *StateModel, t Time, client api.ClientWithResponses
val, ok := values[key.Address]
if !ok {
var account = api.Account{
Address: key.Address,
Status: "Unknown",
Amount: 0,
Address: key.Address,
Status: "Unknown",
IncentiveEligible: nil,
Amount: 0,
}
if state.Status.State != SyncingState {
var err error
Expand All @@ -84,13 +87,22 @@ func AccountsFromState(state *StateModel, t Time, client api.ClientWithResponses
}
}

// Check for eligibility
var incentiveEligible = false
if account.IncentiveEligible == nil {
incentiveEligible = false
} else {
incentiveEligible = *account.IncentiveEligible
}

values[key.Address] = Account{
Participation: account.Participation,
Address: key.Address,
Status: account.Status,
Balance: account.Amount / 1000000,
Expires: GetExpiresTime(t, key, state),
Keys: 1,
Participation: account.Participation,
Address: key.Address,
Status: account.Status,
Balance: account.Amount / 1000000,
Expires: GetExpiresTime(t, key, state),
IncentiveEligible: incentiveEligible,
Keys: 1,
}
} else {
val.Keys++
Expand Down
9 changes: 5 additions & 4 deletions internal/participation.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,7 @@ func FindParticipationIdForVoteKey(slice *[]api.ParticipationKey, votekey []byte
return nil
}

func ToLoraDeepLink(network string, offline bool, part api.ParticipationKey) (string, error) {
fee := 2000000
func ToLoraDeepLink(network string, offline bool, incentiveEligible bool, part api.ParticipationKey) (string, error) {
var loraNetwork = strings.Replace(strings.Replace(network, "-v1.0", "", 1), "-v1", "", 1)
if loraNetwork == "dockernet" || loraNetwork == "tuinet" {
loraNetwork = "localnet"
Expand All @@ -124,8 +123,7 @@ func ToLoraDeepLink(network string, offline bool, part api.ParticipationKey) (st
)
} else {
query = fmt.Sprintf(
"type[0]=keyreg&fee[0]=%d&sender[0]=%s&selkey[0]=%s&sprfkey[0]=%s&votekey[0]=%s&votefst[0]=%d&votelst[0]=%d&votekd[0]=%d",
fee,
"type[0]=keyreg&sender[0]=%s&selkey[0]=%s&sprfkey[0]=%s&votekey[0]=%s&votefst[0]=%d&votelst[0]=%d&votekd[0]=%d",
part.Address,
base64.RawURLEncoding.EncodeToString(part.Key.SelectionParticipationKey),
base64.RawURLEncoding.EncodeToString(*part.Key.StateProofKey),
Expand All @@ -134,6 +132,9 @@ func ToLoraDeepLink(network string, offline bool, part api.ParticipationKey) (st
part.Key.VoteLastValid,
part.Key.VoteKeyDilution,
)
if incentiveEligible {
query += fmt.Sprintf("&fee[0]=%d", 2000000)
}
}
return fmt.Sprintf("https://lora.algokit.io/%s/transaction-wizard?%s", loraNetwork, strings.Replace(query, "[0]", encodedIndex, -1)), nil
}
95 changes: 51 additions & 44 deletions internal/participation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,47 @@ import (
"context"
"fmt"
"github.com/algorandfoundation/hack-tui/api"
"github.com/oapi-codegen/oapi-codegen/v2/pkg/securityprovider"
"github.com/algorandfoundation/hack-tui/internal/test"
"github.com/algorandfoundation/hack-tui/internal/test/mock"
"testing"
)

func Test_ToLoraDeeplink(t *testing.T) {
link, err := ToLoraDeepLink("tuinet-v1", true, true, api.ParticipationKey{
Address: "ABC",
EffectiveFirstValid: nil,
EffectiveLastValid: nil,
Id: "",
Key: api.AccountParticipation{},
LastBlockProposal: nil,
LastStateProof: nil,
LastVote: nil,
})
if err != nil {
t.Error(err)
}
if link != "https://lora.algokit.io/localnet/transaction-wizard?type%5B0%5D=keyreg&sender%5B0%5D=ABC" {
t.Error("Link should be a known deeplink")
}

link, err = ToLoraDeepLink("tuinet-v1", false, true, mock.Keys[0])
if err != nil {
t.Error(err)
}
if link != "https://lora.algokit.io/localnet/transaction-wizard?type%5B0%5D=keyreg&sender%5B0%5D=ABC&selkey%5B0%5D=VEVTVEtFWQ&sprfkey%5B0%5D=VEVTVEtFWQ&votekey%5B0%5D=VEVTVEtFWQ&votefst%5B0%5D=0&votelst%5B0%5D=30000&votekd%5B0%5D=100&fee%5B0%5D=2000000" {
t.Error("Link should be a known deeplink fee")
}

link, err = ToLoraDeepLink("tuinet-v1", false, false, mock.Keys[0])
if err != nil {
t.Error(err)
}
if link != "https://lora.algokit.io/localnet/transaction-wizard?type%5B0%5D=keyreg&sender%5B0%5D=ABC&selkey%5B0%5D=VEVTVEtFWQ&sprfkey%5B0%5D=VEVTVEtFWQ&votekey%5B0%5D=VEVTVEtFWQ&votefst%5B0%5D=0&votelst%5B0%5D=30000&votekd%5B0%5D=100" {
t.Error("Link should be a known deeplink fee")
}

}

func Test_ListParticipationKeys(t *testing.T) {
ctx := context.Background()
client, err := api.NewClientWithResponses("https://mainnet-api.4160.nodely.dev:443")
Expand All @@ -23,16 +60,9 @@ func Test_ListParticipationKeys(t *testing.T) {
}

// Setup elevated client
apiToken, err := securityprovider.NewSecurityProviderApiKey("header", "X-Algo-API-Token", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")
if err != nil {
t.Fatal(err)
}
client, err = api.NewClientWithResponses("http://localhost:8080", api.WithRequestEditorFn(apiToken.Intercept))
if err != nil {
t.Fatal(err)
}
tClient := test.GetClient(false)

keys, err := GetPartKeys(ctx, client)
keys, err := GetPartKeys(ctx, tClient)
if err != nil {
t.Fatal(err)
}
Expand All @@ -54,25 +84,17 @@ func Test_ReadParticipationKey(t *testing.T) {
t.Fatal(err)
}

// Setup elevated client
apiToken, err := securityprovider.NewSecurityProviderApiKey("header", "X-Algo-API-Token", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")
if err != nil {
t.Fatal(err)
}
client, err = api.NewClientWithResponses("http://localhost:8080", api.WithRequestEditorFn(apiToken.Intercept))
if err != nil {
t.Fatal(err)
}
tClient := test.GetClient(false)

keys, err := GetPartKeys(ctx, client)
keys, err := GetPartKeys(ctx, tClient)
if err != nil {
t.Fatal(err)
}
if keys == nil {
t.Fatal(err)
}

_, err = ReadPartKey(ctx, client, (*keys)[0].Id)
_, err = ReadPartKey(ctx, tClient, (*keys)[0].Id)

if err != nil {
t.Fatal(err)
Expand All @@ -88,31 +110,23 @@ func Test_GenerateParticipationKey(t *testing.T) {
if err != nil {
t.Fatal(err)
}

// Generate error
_, err = GenerateKeyPair(ctx, client, "", nil)
if err == nil {
t.Fatal(err)
}

// Setup elevated client
apiToken, err := securityprovider.NewSecurityProviderApiKey("header", "X-Algo-API-Token", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")
if err != nil {
t.Fatal(err)
}
client, err = api.NewClientWithResponses("http://localhost:8080", api.WithRequestEditorFn(apiToken.Intercept))
if err != nil {
t.Fatal(err)
}
// Setup test client
tClient := test.GetClient(false)

params := api.GenerateParticipationKeysParams{
Dilution: nil,
First: 0,
Last: 10000,
Last: 30,
}

// This returns nothing and sucks
key, err := GenerateKeyPair(ctx, client, "QNZ7GONNHTNXFW56Y24CNJQEMYKZKKI566ASNSWPD24VSGKJWHGO6QOP7U", &params)
key, err := GenerateKeyPair(ctx, tClient, "ABC", &params)
if err != nil {
t.Fatal(err)
}
Expand All @@ -121,21 +135,14 @@ func Test_GenerateParticipationKey(t *testing.T) {

func Test_DeleteParticipationKey(t *testing.T) {
ctx := context.Background()
// Setup elevated client
apiToken, err := securityprovider.NewSecurityProviderApiKey("header", "X-Algo-API-Token", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")
if err != nil {
t.Fatal(err)
}
client, err := api.NewClientWithResponses("http://localhost:8080", api.WithRequestEditorFn(apiToken.Intercept))
if err != nil {
t.Fatal(err)
}

client := test.GetClient(false)
params := api.GenerateParticipationKeysParams{
Dilution: nil,
First: 0,
Last: 10000,
Last: 30000,
}
key, err := GenerateKeyPair(ctx, client, "QNZ7GONNHTNXFW56Y24CNJQEMYKZKKI566ASNSWPD24VSGKJWHGO6QOP7U", &params)
key, err := GenerateKeyPair(ctx, client, "ABC", &params)
if err != nil {
t.Fatal(err)
}
Expand Down
30 changes: 30 additions & 0 deletions internal/test/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,36 @@ algod_crypto_vrf_hash_total 0`
}
return &res, nil
}
func (c *Client) GetParticipationKeyByIDWithResponse(ctx context.Context, participationId string, reqEditors ...api.RequestEditorFn) (*api.GetParticipationKeyByIDResponse, error) {
var res api.GetParticipationKeyByIDResponse
if !c.Invalid {
httpResponse := http.Response{StatusCode: 200}
res = api.GetParticipationKeyByIDResponse{
Body: nil,
HTTPResponse: &httpResponse,
JSON200: &mock.Keys[0],
JSON400: nil,
JSON401: nil,
JSON404: nil,
JSON500: nil,
}
} else {
httpResponse := http.Response{StatusCode: 404}
res = api.GetParticipationKeyByIDResponse{
Body: nil,
HTTPResponse: &httpResponse,
JSON200: nil,
JSON400: nil,
JSON401: nil,
JSON404: nil,
JSON500: nil,
}
}
if c.Errors {
return nil, errors.New("test error")
}
return &res, nil
}
func (c *Client) GetParticipationKeysWithResponse(ctx context.Context, reqEditors ...api.RequestEditorFn) (*api.GetParticipationKeysResponse, error) {
var res api.GetParticipationKeysResponse
clone := mock.Keys
Expand Down
11 changes: 6 additions & 5 deletions ui/internal/test/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,12 @@ func GetState(client api.ClientWithResponsesInterface) *internal.StateModel {
val, ok := values[key.Address]
if !ok {
values[key.Address] = internal.Account{
Address: key.Address,
Status: "Offline",
Balance: 0,
Expires: internal.GetExpiresTime(clock, key, sm),
Keys: 1,
Address: key.Address,
Status: "Offline",
Balance: 0,
IncentiveEligible: true,
Expires: internal.GetExpiresTime(clock, key, sm),
Keys: 1,
}
} else {
val.Keys++
Expand Down
32 changes: 16 additions & 16 deletions ui/modal/testdata/Test_Snapshot/TransactionModal.golden
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@






╭──Register Offline─────────────────────────────────────────╮
Expand All @@ -29,22 +30,20 @@
│ Scan the QR code with Pera or Defly │
│ (make sure you use the testnet-v1.0 network) │
│ │
│ █████████████████████████████████ │
│ ██ ▄▄▄▄▄ █▀▀ ▄█▀▄██▀█ ▄█ ▄▄▄▄▄ ██ │
│ ██ █ █ ██▄█ █▀█▄██▄▀ █ █ █ ██ │
│ ██ █▄▄▄█ █▄ ▄▀▄▄▀▀ █ ▄█ █▄▄▄█ ██ │
│ ██▄▄▄▄▄▄▄█▄▀▄▀ █▄█ ▀▄▀▄█▄▄▄▄▄▄▄██ │
│ ██ ▀ █ ▀▄██▀█ ▀▀██ ▀██▀██▄█▀ ▀██ │
│ ██▄ ▀▄██▄ ▀▄ ▄▀▀ ▀▀▀█▀█▀ ▄▄█▄ ██ │
│ ██ ▄▀▄ █▄ ██▀▄█ █ ▄▀██ ▄█▄ █ ██ │
│ ██▀▄▀▀█▀▄▀▀▀ ██▄██▄▀ ▀▀█ ▄▀██ ▄██ │
│ ███▀██▀▄▄ ▄▀▀▀▄▀██▀ ▀▄██ ▀█▀█ ▀██ │
│ ██▄▀ ▀▄▄▄ ▄ █▀▀ ▀█▀▄▀▀▄▀▄▀▄▄▄▄██ │
│ ██▄█▄▄██▄█▀█▀███ ▄▀ █▀ ▄▄▄ █▀▀ ██ │
│ ██ ▄▄▄▄▄ ██▄█▄█▄█▀▀▀▀▄ █▄█ ██▄ ██ │
│ ██ █ █ █▄▄▄█▄▀██ ▄ █▄▄▄ ██▀ ██ │
│ ██ █▄▄▄█ █▄ ▄█▀ ██▀▀ ██▀ ▀▄▀▄██ │
│ ██▄▄▄▄▄▄▄█▄█▄███▄▄▄▄█▄▄████▄█▄▄██ │
│ █████████████████████████████ │
│ ██ ▄▄▄▄▄ █▀█▄▀█▀█ ▀█ ▄▄▄▄▄ ██ │
│ ██ █ █ ██▀▄▀ █ █ █ █ █ ██ │
│ ██ █▄▄▄█ █▄▀▀▀█▀ ██ █▄▄▄█ ██ │
│ ██▄▄▄▄▄▄▄█▄█▄█▄▀ ▀ █▄▄▄▄▄▄▄██ │
│ ██▄▀ ▀ █▄▀▀ ▄█▄ █▀▀▀▀▄██ ▀██ │
│ ███▀ ▄▀▄▄▀▀█▄█▄▀▀█▀▄▀▀▀▄█ ▄██ │
│ ███▀█ ▀▄ █ ▄▀▄▄█▄█▀ ██▀ ▀██ │
│ ██▄▀█ ▄▄ █▄ █▀ ██▄▀█▄▄█▄▄██ │
│ ██▄███▄█▄▄▀▄▀█ █▀ ▄▄▄ █▀ ██ │
│ ██ ▄▄▄▄▄ ██▄ ▀▀▀▀█ █▄█ ██ ██ │
│ ██ █ █ █▄ ▀█ ▄▀▀ ▄▄ ▀█████ │
│ ██ █▄▄▄█ █▄▀ █▄▀ ▀▄▀▄ ▄▄▀▄██ │
│ ██▄▄▄▄▄▄▄█▄█▄██▄█▄▄▄▄▄███▄▄██ │
│ │
│ -or- │
│ │
Expand Down Expand Up @@ -75,6 +74,7 @@







Loading

0 comments on commit 03895ba

Please sign in to comment.