Skip to content

Commit

Permalink
add stake program (#235)
Browse files Browse the repository at this point in the history
  • Loading branch information
conorpp authored Oct 10, 2024
1 parent 05e94f2 commit bea4b03
Show file tree
Hide file tree
Showing 10 changed files with 1,106 additions and 0 deletions.
71 changes: 71 additions & 0 deletions programs/stake/Authorized.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
// Copyright 2024 github.com/cordialsys
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package stake

import (
"errors"

bin "github.com/gagliardetto/binary"
ag_solanago "github.com/gagliardetto/solana-go"
)

type Authorized struct {
// Address that will own the stake account
Staker *ag_solanago.PublicKey
// Address that is permitted to with from the stake account
Withdrawer *ag_solanago.PublicKey
}

func (auth *Authorized) UnmarshalWithDecoder(dec *bin.Decoder) error {
{
err := dec.Decode(&auth.Staker)
if err != nil {
return err
}
}
{
err := dec.Decode(&auth.Withdrawer)
if err != nil {
return err
}
}
return nil
}

func (auth *Authorized) MarshalWithEncoder(encoder *bin.Encoder) error {
{
err := encoder.Encode(*auth.Staker)
if err != nil {
return err
}
}
{
err := encoder.Encode(*auth.Withdrawer)
if err != nil {
return err
}
}
return nil
}

func (auth *Authorized) Validate() error {
if auth.Staker == nil {
return errors.New("staker parameter is not set")
}
if auth.Withdrawer == nil {
return errors.New("withdrawer parameter is not set")
}
return nil
}
120 changes: 120 additions & 0 deletions programs/stake/Deactivate.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
// Copyright 2024 github.com/cordialsys
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package stake

import (
"fmt"

bin "github.com/gagliardetto/binary"
"github.com/gagliardetto/solana-go"
"github.com/gagliardetto/solana-go/text/format"
"github.com/gagliardetto/treeout"
)

type Deactivate struct {

// [0] = [WRITE] Stake Account
// ··········· Delegated stake account to be deactivated
//
// [1] = [] Clock Sysvar
// ··········· The Clock Sysvar Account
//
// [2] = [SIGNER] Stake Authority
// ··········· Stake authority
//
solana.AccountMetaSlice `bin:"-" borsh_skip:"true"`
}

func (inst *Deactivate) Validate() error {

// Check whether all accounts are set:
for accIndex, acc := range inst.AccountMetaSlice {
if acc == nil {
return fmt.Errorf("ins.AccountMetaSlice[%v] is not set", accIndex)
}
}
return nil
}
func (inst *Deactivate) SetStakeAccount(stakeAccount solana.PublicKey) *Deactivate {
inst.AccountMetaSlice[0] = solana.Meta(stakeAccount).WRITE()
return inst
}
func (inst *Deactivate) SetClockSysvar(clockSysvar solana.PublicKey) *Deactivate {
inst.AccountMetaSlice[1] = solana.Meta(clockSysvar)
return inst
}
func (inst *Deactivate) SetStakeAuthority(stakeAuthority solana.PublicKey) *Deactivate {
inst.AccountMetaSlice[2] = solana.Meta(stakeAuthority).SIGNER()
return inst
}

func (inst *Deactivate) GetStakeAccount() *solana.AccountMeta {
return inst.AccountMetaSlice[0]
}
func (inst *Deactivate) GetClockSysvar() *solana.AccountMeta {
return inst.AccountMetaSlice[1]
}
func (inst *Deactivate) GetStakeAuthority() *solana.AccountMeta {
return inst.AccountMetaSlice[2]
}

func (inst Deactivate) Build() *Instruction {
return &Instruction{BaseVariant: bin.BaseVariant{
Impl: inst,
TypeID: bin.TypeIDFromUint32(Instruction_Deactivate, bin.LE),
}}
}

func (inst *Deactivate) EncodeToTree(parent treeout.Branches) {
parent.Child(format.Program(ProgramName, ProgramID)).
//
ParentFunc(func(programBranch treeout.Branches) {
programBranch.Child(format.Instruction("Deactivate")).
//
ParentFunc(func(instructionBranch treeout.Branches) {
// Parameters of the instruction:
instructionBranch.Child("Params").ParentFunc(func(paramsBranch treeout.Branches) {
})

// Accounts of the instruction:
instructionBranch.Child("Accounts").ParentFunc(func(accountsBranch treeout.Branches) {
accountsBranch.Child(format.Meta(" StakeAccount", inst.AccountMetaSlice.Get(0)))
accountsBranch.Child(format.Meta(" ClockSysvar", inst.AccountMetaSlice.Get(1)))
accountsBranch.Child(format.Meta(" StakeAuthoriy", inst.AccountMetaSlice.Get(2)))
})
})
})
}

// NewDeactivateInstructionBuilder creates a new `Deactivate` instruction builder.
func NewDeactivateInstructionBuilder() *Deactivate {
nd := &Deactivate{
AccountMetaSlice: make(solana.AccountMetaSlice, 3),
}
return nd
}

// NewDeactivateInstruction declares a new Deactivate instruction with the provided parameters and accounts.
func NewDeactivateInstruction(
// Params:
// Accounts:
stakeAccount solana.PublicKey,
stakeAuthority solana.PublicKey,
) *Deactivate {
return NewDeactivateInstructionBuilder().
SetStakeAccount(stakeAccount).
SetClockSysvar(solana.SysVarClockPubkey).
SetStakeAuthority(stakeAuthority)
}
143 changes: 143 additions & 0 deletions programs/stake/DelegateStake.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
// Copyright 2024 github.com/cordialsys
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package stake

import (
"fmt"

bin "github.com/gagliardetto/binary"
"github.com/gagliardetto/solana-go"
"github.com/gagliardetto/solana-go/text/format"
"github.com/gagliardetto/treeout"
)

type DelegateStake struct {
// [0] = [WRITE SIGNER] StakeAccount
// ··········· Stake account getting initialized
//
// [1] = [] Vote Account
// ··········· The validator vote account being delegated to
//
// [2] = [] Clock Sysvar
// ··········· The Clock Sysvar Account
//
// [3] = [] Stake History Sysvar
// ··········· The Stake History Sysvar Account
//
// [4] = [] Stake Config Account
// ··········· The Stake Config Account
//
// [5] = [WRITE SIGNER] Stake Authoriy
// ··········· The Stake Authority
//
solana.AccountMetaSlice `bin:"-" borsh_skip:"true"`
}

func (inst *DelegateStake) Validate() error {
// Check whether all accounts are set:
for accIndex, acc := range inst.AccountMetaSlice {
if acc == nil {
return fmt.Errorf("ins.AccountMetaSlice[%v] is not set", accIndex)
}
}
return nil
}
func (inst *DelegateStake) SetStakeAccount(stakeAccount solana.PublicKey) *DelegateStake {
inst.AccountMetaSlice[0] = solana.Meta(stakeAccount).WRITE().SIGNER()
return inst
}
func (inst *DelegateStake) SetVoteAccount(voteAcc solana.PublicKey) *DelegateStake {
inst.AccountMetaSlice[1] = solana.Meta(voteAcc)
return inst
}
func (inst *DelegateStake) SetClockSysvar(clockSysVarAcc solana.PublicKey) *DelegateStake {
inst.AccountMetaSlice[2] = solana.Meta(clockSysVarAcc)
return inst
}
func (inst *DelegateStake) SetStakeHistorySysvar(stakeHistorySysVarAcc solana.PublicKey) *DelegateStake {
inst.AccountMetaSlice[3] = solana.Meta(stakeHistorySysVarAcc)
return inst
}
func (inst *DelegateStake) SetConfigAccount(stakeConfigAcc solana.PublicKey) *DelegateStake {
inst.AccountMetaSlice[4] = solana.Meta(stakeConfigAcc)
return inst
}
func (inst *DelegateStake) SetStakeAuthority(stakeAuthority solana.PublicKey) *DelegateStake {
inst.AccountMetaSlice[5] = solana.Meta(stakeAuthority).WRITE().SIGNER()
return inst
}
func (inst *DelegateStake) GetStakeAccount() *solana.AccountMeta { return inst.AccountMetaSlice[0] }
func (inst *DelegateStake) GetVoteAccount() *solana.AccountMeta { return inst.AccountMetaSlice[1] }
func (inst *DelegateStake) GetClockSysvar() *solana.AccountMeta { return inst.AccountMetaSlice[2] }
func (inst *DelegateStake) GetStakeHistorySysvar() *solana.AccountMeta {
return inst.AccountMetaSlice[3]
}
func (inst *DelegateStake) GetConfigAccount() *solana.AccountMeta { return inst.AccountMetaSlice[4] }
func (inst *DelegateStake) GetStakeAuthority() *solana.AccountMeta { return inst.AccountMetaSlice[5] }

func (inst DelegateStake) Build() *Instruction {
return &Instruction{BaseVariant: bin.BaseVariant{
Impl: inst,
TypeID: bin.TypeIDFromUint32(Instruction_DelegateStake, bin.LE),
}}
}

func (inst *DelegateStake) EncodeToTree(parent treeout.Branches) {
parent.Child(format.Program(ProgramName, ProgramID)).
//
ParentFunc(func(programBranch treeout.Branches) {
programBranch.Child(format.Instruction("DelegateStake")).
//
ParentFunc(func(instructionBranch treeout.Branches) {
// Parameters of the instruction:
instructionBranch.Child("Params").ParentFunc(func(paramsBranch treeout.Branches) {
})

// Accounts of the instruction:
instructionBranch.Child("Accounts").ParentFunc(func(accountsBranch treeout.Branches) {
accountsBranch.Child(format.Meta(" StakeAccount", inst.AccountMetaSlice.Get(0)))
accountsBranch.Child(format.Meta(" VoteAccount", inst.AccountMetaSlice.Get(1)))
accountsBranch.Child(format.Meta(" ClockSysvar", inst.AccountMetaSlice.Get(2)))
accountsBranch.Child(format.Meta(" StakeHistorySysvar", inst.AccountMetaSlice.Get(3)))
accountsBranch.Child(format.Meta(" StakeConfigAccount", inst.AccountMetaSlice.Get(4)))
accountsBranch.Child(format.Meta(" StakeAuthoriy", inst.AccountMetaSlice.Get(5)))
})
})
})
}

// NewDelegateStakeInstructionBuilder creates a new `DelegateStake` instruction builder.
func NewDelegateStakeInstructionBuilder() *DelegateStake {
nd := &DelegateStake{
AccountMetaSlice: make(solana.AccountMetaSlice, 6),
}
return nd
}

// NewDelegateStakeInstruction declares a new DelegateStake instruction with the provided parameters and accounts.
func NewDelegateStakeInstruction(
// Accounts:
validatorVoteAccount solana.PublicKey,
stakeAuthority solana.PublicKey,
stakeAccount solana.PublicKey,
) *DelegateStake {
return NewDelegateStakeInstructionBuilder().
SetStakeAccount(stakeAccount).
SetVoteAccount(validatorVoteAccount).
SetClockSysvar(solana.SysVarClockPubkey).
SetStakeHistorySysvar(solana.SysVarStakeHistoryPubkey).
SetConfigAccount(solana.SysVarStakeConfigPubkey).
SetStakeAuthority(stakeAuthority)
}
Loading

0 comments on commit bea4b03

Please sign in to comment.