Skip to content

Commit cf78f2b

Browse files
author
Tasos Bitsios
committed
feat: enable incentive eligibility fees
1 parent b241852 commit cf78f2b

File tree

7 files changed

+57
-12
lines changed

7 files changed

+57
-12
lines changed

cmd/bootstrap.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ var bootstrapCmd = &cobra.Command{
162162

163163
t := new(system.Clock)
164164
// Fetch the state and handle any creation errors
165-
state, stateResponse, err := algod.NewStateModel(ctx, client, httpPkg)
165+
state, stateResponse, err := algod.NewStateModel(ctx, client, httpPkg, false)
166166
cmdutils.WithInvalidResponsesExplanations(err, stateResponse, cmd.UsageString())
167167
cobra.CheckErr(err)
168168

cmd/root.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ var (
2424

2525
NeedsUpgrade = false
2626

27+
// whether the user forbids incentive eligibility fees to be set
28+
IncentivesDisabled = false
29+
2730
// algodEndpoint defines the URI address of the Algorand node, including the protocol (http/https), for client communication.
2831
algodData string
2932

@@ -60,7 +63,7 @@ var (
6063
httpPkg := new(api.HttpPkg)
6164
t := new(system.Clock)
6265
// Fetch the state and handle any creation errors
63-
state, stateResponse, err := algod.NewStateModel(ctx, client, httpPkg)
66+
state, stateResponse, err := algod.NewStateModel(ctx, client, httpPkg, IncentivesDisabled)
6467
utils.WithInvalidResponsesExplanations(err, stateResponse, cmd.UsageString())
6568
cobra.CheckErr(err)
6669

@@ -127,6 +130,7 @@ func NeedsToBeStopped(cmd *cobra.Command, args []string) {
127130
// init initializes the application, setting up logging, commands, and version information.
128131
func init() {
129132
log.SetReportTimestamp(false)
133+
RootCmd.Flags().BoolVarP(&IncentivesDisabled, "no-incentives", "n", false, style.LightBlue("Disable setting incentive eligibility fees"))
130134
RootCmd.SetVersionTemplate(fmt.Sprintf("nodekit-%s-%s@{{.Version}}\n", runtime.GOARCH, runtime.GOOS))
131135
// Add Commands
132136
if runtime.GOOS != "windows" {

internal/algod/participation/participation.go

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ func GetOnlineShortLink(http api.HttpPkgInterface, part OnlineShortLinkBody) (Sh
167167
if err != nil {
168168
return response, err
169169
}
170-
res, err := http.Post("http://b.nodekit.run/online", "applicaiton/json", bytes.NewReader(data))
170+
res, err := http.Post("http://b.nodekit.run/online", "application/json", bytes.NewReader(data))
171171
if err != nil {
172172
return response, err
173173
}
@@ -219,6 +219,10 @@ func GetOfflineShortLink(http api.HttpPkgInterface, offline OfflineShortLinkBody
219219

220220
// ToShortLink generates a shortened URL string using the unique
221221
// identifier from the provided ShortLinkResponse.
222-
func ToShortLink(link ShortLinkResponse) string {
223-
return fmt.Sprintf("https://b.nodekit.run/%s", link.Id)
222+
func ToShortLink(link ShortLinkResponse, incentiveEligibleFee bool) string {
223+
suffix := ""
224+
if incentiveEligibleFee {
225+
suffix = "i"
226+
}
227+
return fmt.Sprintf("https://b.nodekit.run/%s%s", link.Id, suffix)
224228
}

internal/algod/state.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@ type StateModel struct {
3838
// TODO: handle contexts instead of adding it to state (skill-issue zero)
3939
Watching bool
4040

41+
// Whether user has disabled automatically applying incentive eligibility fees
42+
IncentivesDisabled bool
43+
4144
// Client provides an interface for interacting with API endpoints,
4245
// enabling various node operations and data retrieval.
4346
Client api.ClientWithResponsesInterface
@@ -53,7 +56,7 @@ type StateModel struct {
5356

5457
// NewStateModel initializes and returns a new StateModel instance
5558
// along with an API response and potential error.
56-
func NewStateModel(ctx context.Context, client api.ClientWithResponsesInterface, httpPkg api.HttpPkgInterface) (*StateModel, api.ResponseInterface, error) {
59+
func NewStateModel(ctx context.Context, client api.ClientWithResponsesInterface, httpPkg api.HttpPkgInterface, incentivesDisabled bool) (*StateModel, api.ResponseInterface, error) {
5760
// Preload the node status
5861
status, response, err := NewStatus(ctx, client, httpPkg)
5962
if err != nil {
@@ -79,6 +82,8 @@ func NewStateModel(ctx context.Context, client api.ClientWithResponsesInterface,
7982
Client: client,
8083
HttpPkg: httpPkg,
8184
Context: ctx,
85+
86+
IncentivesDisabled: incentivesDisabled,
8287
}, partkeysResponse, nil
8388
}
8489

internal/algod/status.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,9 @@ type Status struct {
4848
// NeedsUpdate indicates whether the system requires an update based on the current version and available release data.
4949
NeedsUpdate bool `json:"needsUpdate"`
5050

51+
// LastProtocolVersion represents the most recent round protocol version.
52+
LastProtocolVersion string `json:"lastProtocolVersion"`
53+
5154
// LastRound represents the most recent round number recorded by the system or client.
5255
LastRound uint64 `json:"lastRound"`
5356

@@ -106,6 +109,9 @@ func (s Status) Update(status Status) Status {
106109
if s.LastRound != status.LastRound {
107110
s.LastRound = status.LastRound
108111
}
112+
if s.LastProtocolVersion != status.LastProtocolVersion {
113+
s.LastProtocolVersion = status.LastProtocolVersion
114+
}
109115
return s
110116
}
111117

@@ -127,6 +133,7 @@ func (s Status) Wait(ctx context.Context) (Status, api.ResponseInterface, error)
127133
// Merge updates the current Status with data from a given StatusLike instance and adjusts fields based on defined conditions.
128134
func (s Status) Merge(res api.StatusLike) Status {
129135
s.LastRound = uint64(res.LastRound)
136+
s.LastProtocolVersion = res.LastVersion
130137
catchpoint := res.Catchpoint
131138
if catchpoint != nil && *catchpoint != "" {
132139
s.State = FastCatchupState

ui/modals/transaction/controller.go

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,21 @@ func (m *ViewModel) Account() *algod.Account {
5454

5555
return nil
5656
}
57+
58+
func (m *ViewModel) IsIncentiveProtocol() bool {
59+
return m.State.Status.LastProtocolVersion == "https://github.com/algorandfoundation/specs/tree/236dcc18c9c507d794813ab768e467ea42d1b4d9"
60+
}
61+
62+
// Whether the 2A incentive fee should be added
63+
func (m *ViewModel) ShouldAddIncentivesFee() bool {
64+
// conditions for 2A fee:
65+
// 1) incentives allowed by user: command line flag to disable incentives has not been passed
66+
// 2) online keyreg
67+
// 3) protocol supports incentives
68+
// 4) account is not already incentives eligible
69+
return m.State != nil && !m.State.IncentivesDisabled && !m.Active && m.IsIncentiveProtocol() && !m.Account().IncentiveEligible
70+
}
71+
5772
func (m *ViewModel) UpdateState() {
5873
if m.Participation == nil {
5974
return
@@ -64,11 +79,10 @@ func (m *ViewModel) UpdateState() {
6479
}
6580

6681
var fee *uint64
67-
// TODO: enable fee with either feature flag or config flag
68-
//if m.Account().IncentiveEligible && !m.Active {
69-
//feeInst := uint64(2000000)
70-
//fee = &feeInst
71-
//}
82+
if m.ShouldAddIncentivesFee() {
83+
feeInst := uint64(2000000)
84+
fee = &feeInst
85+
}
7286

7387
m.ATxn.AUrlTxnKeyCommon.Sender = m.Participation.Address
7488
m.ATxn.AUrlTxnKeyCommon.Type = string(types.KeyRegistrationTx)

ui/modals/transaction/view.go

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,23 @@ func (m ViewModel) View() string {
2929
adj = "online"
3030
}
3131
intro := fmt.Sprintf("Sign this transaction to register your account as %s", adj)
32-
link := participation.ToShortLink(*m.Link)
32+
link := participation.ToShortLink(*m.Link, m.ShouldAddIncentivesFee())
3333
loraText := lipgloss.JoinVertical(
3434
lipgloss.Center,
3535
"Open this URL in your browser:\n",
3636
style.WithHyperlink(link, link),
3737
)
38+
39+
if m.ShouldAddIncentivesFee() {
40+
loraText = lipgloss.JoinVertical(
41+
lipgloss.Center,
42+
loraText,
43+
"",
44+
"Note: Transction fee set to 2 ALGO",
45+
"for staking rewards eligibility",
46+
)
47+
}
48+
3849
if isOffline {
3950
loraText = lipgloss.JoinVertical(
4051
lipgloss.Center,

0 commit comments

Comments
 (0)