Upgrade bin package; use generated system program client.

This commit is contained in:
Slavomir 2021-08-31 16:27:21 +02:00
parent f4fb6389da
commit 3853032c9c
38 changed files with 2593 additions and 662 deletions

View File

@ -103,10 +103,24 @@ var tokenRegistryRegisterCmd = &cobra.Command{
tokenRegistryProgramID := tokenregistry.ProgramID()
createAccountInstruction := system.NewCreateAccountInstruction(uint64(lamport), tokenregistry.TOKEN_META_SIZE, tokenRegistryProgramID, registrarPubKey, tokenMetaAccount.PublicKey())
createAccountInstruction := system.NewCreateAccountInstruction(
lamport,
tokenregistry.TOKEN_META_SIZE,
tokenRegistryProgramID,
registrarPubKey,
tokenMetaAccount.PublicKey(),
).
Build()
registerTokenInstruction := tokenregistry.NewRegisterTokenInstruction(logo, name, symbol, website, tokenMetaAccount.PublicKey(), registrarPubKey, tokenAddress)
trx, err := solana.NewTransaction([]solana.Instruction{createAccountInstruction, registerTokenInstruction}, blockHashResult.Value.Blockhash, solana.TransactionPayer(registrarPubKey))
trx, err := solana.NewTransaction(
[]solana.Instruction{
createAccountInstruction,
registerTokenInstruction,
},
blockHashResult.Value.Blockhash,
solana.TransactionPayer(registrarPubKey),
)
if err != nil {
return fmt.Errorf("unable to craft transaction: %w", err)
}

7
go.mod
View File

@ -19,11 +19,11 @@ require (
github.com/fatih/color v1.7.0
github.com/gagliardetto/treeout v0.1.2
github.com/google/go-cmp v0.5.1
github.com/google/gofuzz v1.0.0
github.com/gorilla/rpc v1.2.0
github.com/gorilla/websocket v1.4.2
github.com/json-iterator/go v1.1.11
github.com/klauspost/compress v1.13.1
github.com/kr/pretty v0.2.1 // indirect
github.com/logrusorgru/aurora v2.0.3+incompatible
github.com/magiconair/properties v1.8.1
github.com/mr-tron/base58 v1.2.0
@ -47,7 +47,8 @@ require (
golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf // indirect
golang.org/x/tools v0.0.0-20200601175630-2caf76543d99 // indirect
google.golang.org/api v0.29.0
gopkg.in/yaml.v2 v2.4.0 // indirect
)
replace github.com/dfuse-io/binary => github.com/gagliardetto/binary v0.3.0
replace github.com/dfuse-io/binary => github.com/gagliardetto/binary v0.4.0
replace github.com/google/gofuzz => github.com/gagliardetto/gofuzz v1.2.1

8
go.sum
View File

@ -87,8 +87,10 @@ github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/gagliardetto/binary v0.3.0 h1:SN0+zufFFc5CFYl5T0/wRuUOjx2YkhqKbx82WuSmSL4=
github.com/gagliardetto/binary v0.3.0/go.mod h1:GDFX6qH3BQZPWTeYaA4ZW98T94zs2skRoG3oMz/0jw0=
github.com/gagliardetto/binary v0.4.0 h1:dxLndYArHtdZYbLYwnpLY86mlAa9gWgxG2zSDPFINjM=
github.com/gagliardetto/binary v0.4.0/go.mod h1:55fxN6CKhVnsBhSr3Hmyn7i2igseIzN9/NC+gHvv42k=
github.com/gagliardetto/gofuzz v1.2.1 h1:fHBiDgCYYb8kBRqyI+bhU59/IKATHArFUAY3iVUrdPA=
github.com/gagliardetto/gofuzz v1.2.1/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/gagliardetto/treeout v0.1.2 h1:WXO7LDJTwINO37OQfNlf7s095Z1bAiwN2ACaZQic33Q=
github.com/gagliardetto/treeout v0.1.2/go.mod h1:loUefvXTrlRG5rYmJmExNryyBRh8f89VZhmMOyCyqok=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
@ -134,7 +136,6 @@ github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.1 h1:JFrFEBb2xKufg6XkJsJr+WbKb4FQlURi5RUcBveYu9k=
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
@ -494,6 +495,7 @@ golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtn
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191216052735-49a3e744a425/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=

View File

@ -82,7 +82,7 @@ func (i *Instruction) MarshalWithEncoder(encoder *bin.Encoder) error {
return fmt.Errorf("unable to write instruction version: %w", err)
}
err = encoder.WriteUint32(i.TypeID, binary.LittleEndian)
err = encoder.WriteUint32(i.TypeID.Uint32(), binary.LittleEndian)
if err != nil {
return fmt.Errorf("unable to write variant type: %w", err)
}

View File

@ -1,6 +1,7 @@
package serum
import (
"encoding/binary"
"encoding/hex"
"testing"
@ -20,7 +21,7 @@ func TestDecodeInstruction(t *testing.T) {
hexData: "000900000001000000b80600000000000010eb09000000000000000000168106e091da511601000000",
expectInstruction: &Instruction{
BaseVariant: bin.BaseVariant{
TypeID: 9,
TypeID: bin.TypeIDFromUint32(9, binary.LittleEndian),
Impl: &InstructionNewOrderV2{
Side: SideAsk,
LimitPrice: 1720,
@ -38,7 +39,7 @@ func TestDecodeInstruction(t *testing.T) {
hexData: "0002000000ffff",
expectInstruction: &Instruction{
BaseVariant: bin.BaseVariant{
TypeID: 2,
TypeID: bin.TypeIDFromUint32(2, binary.LittleEndian),
Impl: &InstructionMatchOrder{
Limit: 65535,
},
@ -51,7 +52,7 @@ func TestDecodeInstruction(t *testing.T) {
hexData: "0005000000",
expectInstruction: &Instruction{
BaseVariant: bin.BaseVariant{
TypeID: 5,
TypeID: bin.TypeIDFromUint32(5, binary.LittleEndian),
Impl: &InstructionSettleFunds{},
},
Version: 0,

View File

@ -167,7 +167,7 @@ func (s *Slab) UnmarshalWithDecoder(decoder *bin.Decoder) error {
}
func (s *Slab) MarshalWithEncoder(encoder *bin.Encoder) error {
err := encoder.WriteUint32(s.TypeID, binary.LittleEndian)
err := encoder.WriteUint32(s.TypeID.Uint32(), binary.LittleEndian)
if err != nil {
return err
}

View File

@ -2,6 +2,7 @@ package serum
import (
"encoding/base64"
"encoding/binary"
"encoding/hex"
"fmt"
"io/ioutil"
@ -89,7 +90,7 @@ func TestDecoder_Orderbook(t *testing.T) {
assert.Equal(t, 101, len(ob.Nodes))
assert.Equal(t, &Slab{
BaseVariant: bin.BaseVariant{
TypeID: 1,
TypeID: bin.TypeIDFromUint32(1, binary.LittleEndian),
Impl: &SlabInnerNode{
PrefixLen: 57,
Key: bin.Uint128{
@ -108,7 +109,7 @@ func TestDecoder_Orderbook(t *testing.T) {
}, ob.Nodes[0])
assert.Equal(t, &Slab{
BaseVariant: bin.BaseVariant{
TypeID: 3,
TypeID: bin.TypeIDFromUint32(3, binary.LittleEndian),
Impl: &SlabFreeNode{
Next: 2,
Padding: [64]byte{
@ -125,7 +126,7 @@ func TestDecoder_Orderbook(t *testing.T) {
}, ob.Nodes[1])
assert.Equal(t, &Slab{
BaseVariant: bin.BaseVariant{
TypeID: 2,
TypeID: bin.TypeIDFromUint32(2, binary.LittleEndian),
Impl: &SlabLeafNode{
OwnerSlot: 1,
FeeTier: 5,
@ -154,7 +155,7 @@ func TestDecoder_Slabs(t *testing.T) {
slabData: "0100000035000000010babffffffffff4105000000000000400000003f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
expectSlab: &Slab{
BaseVariant: bin.BaseVariant{
TypeID: 1,
TypeID: bin.TypeIDFromUint32(1, binary.LittleEndian),
Impl: &SlabInnerNode{
PrefixLen: 53,
Key: bin.Uint128{
@ -175,7 +176,7 @@ func TestDecoder_Slabs(t *testing.T) {
slabData: "0200000014060000b2cea5ffffffffff23070000000000005ae01b52d00a090c6dc6fce8e37a225815cff2223a99c6dfdad5aae56d3db670e62c000000000000140b0fadcf8fcebf",
expectSlab: &Slab{
BaseVariant: bin.BaseVariant{
TypeID: 2,
TypeID: bin.TypeIDFromUint32(2, binary.LittleEndian),
Impl: &SlabLeafNode{
OwnerSlot: 20,
FeeTier: 6,
@ -196,7 +197,7 @@ func TestDecoder_Slabs(t *testing.T) {
slabData: "030000003400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
expectSlab: &Slab{
BaseVariant: bin.BaseVariant{
TypeID: 3,
TypeID: bin.TypeIDFromUint32(3, binary.LittleEndian),
Impl: &SlabFreeNode{
Next: 52,
},

View File

@ -1,81 +1,131 @@
package system
import (
"encoding/binary"
"fmt"
bin "github.com/dfuse-io/binary"
solana "github.com/gagliardetto/solana-go"
ag_binary "github.com/dfuse-io/binary"
ag_solanago "github.com/gagliardetto/solana-go"
ag_format "github.com/gagliardetto/solana-go/text/format"
ag_treeout "github.com/gagliardetto/treeout"
)
func NewAdvanceNonceAccountInstruction(
nonceAccount solana.PublicKey,
nonceAuthority solana.PublicKey,
) *Instruction {
return NewAdvanceNonceAccountBuilder().
WithNonceAccount(nonceAccount).
WithNonceAuthority(nonceAuthority).
Build()
}
// Consumes a stored nonce, replacing it with a successor.
// Consumes a stored nonce, replacing it with a successor
type AdvanceNonceAccount struct {
// [0] = [WRITE] Nonce account.
// [1] = [] RecentBlockhashes sysvar.
// [2] = [SIGNER] Nonce authority.
solana.AccountMetaSlice `bin:"-"`
// [0] = [WRITE] NonceAccount
// ··········· Nonce account
//
// [1] = [] $(SysVarRecentBlockHashesPubkey)
// ··········· RecentBlockhashes sysvar
//
// [2] = [SIGNER] NonceAuthorityAccount
// ··········· Nonce authority
ag_solanago.AccountMetaSlice `bin:"-" borsh_skip:"true"`
}
// NewAdvanceNonceAccountBuilder initializes a new AdvanceNonceAccount builder.
func NewAdvanceNonceAccountBuilder() *AdvanceNonceAccount {
nb := &AdvanceNonceAccount{
AccountMetaSlice: make(solana.AccountMetaSlice, 3),
// NewAdvanceNonceAccountInstructionBuilder creates a new `AdvanceNonceAccount` instruction builder.
func NewAdvanceNonceAccountInstructionBuilder() *AdvanceNonceAccount {
nd := &AdvanceNonceAccount{
AccountMetaSlice: make(ag_solanago.AccountMetaSlice, 3),
}
nb.AccountMetaSlice[1] = solana.Meta(solana.SysVarRecentBlockHashesPubkey)
return nb
nd.AccountMetaSlice[1] = ag_solanago.Meta(ag_solanago.SysVarRecentBlockHashesPubkey)
return nd
}
func (ins *AdvanceNonceAccount) WithNonceAccount(nonceAccount solana.PublicKey) *AdvanceNonceAccount {
ins.AccountMetaSlice[0] = solana.Meta(nonceAccount).WRITE()
return ins
// Nonce account
func (inst *AdvanceNonceAccount) SetNonceAccount(nonceAccount ag_solanago.PublicKey) *AdvanceNonceAccount {
inst.AccountMetaSlice[0] = ag_solanago.Meta(nonceAccount).WRITE()
return inst
}
func (ins *AdvanceNonceAccount) GetNonceAccount() *solana.PublicKey {
ac := ins.AccountMetaSlice[0]
if ac == nil {
return nil
}
return &ac.PublicKey
func (inst *AdvanceNonceAccount) GetNonceAccount() *ag_solanago.AccountMeta {
return inst.AccountMetaSlice[0]
}
func (ins *AdvanceNonceAccount) WithNonceAuthority(nonceAuthority solana.PublicKey) *AdvanceNonceAccount {
ins.AccountMetaSlice[2] = solana.Meta(nonceAuthority).SIGNER()
return ins
// RecentBlockhashes sysvar
func (inst *AdvanceNonceAccount) SetSysVarRecentBlockHashesPubkeyAccount(SysVarRecentBlockHashesPubkey ag_solanago.PublicKey) *AdvanceNonceAccount {
inst.AccountMetaSlice[1] = ag_solanago.Meta(SysVarRecentBlockHashesPubkey)
return inst
}
func (ins *AdvanceNonceAccount) GetNonceAuthority() *solana.PublicKey {
ac := ins.AccountMetaSlice[2]
if ac == nil {
return nil
}
return &ac.PublicKey
func (inst *AdvanceNonceAccount) GetSysVarRecentBlockHashesPubkeyAccount() *ag_solanago.AccountMeta {
return inst.AccountMetaSlice[1]
}
func (ins *AdvanceNonceAccount) Validate() error {
for accIndex, acc := range ins.AccountMetaSlice {
// Nonce authority
func (inst *AdvanceNonceAccount) SetNonceAuthorityAccount(nonceAuthorityAccount ag_solanago.PublicKey) *AdvanceNonceAccount {
inst.AccountMetaSlice[2] = ag_solanago.Meta(nonceAuthorityAccount).SIGNER()
return inst
}
func (inst *AdvanceNonceAccount) GetNonceAuthorityAccount() *ag_solanago.AccountMeta {
return inst.AccountMetaSlice[2]
}
func (inst AdvanceNonceAccount) Build() *Instruction {
return &Instruction{BaseVariant: ag_binary.BaseVariant{
Impl: inst,
TypeID: ag_binary.TypeIDFromUint32(Instruction_AdvanceNonceAccount, binary.LittleEndian),
}}
}
// ValidateAndBuild validates the instruction parameters and accounts;
// if there is a validation error, it returns the error.
// Otherwise, it builds and returns the instruction.
func (inst AdvanceNonceAccount) ValidateAndBuild() (*Instruction, error) {
if err := inst.Validate(); err != nil {
return nil, err
}
return inst.Build(), nil
}
func (inst *AdvanceNonceAccount) Validate() error {
// Check whether all accounts are set:
for accIndex, acc := range inst.AccountMetaSlice {
if acc == nil {
return fmt.Errorf("ins.AccountMetaSlice[%v] is nil", accIndex)
return fmt.Errorf("ins.AccountMetaSlice[%v] is not set", accIndex)
}
}
return nil
}
func (ins *AdvanceNonceAccount) Build() *Instruction {
return &Instruction{
BaseVariant: bin.BaseVariant{
func (inst *AdvanceNonceAccount) EncodeToTree(parent ag_treeout.Branches) {
parent.Child(ag_format.Program(ProgramName, ProgramID)).
//
ParentFunc(func(programBranch ag_treeout.Branches) {
programBranch.Child(ag_format.Instruction("AdvanceNonceAccount")).
//
ParentFunc(func(instructionBranch ag_treeout.Branches) {
TypeID: Instruction_AdvanceNonceAccount,
// Parameters of the instruction:
instructionBranch.Child("Params").ParentFunc(func(paramsBranch ag_treeout.Branches) {})
Impl: ins,
},
// Accounts of the instruction:
instructionBranch.Child("Accounts").ParentFunc(func(accountsBranch ag_treeout.Branches) {
accountsBranch.Child(ag_format.Meta("NonceAccount", inst.AccountMetaSlice[0]))
accountsBranch.Child(ag_format.Meta("$(SysVarRecentBlockHashesPubkey)", inst.AccountMetaSlice[1]))
accountsBranch.Child(ag_format.Meta("NonceAuthorityAccount", inst.AccountMetaSlice[2]))
})
})
})
}
func (inst AdvanceNonceAccount) MarshalWithEncoder(encoder *ag_binary.Encoder) error {
return nil
}
func (inst *AdvanceNonceAccount) UnmarshalWithDecoder(decoder *ag_binary.Decoder) error {
return nil
}
// NewAdvanceNonceAccountInstruction declares a new AdvanceNonceAccount instruction with the provided parameters and accounts.
func NewAdvanceNonceAccountInstruction(
// Accounts:
nonceAccount ag_solanago.PublicKey,
SysVarRecentBlockHashesPubkey ag_solanago.PublicKey,
nonceAuthorityAccount ag_solanago.PublicKey) *AdvanceNonceAccount {
return NewAdvanceNonceAccountInstructionBuilder().
SetNonceAccount(nonceAccount).
SetSysVarRecentBlockHashesPubkeyAccount(SysVarRecentBlockHashesPubkey).
SetNonceAuthorityAccount(nonceAuthorityAccount)
}

View File

@ -0,0 +1,31 @@
package system
import (
"bytes"
ag_gofuzz "github.com/google/gofuzz"
ag_require "github.com/stretchr/testify/require"
"strconv"
"testing"
)
func TestEncodeDecode_AdvanceNonceAccount(t *testing.T) {
fu := ag_gofuzz.New().NilChance(0)
for i := 0; i < 1; i++ {
t.Run("AdvanceNonceAccount"+strconv.Itoa(i), func(t *testing.T) {
{
params := new(AdvanceNonceAccount)
fu.Fuzz(params)
params.AccountMetaSlice = nil
buf := new(bytes.Buffer)
err := encodeT(*params, buf)
ag_require.NoError(t, err)
//
got := new(AdvanceNonceAccount)
err = decodeT(got, buf.Bytes())
got.AccountMetaSlice = nil
ag_require.NoError(t, err)
ag_require.Equal(t, params, got)
}
})
}
}

View File

@ -1,33 +1,133 @@
package system
import (
bin "github.com/dfuse-io/binary"
solana "github.com/gagliardetto/solana-go"
"encoding/binary"
"errors"
"fmt"
ag_binary "github.com/dfuse-io/binary"
ag_solanago "github.com/gagliardetto/solana-go"
ag_format "github.com/gagliardetto/solana-go/text/format"
ag_treeout "github.com/gagliardetto/treeout"
)
func NewAllocateInstruction(
space uint64,
accountPubKey solana.PublicKey,
) *Instruction {
return &Instruction{
BaseVariant: bin.BaseVariant{
TypeID: Instruction_Allocate,
Impl: &Allocate{
Space: bin.Uint64(space),
AccountMetaSlice: []*solana.AccountMeta{
solana.Meta(accountPubKey).WRITE().SIGNER(),
},
},
},
}
}
// Allocate space in a (possibly new) account without funding
type Allocate struct {
// Number of bytes of memory to allocate.
Space bin.Uint64
// Number of bytes of memory to allocate
Space *uint64
// [0] = [WRITE, SIGNER] New account.
solana.AccountMetaSlice `bin:"-"`
// [0] = [WRITE, SIGNER] NewAccount
// ··········· New account
ag_solanago.AccountMetaSlice `bin:"-" borsh_skip:"true"`
}
// NewAllocateInstructionBuilder creates a new `Allocate` instruction builder.
func NewAllocateInstructionBuilder() *Allocate {
nd := &Allocate{
AccountMetaSlice: make(ag_solanago.AccountMetaSlice, 1),
}
return nd
}
// Number of bytes of memory to allocate
func (inst *Allocate) SetSpace(space uint64) *Allocate {
inst.Space = &space
return inst
}
// New account
func (inst *Allocate) SetNewAccount(newAccount ag_solanago.PublicKey) *Allocate {
inst.AccountMetaSlice[0] = ag_solanago.Meta(newAccount).WRITE().SIGNER()
return inst
}
func (inst *Allocate) GetNewAccount() *ag_solanago.AccountMeta {
return inst.AccountMetaSlice[0]
}
func (inst Allocate) Build() *Instruction {
return &Instruction{BaseVariant: ag_binary.BaseVariant{
Impl: inst,
TypeID: ag_binary.TypeIDFromUint32(Instruction_Allocate, binary.LittleEndian),
}}
}
// ValidateAndBuild validates the instruction parameters and accounts;
// if there is a validation error, it returns the error.
// Otherwise, it builds and returns the instruction.
func (inst Allocate) ValidateAndBuild() (*Instruction, error) {
if err := inst.Validate(); err != nil {
return nil, err
}
return inst.Build(), nil
}
func (inst *Allocate) Validate() error {
// Check whether all (required) parameters are set:
{
if inst.Space == nil {
return errors.New("Space parameter is not set")
}
}
// 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 *Allocate) EncodeToTree(parent ag_treeout.Branches) {
parent.Child(ag_format.Program(ProgramName, ProgramID)).
//
ParentFunc(func(programBranch ag_treeout.Branches) {
programBranch.Child(ag_format.Instruction("Allocate")).
//
ParentFunc(func(instructionBranch ag_treeout.Branches) {
// Parameters of the instruction:
instructionBranch.Child("Params").ParentFunc(func(paramsBranch ag_treeout.Branches) {
paramsBranch.Child(ag_format.Param("Space", *inst.Space))
})
// Accounts of the instruction:
instructionBranch.Child("Accounts").ParentFunc(func(accountsBranch ag_treeout.Branches) {
accountsBranch.Child(ag_format.Meta("NewAccount", inst.AccountMetaSlice[0]))
})
})
})
}
func (inst Allocate) MarshalWithEncoder(encoder *ag_binary.Encoder) error {
// Serialize `Space` param:
{
err := encoder.Encode(*inst.Space)
if err != nil {
return err
}
}
return nil
}
func (inst *Allocate) UnmarshalWithDecoder(decoder *ag_binary.Decoder) error {
// Deserialize `Space` param:
{
err := decoder.Decode(&inst.Space)
if err != nil {
return err
}
}
return nil
}
// NewAllocateInstruction declares a new Allocate instruction with the provided parameters and accounts.
func NewAllocateInstruction(
// Parameters:
space uint64,
// Accounts:
newAccount ag_solanago.PublicKey) *Allocate {
return NewAllocateInstructionBuilder().
SetSpace(space).
SetNewAccount(newAccount)
}

View File

@ -1,45 +1,236 @@
package system
import (
bin "github.com/dfuse-io/binary"
solana "github.com/gagliardetto/solana-go"
"encoding/binary"
"errors"
"fmt"
ag_binary "github.com/dfuse-io/binary"
ag_solanago "github.com/gagliardetto/solana-go"
ag_format "github.com/gagliardetto/solana-go/text/format"
ag_treeout "github.com/gagliardetto/treeout"
)
// Allocate space for and assign an account at an address derived from a base public key and a seed
type AllocateWithSeed struct {
// Base public key
Base *ag_solanago.PublicKey
// String of ASCII chars, no longer than pubkey::MAX_SEED_LEN
Seed *string
// Number of bytes of memory to allocate
Space *uint64
// Owner program account address
Owner *ag_solanago.PublicKey
// [0] = [WRITE] AllocatedAccount
// ··········· Allocated account
//
// [1] = [SIGNER] BaseAccount
// ··········· Base account
ag_solanago.AccountMetaSlice `bin:"-" borsh_skip:"true"`
}
// NewAllocateWithSeedInstructionBuilder creates a new `AllocateWithSeed` instruction builder.
func NewAllocateWithSeedInstructionBuilder() *AllocateWithSeed {
nd := &AllocateWithSeed{
AccountMetaSlice: make(ag_solanago.AccountMetaSlice, 2),
}
return nd
}
// Base public key
func (inst *AllocateWithSeed) SetBase(base ag_solanago.PublicKey) *AllocateWithSeed {
inst.Base = &base
return inst
}
// String of ASCII chars, no longer than pubkey::MAX_SEED_LEN
func (inst *AllocateWithSeed) SetSeed(seed string) *AllocateWithSeed {
inst.Seed = &seed
return inst
}
// Number of bytes of memory to allocate
func (inst *AllocateWithSeed) SetSpace(space uint64) *AllocateWithSeed {
inst.Space = &space
return inst
}
// Owner program account address
func (inst *AllocateWithSeed) SetOwner(owner ag_solanago.PublicKey) *AllocateWithSeed {
inst.Owner = &owner
return inst
}
// Allocated account
func (inst *AllocateWithSeed) SetAllocatedAccount(allocatedAccount ag_solanago.PublicKey) *AllocateWithSeed {
inst.AccountMetaSlice[0] = ag_solanago.Meta(allocatedAccount).WRITE()
return inst
}
func (inst *AllocateWithSeed) GetAllocatedAccount() *ag_solanago.AccountMeta {
return inst.AccountMetaSlice[0]
}
// Base account
func (inst *AllocateWithSeed) SetBaseAccount(baseAccount ag_solanago.PublicKey) *AllocateWithSeed {
inst.AccountMetaSlice[1] = ag_solanago.Meta(baseAccount).SIGNER()
return inst
}
func (inst *AllocateWithSeed) GetBaseAccount() *ag_solanago.AccountMeta {
return inst.AccountMetaSlice[1]
}
func (inst AllocateWithSeed) Build() *Instruction {
return &Instruction{BaseVariant: ag_binary.BaseVariant{
Impl: inst,
TypeID: ag_binary.TypeIDFromUint32(Instruction_AllocateWithSeed, binary.LittleEndian),
}}
}
// ValidateAndBuild validates the instruction parameters and accounts;
// if there is a validation error, it returns the error.
// Otherwise, it builds and returns the instruction.
func (inst AllocateWithSeed) ValidateAndBuild() (*Instruction, error) {
if err := inst.Validate(); err != nil {
return nil, err
}
return inst.Build(), nil
}
func (inst *AllocateWithSeed) Validate() error {
// Check whether all (required) parameters are set:
{
if inst.Base == nil {
return errors.New("Base parameter is not set")
}
if inst.Seed == nil {
return errors.New("Seed parameter is not set")
}
if inst.Space == nil {
return errors.New("Space parameter is not set")
}
if inst.Owner == nil {
return errors.New("Owner parameter is not set")
}
}
// 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 *AllocateWithSeed) EncodeToTree(parent ag_treeout.Branches) {
parent.Child(ag_format.Program(ProgramName, ProgramID)).
//
ParentFunc(func(programBranch ag_treeout.Branches) {
programBranch.Child(ag_format.Instruction("AllocateWithSeed")).
//
ParentFunc(func(instructionBranch ag_treeout.Branches) {
// Parameters of the instruction:
instructionBranch.Child("Params").ParentFunc(func(paramsBranch ag_treeout.Branches) {
paramsBranch.Child(ag_format.Param("Base", *inst.Base))
paramsBranch.Child(ag_format.Param("Seed", *inst.Seed))
paramsBranch.Child(ag_format.Param("Space", *inst.Space))
paramsBranch.Child(ag_format.Param("Owner", *inst.Owner))
})
// Accounts of the instruction:
instructionBranch.Child("Accounts").ParentFunc(func(accountsBranch ag_treeout.Branches) {
accountsBranch.Child(ag_format.Meta("AllocatedAccount", inst.AccountMetaSlice[0]))
accountsBranch.Child(ag_format.Meta("BaseAccount", inst.AccountMetaSlice[1]))
})
})
})
}
func (inst AllocateWithSeed) MarshalWithEncoder(encoder *ag_binary.Encoder) error {
// Serialize `Base` param:
{
err := encoder.Encode(*inst.Base)
if err != nil {
return err
}
}
// Serialize `Seed` param:
{
err := encoder.Encode(*inst.Seed)
if err != nil {
return err
}
}
// Serialize `Space` param:
{
err := encoder.Encode(*inst.Space)
if err != nil {
return err
}
}
// Serialize `Owner` param:
{
err := encoder.Encode(*inst.Owner)
if err != nil {
return err
}
}
return nil
}
func (inst *AllocateWithSeed) UnmarshalWithDecoder(decoder *ag_binary.Decoder) error {
// Deserialize `Base` param:
{
err := decoder.Decode(&inst.Base)
if err != nil {
return err
}
}
// Deserialize `Seed` param:
{
err := decoder.Decode(&inst.Seed)
if err != nil {
return err
}
}
// Deserialize `Space` param:
{
err := decoder.Decode(&inst.Space)
if err != nil {
return err
}
}
// Deserialize `Owner` param:
{
err := decoder.Decode(&inst.Owner)
if err != nil {
return err
}
}
return nil
}
// NewAllocateWithSeedInstruction declares a new AllocateWithSeed instruction with the provided parameters and accounts.
func NewAllocateWithSeedInstruction(
accountPubKey solana.PublicKey,
basePubKey solana.PublicKey,
// Parameters:
base ag_solanago.PublicKey,
seed string,
space uint64,
owner solana.PublicKey,
) *Instruction {
return &Instruction{
BaseVariant: bin.BaseVariant{
TypeID: Instruction_AllocateWithSeed,
Impl: &AllocateWithSeed{
Base: basePubKey,
Seed: seed,
Space: bin.Uint64(space),
Owner: owner,
AccountMetaSlice: []*solana.AccountMeta{
solana.Meta(accountPubKey).WRITE(),
solana.Meta(basePubKey).SIGNER(),
},
},
},
}
}
type AllocateWithSeed struct {
Base solana.PublicKey
SeedSize int `bin:"sizeof=Seed"`
Seed string
Space bin.Uint64
Owner solana.PublicKey
// [0] = [WRITE] Allocated account.
// [1] = [SIGNER] Base account.
solana.AccountMetaSlice `bin:"-"`
owner ag_solanago.PublicKey,
// Accounts:
allocatedAccount ag_solanago.PublicKey,
baseAccount ag_solanago.PublicKey) *AllocateWithSeed {
return NewAllocateWithSeedInstructionBuilder().
SetBase(base).
SetSeed(seed).
SetSpace(space).
SetOwner(owner).
SetAllocatedAccount(allocatedAccount).
SetBaseAccount(baseAccount)
}

View File

@ -0,0 +1,31 @@
package system
import (
"bytes"
ag_gofuzz "github.com/google/gofuzz"
ag_require "github.com/stretchr/testify/require"
"strconv"
"testing"
)
func TestEncodeDecode_AllocateWithSeed(t *testing.T) {
fu := ag_gofuzz.New().NilChance(0)
for i := 0; i < 1; i++ {
t.Run("AllocateWithSeed"+strconv.Itoa(i), func(t *testing.T) {
{
params := new(AllocateWithSeed)
fu.Fuzz(params)
params.AccountMetaSlice = nil
buf := new(bytes.Buffer)
err := encodeT(*params, buf)
ag_require.NoError(t, err)
//
got := new(AllocateWithSeed)
err = decodeT(got, buf.Bytes())
got.AccountMetaSlice = nil
ag_require.NoError(t, err)
ag_require.Equal(t, params, got)
}
})
}
}

View File

@ -0,0 +1,31 @@
package system
import (
"bytes"
ag_gofuzz "github.com/google/gofuzz"
ag_require "github.com/stretchr/testify/require"
"strconv"
"testing"
)
func TestEncodeDecode_Allocate(t *testing.T) {
fu := ag_gofuzz.New().NilChance(0)
for i := 0; i < 1; i++ {
t.Run("Allocate"+strconv.Itoa(i), func(t *testing.T) {
{
params := new(Allocate)
fu.Fuzz(params)
params.AccountMetaSlice = nil
buf := new(bytes.Buffer)
err := encodeT(*params, buf)
ag_require.NoError(t, err)
//
got := new(Allocate)
err = decodeT(got, buf.Bytes())
got.AccountMetaSlice = nil
ag_require.NoError(t, err)
ag_require.Equal(t, params, got)
}
})
}
}

View File

@ -1,37 +1,133 @@
package system
import (
bin "github.com/dfuse-io/binary"
solana "github.com/gagliardetto/solana-go"
"encoding/binary"
"errors"
"fmt"
ag_binary "github.com/dfuse-io/binary"
ag_solanago "github.com/gagliardetto/solana-go"
ag_format "github.com/gagliardetto/solana-go/text/format"
ag_treeout "github.com/gagliardetto/treeout"
)
func NewAssignInstruction(
// The account that is being assigned.
accountPubkey solana.PublicKey,
// The program that is becoming the new owner of the account.
assignToProgramID solana.PublicKey,
) *Instruction {
return &Instruction{
BaseVariant: bin.BaseVariant{
TypeID: Instruction_Assign,
Impl: &Assign{
NewOwner: assignToProgramID,
AccountMetaSlice: []*solana.AccountMeta{
solana.Meta(accountPubkey).WRITE().SIGNER(),
},
},
},
}
}
// Assign account to a program
type Assign struct {
// Owner program account.
NewOwner solana.PublicKey
// Owner program account
Owner *ag_solanago.PublicKey
// [0] = [WRITE, SIGNER] Assigned account public key.
solana.AccountMetaSlice `bin:"-"`
// [0] = [WRITE, SIGNER] AssignedAccount
// ··········· Assigned account public key
ag_solanago.AccountMetaSlice `bin:"-" borsh_skip:"true"`
}
// NewAssignInstructionBuilder creates a new `Assign` instruction builder.
func NewAssignInstructionBuilder() *Assign {
nd := &Assign{
AccountMetaSlice: make(ag_solanago.AccountMetaSlice, 1),
}
return nd
}
// Owner program account
func (inst *Assign) SetOwner(owner ag_solanago.PublicKey) *Assign {
inst.Owner = &owner
return inst
}
// Assigned account public key
func (inst *Assign) SetAssignedAccount(assignedAccount ag_solanago.PublicKey) *Assign {
inst.AccountMetaSlice[0] = ag_solanago.Meta(assignedAccount).WRITE().SIGNER()
return inst
}
func (inst *Assign) GetAssignedAccount() *ag_solanago.AccountMeta {
return inst.AccountMetaSlice[0]
}
func (inst Assign) Build() *Instruction {
return &Instruction{BaseVariant: ag_binary.BaseVariant{
Impl: inst,
TypeID: ag_binary.TypeIDFromUint32(Instruction_Assign, binary.LittleEndian),
}}
}
// ValidateAndBuild validates the instruction parameters and accounts;
// if there is a validation error, it returns the error.
// Otherwise, it builds and returns the instruction.
func (inst Assign) ValidateAndBuild() (*Instruction, error) {
if err := inst.Validate(); err != nil {
return nil, err
}
return inst.Build(), nil
}
func (inst *Assign) Validate() error {
// Check whether all (required) parameters are set:
{
if inst.Owner == nil {
return errors.New("Owner parameter is not set")
}
}
// 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 *Assign) EncodeToTree(parent ag_treeout.Branches) {
parent.Child(ag_format.Program(ProgramName, ProgramID)).
//
ParentFunc(func(programBranch ag_treeout.Branches) {
programBranch.Child(ag_format.Instruction("Assign")).
//
ParentFunc(func(instructionBranch ag_treeout.Branches) {
// Parameters of the instruction:
instructionBranch.Child("Params").ParentFunc(func(paramsBranch ag_treeout.Branches) {
paramsBranch.Child(ag_format.Param("Owner", *inst.Owner))
})
// Accounts of the instruction:
instructionBranch.Child("Accounts").ParentFunc(func(accountsBranch ag_treeout.Branches) {
accountsBranch.Child(ag_format.Meta("AssignedAccount", inst.AccountMetaSlice[0]))
})
})
})
}
func (inst Assign) MarshalWithEncoder(encoder *ag_binary.Encoder) error {
// Serialize `Owner` param:
{
err := encoder.Encode(*inst.Owner)
if err != nil {
return err
}
}
return nil
}
func (inst *Assign) UnmarshalWithDecoder(decoder *ag_binary.Decoder) error {
// Deserialize `Owner` param:
{
err := decoder.Decode(&inst.Owner)
if err != nil {
return err
}
}
return nil
}
// NewAssignInstruction declares a new Assign instruction with the provided parameters and accounts.
func NewAssignInstruction(
// Parameters:
owner ag_solanago.PublicKey,
// Accounts:
assignedAccount ag_solanago.PublicKey) *Assign {
return NewAssignInstructionBuilder().
SetOwner(owner).
SetAssignedAccount(assignedAccount)
}

View File

@ -1,42 +1,207 @@
package system
import (
bin "github.com/dfuse-io/binary"
solana "github.com/gagliardetto/solana-go"
"encoding/binary"
"errors"
"fmt"
ag_binary "github.com/dfuse-io/binary"
ag_solanago "github.com/gagliardetto/solana-go"
ag_format "github.com/gagliardetto/solana-go/text/format"
ag_treeout "github.com/gagliardetto/treeout"
)
func NewAssignWithSeedInstruction(
accountPubKey solana.PublicKey,
basePubKey solana.PublicKey,
seed string,
owner solana.PublicKey,
) *Instruction {
return &Instruction{
BaseVariant: bin.BaseVariant{
TypeID: Instruction_AssignWithSeed,
Impl: &AssignWithSeed{
Base: basePubKey,
Seed: seed,
Owner: owner,
AccountMetaSlice: []*solana.AccountMeta{
solana.Meta(accountPubKey).WRITE(),
solana.Meta(basePubKey).SIGNER(),
},
},
},
}
}
// Assign account to a program based on a seed
type AssignWithSeed struct {
Base solana.PublicKey
SeedSize int `bin:"sizeof=Seed"`
Seed string
Owner solana.PublicKey
// Base public key
Base *ag_solanago.PublicKey
// [0] = [WRITE] Assigned account.
// [1] = [SIGNER] Base account.
solana.AccountMetaSlice `bin:"-"`
// String of ASCII chars, no longer than pubkey::MAX_SEED_LEN
Seed *string
// Owner program account
Owner *ag_solanago.PublicKey
// [0] = [WRITE] AssignedAccount
// ··········· Assigned account
//
// [1] = [SIGNER] BaseAccount
// ··········· Base account
ag_solanago.AccountMetaSlice `bin:"-" borsh_skip:"true"`
}
// NewAssignWithSeedInstructionBuilder creates a new `AssignWithSeed` instruction builder.
func NewAssignWithSeedInstructionBuilder() *AssignWithSeed {
nd := &AssignWithSeed{
AccountMetaSlice: make(ag_solanago.AccountMetaSlice, 2),
}
return nd
}
// Base public key
func (inst *AssignWithSeed) SetBase(base ag_solanago.PublicKey) *AssignWithSeed {
inst.Base = &base
return inst
}
// String of ASCII chars, no longer than pubkey::MAX_SEED_LEN
func (inst *AssignWithSeed) SetSeed(seed string) *AssignWithSeed {
inst.Seed = &seed
return inst
}
// Owner program account
func (inst *AssignWithSeed) SetOwner(owner ag_solanago.PublicKey) *AssignWithSeed {
inst.Owner = &owner
return inst
}
// Assigned account
func (inst *AssignWithSeed) SetAssignedAccount(assignedAccount ag_solanago.PublicKey) *AssignWithSeed {
inst.AccountMetaSlice[0] = ag_solanago.Meta(assignedAccount).WRITE()
return inst
}
func (inst *AssignWithSeed) GetAssignedAccount() *ag_solanago.AccountMeta {
return inst.AccountMetaSlice[0]
}
// Base account
func (inst *AssignWithSeed) SetBaseAccount(baseAccount ag_solanago.PublicKey) *AssignWithSeed {
inst.AccountMetaSlice[1] = ag_solanago.Meta(baseAccount).SIGNER()
return inst
}
func (inst *AssignWithSeed) GetBaseAccount() *ag_solanago.AccountMeta {
return inst.AccountMetaSlice[1]
}
func (inst AssignWithSeed) Build() *Instruction {
return &Instruction{BaseVariant: ag_binary.BaseVariant{
Impl: inst,
TypeID: ag_binary.TypeIDFromUint32(Instruction_AssignWithSeed, binary.LittleEndian),
}}
}
// ValidateAndBuild validates the instruction parameters and accounts;
// if there is a validation error, it returns the error.
// Otherwise, it builds and returns the instruction.
func (inst AssignWithSeed) ValidateAndBuild() (*Instruction, error) {
if err := inst.Validate(); err != nil {
return nil, err
}
return inst.Build(), nil
}
func (inst *AssignWithSeed) Validate() error {
// Check whether all (required) parameters are set:
{
if inst.Base == nil {
return errors.New("Base parameter is not set")
}
if inst.Seed == nil {
return errors.New("Seed parameter is not set")
}
if inst.Owner == nil {
return errors.New("Owner parameter is not set")
}
}
// 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 *AssignWithSeed) EncodeToTree(parent ag_treeout.Branches) {
parent.Child(ag_format.Program(ProgramName, ProgramID)).
//
ParentFunc(func(programBranch ag_treeout.Branches) {
programBranch.Child(ag_format.Instruction("AssignWithSeed")).
//
ParentFunc(func(instructionBranch ag_treeout.Branches) {
// Parameters of the instruction:
instructionBranch.Child("Params").ParentFunc(func(paramsBranch ag_treeout.Branches) {
paramsBranch.Child(ag_format.Param("Base", *inst.Base))
paramsBranch.Child(ag_format.Param("Seed", *inst.Seed))
paramsBranch.Child(ag_format.Param("Owner", *inst.Owner))
})
// Accounts of the instruction:
instructionBranch.Child("Accounts").ParentFunc(func(accountsBranch ag_treeout.Branches) {
accountsBranch.Child(ag_format.Meta("AssignedAccount", inst.AccountMetaSlice[0]))
accountsBranch.Child(ag_format.Meta("BaseAccount", inst.AccountMetaSlice[1]))
})
})
})
}
func (inst AssignWithSeed) MarshalWithEncoder(encoder *ag_binary.Encoder) error {
// Serialize `Base` param:
{
err := encoder.Encode(*inst.Base)
if err != nil {
return err
}
}
// Serialize `Seed` param:
{
err := encoder.Encode(*inst.Seed)
if err != nil {
return err
}
}
// Serialize `Owner` param:
{
err := encoder.Encode(*inst.Owner)
if err != nil {
return err
}
}
return nil
}
func (inst *AssignWithSeed) UnmarshalWithDecoder(decoder *ag_binary.Decoder) error {
// Deserialize `Base` param:
{
err := decoder.Decode(&inst.Base)
if err != nil {
return err
}
}
// Deserialize `Seed` param:
{
err := decoder.Decode(&inst.Seed)
if err != nil {
return err
}
}
// Deserialize `Owner` param:
{
err := decoder.Decode(&inst.Owner)
if err != nil {
return err
}
}
return nil
}
// NewAssignWithSeedInstruction declares a new AssignWithSeed instruction with the provided parameters and accounts.
func NewAssignWithSeedInstruction(
// Parameters:
base ag_solanago.PublicKey,
seed string,
owner ag_solanago.PublicKey,
// Accounts:
assignedAccount ag_solanago.PublicKey,
baseAccount ag_solanago.PublicKey) *AssignWithSeed {
return NewAssignWithSeedInstructionBuilder().
SetBase(base).
SetSeed(seed).
SetOwner(owner).
SetAssignedAccount(assignedAccount).
SetBaseAccount(baseAccount)
}

View File

@ -0,0 +1,31 @@
package system
import (
"bytes"
ag_gofuzz "github.com/google/gofuzz"
ag_require "github.com/stretchr/testify/require"
"strconv"
"testing"
)
func TestEncodeDecode_AssignWithSeed(t *testing.T) {
fu := ag_gofuzz.New().NilChance(0)
for i := 0; i < 1; i++ {
t.Run("AssignWithSeed"+strconv.Itoa(i), func(t *testing.T) {
{
params := new(AssignWithSeed)
fu.Fuzz(params)
params.AccountMetaSlice = nil
buf := new(bytes.Buffer)
err := encodeT(*params, buf)
ag_require.NoError(t, err)
//
got := new(AssignWithSeed)
err = decodeT(got, buf.Bytes())
got.AccountMetaSlice = nil
ag_require.NoError(t, err)
ag_require.Equal(t, params, got)
}
})
}
}

View File

@ -0,0 +1,31 @@
package system
import (
"bytes"
ag_gofuzz "github.com/google/gofuzz"
ag_require "github.com/stretchr/testify/require"
"strconv"
"testing"
)
func TestEncodeDecode_Assign(t *testing.T) {
fu := ag_gofuzz.New().NilChance(0)
for i := 0; i < 1; i++ {
t.Run("Assign"+strconv.Itoa(i), func(t *testing.T) {
{
params := new(Assign)
fu.Fuzz(params)
params.AccountMetaSlice = nil
buf := new(bytes.Buffer)
err := encodeT(*params, buf)
ag_require.NoError(t, err)
//
got := new(Assign)
err = decodeT(got, buf.Bytes())
got.AccountMetaSlice = nil
ag_require.NoError(t, err)
ag_require.Equal(t, params, got)
}
})
}
}

View File

@ -1,37 +1,149 @@
package system
import (
bin "github.com/dfuse-io/binary"
solana "github.com/gagliardetto/solana-go"
"encoding/binary"
"errors"
"fmt"
ag_binary "github.com/dfuse-io/binary"
ag_solanago "github.com/gagliardetto/solana-go"
ag_format "github.com/gagliardetto/solana-go/text/format"
ag_treeout "github.com/gagliardetto/treeout"
)
func NewAuthorizeNonceAccountInstruction(
authorizePubKey solana.PublicKey,
noncePubKey solana.PublicKey,
nonceAuthority solana.PublicKey,
) *Instruction {
return &Instruction{
BaseVariant: bin.BaseVariant{
TypeID: Instruction_AuthorizeNonceAccount,
Impl: &AuthorizeNonceAccount{
PubKey: authorizePubKey,
AccountMetaSlice: []*solana.AccountMeta{
solana.Meta(noncePubKey).WRITE(),
solana.Meta(nonceAuthority).SIGNER(),
},
},
},
}
}
// Change the entity authorized to execute nonce instructions on the account
type AuthorizeNonceAccount struct {
// The Pubkey parameter identifies the entity to authorize.
PubKey solana.PublicKey
Authorized *ag_solanago.PublicKey
// [0] = [WRITE] Nonce account.
// [1] = [SIGNER] Nonce authority.
solana.AccountMetaSlice `bin:"-"`
// [0] = [WRITE] NonceAccount
// ··········· Nonce account
//
// [1] = [SIGNER] NonceAuthorityAccount
// ··········· Nonce authority
ag_solanago.AccountMetaSlice `bin:"-" borsh_skip:"true"`
}
// NewAuthorizeNonceAccountInstructionBuilder creates a new `AuthorizeNonceAccount` instruction builder.
func NewAuthorizeNonceAccountInstructionBuilder() *AuthorizeNonceAccount {
nd := &AuthorizeNonceAccount{
AccountMetaSlice: make(ag_solanago.AccountMetaSlice, 2),
}
return nd
}
// The Pubkey parameter identifies the entity to authorize.
func (inst *AuthorizeNonceAccount) SetAuthorized(authorized ag_solanago.PublicKey) *AuthorizeNonceAccount {
inst.Authorized = &authorized
return inst
}
// Nonce account
func (inst *AuthorizeNonceAccount) SetNonceAccount(nonceAccount ag_solanago.PublicKey) *AuthorizeNonceAccount {
inst.AccountMetaSlice[0] = ag_solanago.Meta(nonceAccount).WRITE()
return inst
}
func (inst *AuthorizeNonceAccount) GetNonceAccount() *ag_solanago.AccountMeta {
return inst.AccountMetaSlice[0]
}
// Nonce authority
func (inst *AuthorizeNonceAccount) SetNonceAuthorityAccount(nonceAuthorityAccount ag_solanago.PublicKey) *AuthorizeNonceAccount {
inst.AccountMetaSlice[1] = ag_solanago.Meta(nonceAuthorityAccount).SIGNER()
return inst
}
func (inst *AuthorizeNonceAccount) GetNonceAuthorityAccount() *ag_solanago.AccountMeta {
return inst.AccountMetaSlice[1]
}
func (inst AuthorizeNonceAccount) Build() *Instruction {
return &Instruction{BaseVariant: ag_binary.BaseVariant{
Impl: inst,
TypeID: ag_binary.TypeIDFromUint32(Instruction_AuthorizeNonceAccount, binary.LittleEndian),
}}
}
// ValidateAndBuild validates the instruction parameters and accounts;
// if there is a validation error, it returns the error.
// Otherwise, it builds and returns the instruction.
func (inst AuthorizeNonceAccount) ValidateAndBuild() (*Instruction, error) {
if err := inst.Validate(); err != nil {
return nil, err
}
return inst.Build(), nil
}
func (inst *AuthorizeNonceAccount) Validate() error {
// Check whether all (required) parameters are set:
{
if inst.Authorized == nil {
return errors.New("Authorized parameter is not set")
}
}
// 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 *AuthorizeNonceAccount) EncodeToTree(parent ag_treeout.Branches) {
parent.Child(ag_format.Program(ProgramName, ProgramID)).
//
ParentFunc(func(programBranch ag_treeout.Branches) {
programBranch.Child(ag_format.Instruction("AuthorizeNonceAccount")).
//
ParentFunc(func(instructionBranch ag_treeout.Branches) {
// Parameters of the instruction:
instructionBranch.Child("Params").ParentFunc(func(paramsBranch ag_treeout.Branches) {
paramsBranch.Child(ag_format.Param("Authorized", *inst.Authorized))
})
// Accounts of the instruction:
instructionBranch.Child("Accounts").ParentFunc(func(accountsBranch ag_treeout.Branches) {
accountsBranch.Child(ag_format.Meta("NonceAccount", inst.AccountMetaSlice[0]))
accountsBranch.Child(ag_format.Meta("NonceAuthorityAccount", inst.AccountMetaSlice[1]))
})
})
})
}
func (inst AuthorizeNonceAccount) MarshalWithEncoder(encoder *ag_binary.Encoder) error {
// Serialize `Authorized` param:
{
err := encoder.Encode(*inst.Authorized)
if err != nil {
return err
}
}
return nil
}
func (inst *AuthorizeNonceAccount) UnmarshalWithDecoder(decoder *ag_binary.Decoder) error {
// Deserialize `Authorized` param:
{
err := decoder.Decode(&inst.Authorized)
if err != nil {
return err
}
}
return nil
}
// NewAuthorizeNonceAccountInstruction declares a new AuthorizeNonceAccount instruction with the provided parameters and accounts.
func NewAuthorizeNonceAccountInstruction(
// Parameters:
authorized ag_solanago.PublicKey,
// Accounts:
nonceAccount ag_solanago.PublicKey,
nonceAuthorityAccount ag_solanago.PublicKey) *AuthorizeNonceAccount {
return NewAuthorizeNonceAccountInstructionBuilder().
SetAuthorized(authorized).
SetNonceAccount(nonceAccount).
SetNonceAuthorityAccount(nonceAuthorityAccount)
}

View File

@ -0,0 +1,31 @@
package system
import (
"bytes"
ag_gofuzz "github.com/google/gofuzz"
ag_require "github.com/stretchr/testify/require"
"strconv"
"testing"
)
func TestEncodeDecode_AuthorizeNonceAccount(t *testing.T) {
fu := ag_gofuzz.New().NilChance(0)
for i := 0; i < 1; i++ {
t.Run("AuthorizeNonceAccount"+strconv.Itoa(i), func(t *testing.T) {
{
params := new(AuthorizeNonceAccount)
fu.Fuzz(params)
params.AccountMetaSlice = nil
buf := new(bytes.Buffer)
err := encodeT(*params, buf)
ag_require.NoError(t, err)
//
got := new(AuthorizeNonceAccount)
err = decodeT(got, buf.Bytes())
got.AccountMetaSlice = nil
ag_require.NoError(t, err)
ag_require.Equal(t, params, got)
}
})
}
}

View File

@ -1,114 +1,207 @@
package system
import (
"encoding/binary"
"errors"
"fmt"
bin "github.com/dfuse-io/binary"
solana "github.com/gagliardetto/solana-go"
ag_binary "github.com/dfuse-io/binary"
ag_solanago "github.com/gagliardetto/solana-go"
ag_format "github.com/gagliardetto/solana-go/text/format"
ag_treeout "github.com/gagliardetto/treeout"
)
// Create a new account
type CreateAccount struct {
// Number of lamports to transfer to the new account
Lamports *uint64
// Number of bytes of memory to allocate
Space *uint64
// Address of program that will own the new account
Owner *ag_solanago.PublicKey
// [0] = [WRITE, SIGNER] FundingAccount
// ··········· Funding account
//
// [1] = [WRITE, SIGNER] NewAccount
// ··········· New account
ag_solanago.AccountMetaSlice `bin:"-" borsh_skip:"true"`
}
// NewCreateAccountInstructionBuilder creates a new `CreateAccount` instruction builder.
func NewCreateAccountInstructionBuilder() *CreateAccount {
nd := &CreateAccount{
AccountMetaSlice: make(ag_solanago.AccountMetaSlice, 2),
}
return nd
}
// Number of lamports to transfer to the new account
func (inst *CreateAccount) SetLamports(lamports uint64) *CreateAccount {
inst.Lamports = &lamports
return inst
}
// Number of bytes of memory to allocate
func (inst *CreateAccount) SetSpace(space uint64) *CreateAccount {
inst.Space = &space
return inst
}
// Address of program that will own the new account
func (inst *CreateAccount) SetOwner(owner ag_solanago.PublicKey) *CreateAccount {
inst.Owner = &owner
return inst
}
// Funding account
func (inst *CreateAccount) SetFundingAccount(fundingAccount ag_solanago.PublicKey) *CreateAccount {
inst.AccountMetaSlice[0] = ag_solanago.Meta(fundingAccount).WRITE().SIGNER()
return inst
}
func (inst *CreateAccount) GetFundingAccount() *ag_solanago.AccountMeta {
return inst.AccountMetaSlice[0]
}
// New account
func (inst *CreateAccount) SetNewAccount(newAccount ag_solanago.PublicKey) *CreateAccount {
inst.AccountMetaSlice[1] = ag_solanago.Meta(newAccount).WRITE().SIGNER()
return inst
}
func (inst *CreateAccount) GetNewAccount() *ag_solanago.AccountMeta {
return inst.AccountMetaSlice[1]
}
func (inst CreateAccount) Build() *Instruction {
return &Instruction{BaseVariant: ag_binary.BaseVariant{
Impl: inst,
TypeID: ag_binary.TypeIDFromUint32(Instruction_CreateAccount, binary.LittleEndian),
}}
}
// ValidateAndBuild validates the instruction parameters and accounts;
// if there is a validation error, it returns the error.
// Otherwise, it builds and returns the instruction.
func (inst CreateAccount) ValidateAndBuild() (*Instruction, error) {
if err := inst.Validate(); err != nil {
return nil, err
}
return inst.Build(), nil
}
func (inst *CreateAccount) Validate() error {
// Check whether all (required) parameters are set:
{
if inst.Lamports == nil {
return errors.New("Lamports parameter is not set")
}
if inst.Space == nil {
return errors.New("Space parameter is not set")
}
if inst.Owner == nil {
return errors.New("Owner parameter is not set")
}
}
// 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 *CreateAccount) EncodeToTree(parent ag_treeout.Branches) {
parent.Child(ag_format.Program(ProgramName, ProgramID)).
//
ParentFunc(func(programBranch ag_treeout.Branches) {
programBranch.Child(ag_format.Instruction("CreateAccount")).
//
ParentFunc(func(instructionBranch ag_treeout.Branches) {
// Parameters of the instruction:
instructionBranch.Child("Params").ParentFunc(func(paramsBranch ag_treeout.Branches) {
paramsBranch.Child(ag_format.Param("Lamports", *inst.Lamports))
paramsBranch.Child(ag_format.Param("Space", *inst.Space))
paramsBranch.Child(ag_format.Param("Owner", *inst.Owner))
})
// Accounts of the instruction:
instructionBranch.Child("Accounts").ParentFunc(func(accountsBranch ag_treeout.Branches) {
accountsBranch.Child(ag_format.Meta("FundingAccount", inst.AccountMetaSlice[0]))
accountsBranch.Child(ag_format.Meta("NewAccount", inst.AccountMetaSlice[1]))
})
})
})
}
func (inst CreateAccount) MarshalWithEncoder(encoder *ag_binary.Encoder) error {
// Serialize `Lamports` param:
{
err := encoder.Encode(*inst.Lamports)
if err != nil {
return err
}
}
// Serialize `Space` param:
{
err := encoder.Encode(*inst.Space)
if err != nil {
return err
}
}
// Serialize `Owner` param:
{
err := encoder.Encode(*inst.Owner)
if err != nil {
return err
}
}
return nil
}
func (inst *CreateAccount) UnmarshalWithDecoder(decoder *ag_binary.Decoder) error {
// Deserialize `Lamports` param:
{
err := decoder.Decode(&inst.Lamports)
if err != nil {
return err
}
}
// Deserialize `Space` param:
{
err := decoder.Decode(&inst.Space)
if err != nil {
return err
}
}
// Deserialize `Owner` param:
{
err := decoder.Decode(&inst.Owner)
if err != nil {
return err
}
}
return nil
}
// NewCreateAccountInstruction declares a new CreateAccount instruction with the provided parameters and accounts.
func NewCreateAccountInstruction(
// Parameters:
lamports uint64,
space uint64,
owner solana.PublicKey,
fundingAccount solana.PublicKey,
newAccount solana.PublicKey,
) *Instruction {
return NewCreateAccountBuilder().
WithLamports(lamports).
WithSpace(space).
WithOwner(owner).
WithFundingAccount(fundingAccount).
WithNewAccount(newAccount).
Build()
}
// Create a new account.
type CreateAccount struct {
// Number of lamports to transfer to the new account.
Lamports bin.Uint64
// Number of bytes of memory to allocate.
Space bin.Uint64
// Address of program that will own the new account.
Owner solana.PublicKey
// [0] = [WRITE, SIGNER] Funding account.
// [1] = [WRITE, SIGNER] New account.
solana.AccountMetaSlice `bin:"-"`
}
// NewCreateAccountBuilder initializes a new CreateAccount builder.
func NewCreateAccountBuilder() *CreateAccount {
return &CreateAccount{
AccountMetaSlice: make(solana.AccountMetaSlice, 2),
}
}
// WithLamports sets the number of lamports to transfer to the new account.
func (ins *CreateAccount) WithLamports(lamports uint64) *CreateAccount {
ins.Lamports = bin.Uint64(lamports)
return ins
}
// WithSpace sets the number of bytes of memory to allocate.
func (ins *CreateAccount) WithSpace(space uint64) *CreateAccount {
ins.Space = bin.Uint64(space)
return ins
}
// WithOwner sets the address of program that will own the new account.
func (ins *CreateAccount) WithOwner(owner solana.PublicKey) *CreateAccount {
ins.Owner = owner
return ins
}
// WithFundingAccount sets the account that will fund the new account.
func (ins *CreateAccount) WithFundingAccount(fundingAccount solana.PublicKey) *CreateAccount {
ins.AccountMetaSlice[0] = solana.Meta(fundingAccount).WRITE().SIGNER()
return ins
}
// GetFundingAccount gets the account that will fund the new account.
func (ins *CreateAccount) GetFundingAccount() *solana.PublicKey {
ac := ins.AccountMetaSlice[0]
if ac == nil {
return nil
}
return &ac.PublicKey
}
// WithNewAccount sets the new account that will be created.
func (ins *CreateAccount) WithNewAccount(newAccount solana.PublicKey) *CreateAccount {
ins.AccountMetaSlice[1] = solana.Meta(newAccount).WRITE().SIGNER()
return ins
}
// GetNewAccount gets the new account.
func (ins *CreateAccount) GetNewAccount() *solana.PublicKey {
ac := ins.AccountMetaSlice[1]
if ac == nil {
return nil
}
return &ac.PublicKey
}
func (ins *CreateAccount) Validate() error {
for accIndex, acc := range ins.AccountMetaSlice {
if acc == nil {
return fmt.Errorf("ins.AccountMetaSlice[%v] is nil", accIndex)
}
}
return nil
}
func (ins *CreateAccount) Build() *Instruction {
return &Instruction{
BaseVariant: bin.BaseVariant{
TypeID: Instruction_CreateAccount,
Impl: ins,
},
}
owner ag_solanago.PublicKey,
// Accounts:
fundingAccount ag_solanago.PublicKey,
newAccount ag_solanago.PublicKey) *CreateAccount {
return NewCreateAccountInstructionBuilder().
SetLamports(lamports).
SetSpace(space).
SetOwner(owner).
SetFundingAccount(fundingAccount).
SetNewAccount(newAccount)
}

View File

@ -1,70 +1,281 @@
package system
import (
bin "github.com/dfuse-io/binary"
solana "github.com/gagliardetto/solana-go"
"encoding/binary"
"errors"
"fmt"
ag_binary "github.com/dfuse-io/binary"
ag_solanago "github.com/gagliardetto/solana-go"
ag_format "github.com/gagliardetto/solana-go/text/format"
ag_treeout "github.com/gagliardetto/treeout"
)
// Create a new account at an address derived from a base pubkey and a seed
type CreateAccountWithSeed struct {
// Base public key
Base *ag_solanago.PublicKey
// String of ASCII chars, no longer than Pubkey::MAX_SEED_LEN
Seed *string
// Number of lamports to transfer to the new account
Lamports *uint64
// Number of bytes of memory to allocate
Space *uint64
// Owner program account address
Owner *ag_solanago.PublicKey
// [0] = [WRITE, SIGNER] FundingAccount
// ··········· Funding account
//
// [1] = [WRITE] CreatedAccount
// ··········· Created account
//
// [2] = [SIGNER] BaseAccount
// ··········· Base account
ag_solanago.AccountMetaSlice `bin:"-" borsh_skip:"true"`
}
// NewCreateAccountWithSeedInstructionBuilder creates a new `CreateAccountWithSeed` instruction builder.
func NewCreateAccountWithSeedInstructionBuilder() *CreateAccountWithSeed {
nd := &CreateAccountWithSeed{
AccountMetaSlice: make(ag_solanago.AccountMetaSlice, 3),
}
return nd
}
// Base public key
func (inst *CreateAccountWithSeed) SetBase(base ag_solanago.PublicKey) *CreateAccountWithSeed {
inst.Base = &base
return inst
}
// String of ASCII chars, no longer than Pubkey::MAX_SEED_LEN
func (inst *CreateAccountWithSeed) SetSeed(seed string) *CreateAccountWithSeed {
inst.Seed = &seed
return inst
}
// Number of lamports to transfer to the new account
func (inst *CreateAccountWithSeed) SetLamports(lamports uint64) *CreateAccountWithSeed {
inst.Lamports = &lamports
return inst
}
// Number of bytes of memory to allocate
func (inst *CreateAccountWithSeed) SetSpace(space uint64) *CreateAccountWithSeed {
inst.Space = &space
return inst
}
// Owner program account address
func (inst *CreateAccountWithSeed) SetOwner(owner ag_solanago.PublicKey) *CreateAccountWithSeed {
inst.Owner = &owner
return inst
}
// Funding account
func (inst *CreateAccountWithSeed) SetFundingAccount(fundingAccount ag_solanago.PublicKey) *CreateAccountWithSeed {
inst.AccountMetaSlice[0] = ag_solanago.Meta(fundingAccount).WRITE().SIGNER()
return inst
}
func (inst *CreateAccountWithSeed) GetFundingAccount() *ag_solanago.AccountMeta {
return inst.AccountMetaSlice[0]
}
// Created account
func (inst *CreateAccountWithSeed) SetCreatedAccount(createdAccount ag_solanago.PublicKey) *CreateAccountWithSeed {
inst.AccountMetaSlice[1] = ag_solanago.Meta(createdAccount).WRITE()
return inst
}
func (inst *CreateAccountWithSeed) GetCreatedAccount() *ag_solanago.AccountMeta {
return inst.AccountMetaSlice[1]
}
// Base account
func (inst *CreateAccountWithSeed) SetBaseAccount(baseAccount ag_solanago.PublicKey) *CreateAccountWithSeed {
inst.AccountMetaSlice[2] = ag_solanago.Meta(baseAccount).SIGNER()
return inst
}
func (inst *CreateAccountWithSeed) GetBaseAccount() *ag_solanago.AccountMeta {
return inst.AccountMetaSlice[2]
}
func (inst CreateAccountWithSeed) Build() *Instruction {
return &Instruction{BaseVariant: ag_binary.BaseVariant{
Impl: inst,
TypeID: ag_binary.TypeIDFromUint32(Instruction_CreateAccountWithSeed, binary.LittleEndian),
}}
}
// ValidateAndBuild validates the instruction parameters and accounts;
// if there is a validation error, it returns the error.
// Otherwise, it builds and returns the instruction.
func (inst CreateAccountWithSeed) ValidateAndBuild() (*Instruction, error) {
if err := inst.Validate(); err != nil {
return nil, err
}
return inst.Build(), nil
}
func (inst *CreateAccountWithSeed) Validate() error {
// Check whether all (required) parameters are set:
{
if inst.Base == nil {
return errors.New("Base parameter is not set")
}
if inst.Seed == nil {
return errors.New("Seed parameter is not set")
}
if inst.Lamports == nil {
return errors.New("Lamports parameter is not set")
}
if inst.Space == nil {
return errors.New("Space parameter is not set")
}
if inst.Owner == nil {
return errors.New("Owner parameter is not set")
}
}
// 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 *CreateAccountWithSeed) EncodeToTree(parent ag_treeout.Branches) {
parent.Child(ag_format.Program(ProgramName, ProgramID)).
//
ParentFunc(func(programBranch ag_treeout.Branches) {
programBranch.Child(ag_format.Instruction("CreateAccountWithSeed")).
//
ParentFunc(func(instructionBranch ag_treeout.Branches) {
// Parameters of the instruction:
instructionBranch.Child("Params").ParentFunc(func(paramsBranch ag_treeout.Branches) {
paramsBranch.Child(ag_format.Param("Base", *inst.Base))
paramsBranch.Child(ag_format.Param("Seed", *inst.Seed))
paramsBranch.Child(ag_format.Param("Lamports", *inst.Lamports))
paramsBranch.Child(ag_format.Param("Space", *inst.Space))
paramsBranch.Child(ag_format.Param("Owner", *inst.Owner))
})
// Accounts of the instruction:
instructionBranch.Child("Accounts").ParentFunc(func(accountsBranch ag_treeout.Branches) {
accountsBranch.Child(ag_format.Meta("FundingAccount", inst.AccountMetaSlice[0]))
accountsBranch.Child(ag_format.Meta("CreatedAccount", inst.AccountMetaSlice[1]))
accountsBranch.Child(ag_format.Meta("BaseAccount", inst.AccountMetaSlice[2]))
})
})
})
}
func (inst CreateAccountWithSeed) MarshalWithEncoder(encoder *ag_binary.Encoder) error {
// Serialize `Base` param:
{
err := encoder.Encode(*inst.Base)
if err != nil {
return err
}
}
// Serialize `Seed` param:
{
err := encoder.Encode(*inst.Seed)
if err != nil {
return err
}
}
// Serialize `Lamports` param:
{
err := encoder.Encode(*inst.Lamports)
if err != nil {
return err
}
}
// Serialize `Space` param:
{
err := encoder.Encode(*inst.Space)
if err != nil {
return err
}
}
// Serialize `Owner` param:
{
err := encoder.Encode(*inst.Owner)
if err != nil {
return err
}
}
return nil
}
func (inst *CreateAccountWithSeed) UnmarshalWithDecoder(decoder *ag_binary.Decoder) error {
// Deserialize `Base` param:
{
err := decoder.Decode(&inst.Base)
if err != nil {
return err
}
}
// Deserialize `Seed` param:
{
err := decoder.Decode(&inst.Seed)
if err != nil {
return err
}
}
// Deserialize `Lamports` param:
{
err := decoder.Decode(&inst.Lamports)
if err != nil {
return err
}
}
// Deserialize `Space` param:
{
err := decoder.Decode(&inst.Space)
if err != nil {
return err
}
}
// Deserialize `Owner` param:
{
err := decoder.Decode(&inst.Owner)
if err != nil {
return err
}
}
return nil
}
// NewCreateAccountWithSeedInstruction declares a new CreateAccountWithSeed instruction with the provided parameters and accounts.
func NewCreateAccountWithSeedInstruction(
base solana.PublicKey,
// Parameters:
base ag_solanago.PublicKey,
seed string,
lamports uint64,
space uint64,
owner solana.PublicKey,
fundingAccount solana.PublicKey,
newAccount solana.PublicKey,
) *Instruction {
return &Instruction{
BaseVariant: bin.BaseVariant{
TypeID: Instruction_CreateAccountWithSeed,
Impl: &CreateAccountWithSeed{
Base: base,
Seed: seed,
Lamports: bin.Uint64(lamports),
Space: bin.Uint64(space),
Owner: owner,
AccountMetaSlice: func() solana.AccountMetaSlice {
res := solana.AccountMetaSlice{
solana.Meta(fundingAccount).WRITE().SIGNER(),
solana.Meta(newAccount).WRITE(),
}
if !base.Equals(fundingAccount) {
res.Append(solana.Meta(base).SIGNER())
}
return res
}(),
},
},
}
}
type CreateAccountWithSeed struct {
// Base public key.
Base solana.PublicKey
SeedSize int64 `bin:"sizeof=Seed"`
// String of ASCII chars, no longer than solana.MAX_SEED_LEN
Seed string
// Number of lamports to transfer to the new account.
Lamports bin.Uint64
// Number of bytes of memory to allocate
Space bin.Uint64
// Owner program account address.
Owner solana.PublicKey
// [0] = [WRITE, SIGNER] Funding account.
// [1] = [WRITE] Created account.
// [2] = [SIGNER] Base account; the account matching the base Pubkey below must be provided as a signer,
// but may be the same as the funding account and provided as account 0
solana.AccountMetaSlice `bin:"-"`
owner ag_solanago.PublicKey,
// Accounts:
fundingAccount ag_solanago.PublicKey,
createdAccount ag_solanago.PublicKey,
baseAccount ag_solanago.PublicKey) *CreateAccountWithSeed {
return NewCreateAccountWithSeedInstructionBuilder().
SetBase(base).
SetSeed(seed).
SetLamports(lamports).
SetSpace(space).
SetOwner(owner).
SetFundingAccount(fundingAccount).
SetCreatedAccount(createdAccount).
SetBaseAccount(baseAccount)
}

View File

@ -0,0 +1,31 @@
package system
import (
"bytes"
ag_gofuzz "github.com/google/gofuzz"
ag_require "github.com/stretchr/testify/require"
"strconv"
"testing"
)
func TestEncodeDecode_CreateAccountWithSeed(t *testing.T) {
fu := ag_gofuzz.New().NilChance(0)
for i := 0; i < 1; i++ {
t.Run("CreateAccountWithSeed"+strconv.Itoa(i), func(t *testing.T) {
{
params := new(CreateAccountWithSeed)
fu.Fuzz(params)
params.AccountMetaSlice = nil
buf := new(bytes.Buffer)
err := encodeT(*params, buf)
ag_require.NoError(t, err)
//
got := new(CreateAccountWithSeed)
err = decodeT(got, buf.Bytes())
got.AccountMetaSlice = nil
ag_require.NoError(t, err)
ag_require.Equal(t, params, got)
}
})
}
}

View File

@ -0,0 +1,31 @@
package system
import (
"bytes"
ag_gofuzz "github.com/google/gofuzz"
ag_require "github.com/stretchr/testify/require"
"strconv"
"testing"
)
func TestEncodeDecode_CreateAccount(t *testing.T) {
fu := ag_gofuzz.New().NilChance(0)
for i := 0; i < 1; i++ {
t.Run("CreateAccount"+strconv.Itoa(i), func(t *testing.T) {
{
params := new(CreateAccount)
fu.Fuzz(params)
params.AccountMetaSlice = nil
buf := new(bytes.Buffer)
err := encodeT(*params, buf)
ag_require.NoError(t, err)
//
got := new(CreateAccount)
err = decodeT(got, buf.Bytes())
got.AccountMetaSlice = nil
ag_require.NoError(t, err)
ag_require.Equal(t, params, got)
}
})
}
}

View File

@ -1,40 +1,169 @@
package system
import (
bin "github.com/dfuse-io/binary"
solana "github.com/gagliardetto/solana-go"
"encoding/binary"
"errors"
"fmt"
ag_binary "github.com/dfuse-io/binary"
ag_solanago "github.com/gagliardetto/solana-go"
ag_format "github.com/gagliardetto/solana-go/text/format"
ag_treeout "github.com/gagliardetto/treeout"
)
func NewInitializeNonceAccountInstruction(
authPubKey solana.PublicKey,
noncePubKey solana.PublicKey,
) *Instruction {
return &Instruction{
BaseVariant: bin.BaseVariant{
TypeID: Instruction_InitializeNonceAccount,
Impl: &InitializeNonceAccount{
AuthPubKey: authPubKey,
AccountMetaSlice: []*solana.AccountMeta{
solana.Meta(noncePubKey).WRITE(),
solana.Meta(solana.SysVarRecentBlockHashesPubkey),
solana.Meta(solana.SysVarRentPubkey),
},
},
},
}
}
// Drive state of Uninitalized nonce account to Initialized, setting the nonce value
type InitializeNonceAccount struct {
// The Pubkey parameter specifies the entity
// authorized to execute nonce instruction on the account.
// No signatures are required to execute this instruction,
// enabling derived nonce account addresses
AuthPubKey solana.PublicKey
// The Pubkey parameter specifies the entity authorized to execute nonce instruction on the account.
// No signatures are required to execute this instruction, enabling derived nonce account addresses.
Authorized *ag_solanago.PublicKey
// [0] = [WRITE] Nonce account.
// [1] = [] RecentBlockhashes sysvar.
// [2] = [] Rent sysvar.
solana.AccountMetaSlice `bin:"-"`
// [0] = [WRITE] NonceAccount
// ··········· Nonce account
//
// [1] = [] $(SysVarRecentBlockHashesPubkey)
// ··········· RecentBlockhashes sysvar
//
// [2] = [] $(SysVarRentPubkey)
// ··········· Rent sysvar
ag_solanago.AccountMetaSlice `bin:"-" borsh_skip:"true"`
}
// NewInitializeNonceAccountInstructionBuilder creates a new `InitializeNonceAccount` instruction builder.
func NewInitializeNonceAccountInstructionBuilder() *InitializeNonceAccount {
nd := &InitializeNonceAccount{
AccountMetaSlice: make(ag_solanago.AccountMetaSlice, 3),
}
nd.AccountMetaSlice[1] = ag_solanago.Meta(ag_solanago.SysVarRecentBlockHashesPubkey)
nd.AccountMetaSlice[2] = ag_solanago.Meta(ag_solanago.SysVarRentPubkey)
return nd
}
// The Pubkey parameter specifies the entity authorized to execute nonce instruction on the account.
// No signatures are required to execute this instruction, enabling derived nonce account addresses.
func (inst *InitializeNonceAccount) SetAuthorized(authorized ag_solanago.PublicKey) *InitializeNonceAccount {
inst.Authorized = &authorized
return inst
}
// Nonce account
func (inst *InitializeNonceAccount) SetNonceAccount(nonceAccount ag_solanago.PublicKey) *InitializeNonceAccount {
inst.AccountMetaSlice[0] = ag_solanago.Meta(nonceAccount).WRITE()
return inst
}
func (inst *InitializeNonceAccount) GetNonceAccount() *ag_solanago.AccountMeta {
return inst.AccountMetaSlice[0]
}
// RecentBlockhashes sysvar
func (inst *InitializeNonceAccount) SetSysVarRecentBlockHashesPubkeyAccount(SysVarRecentBlockHashesPubkey ag_solanago.PublicKey) *InitializeNonceAccount {
inst.AccountMetaSlice[1] = ag_solanago.Meta(SysVarRecentBlockHashesPubkey)
return inst
}
func (inst *InitializeNonceAccount) GetSysVarRecentBlockHashesPubkeyAccount() *ag_solanago.AccountMeta {
return inst.AccountMetaSlice[1]
}
// Rent sysvar
func (inst *InitializeNonceAccount) SetSysVarRentPubkeyAccount(SysVarRentPubkey ag_solanago.PublicKey) *InitializeNonceAccount {
inst.AccountMetaSlice[2] = ag_solanago.Meta(SysVarRentPubkey)
return inst
}
func (inst *InitializeNonceAccount) GetSysVarRentPubkeyAccount() *ag_solanago.AccountMeta {
return inst.AccountMetaSlice[2]
}
func (inst InitializeNonceAccount) Build() *Instruction {
return &Instruction{BaseVariant: ag_binary.BaseVariant{
Impl: inst,
TypeID: ag_binary.TypeIDFromUint32(Instruction_InitializeNonceAccount, binary.LittleEndian),
}}
}
// ValidateAndBuild validates the instruction parameters and accounts;
// if there is a validation error, it returns the error.
// Otherwise, it builds and returns the instruction.
func (inst InitializeNonceAccount) ValidateAndBuild() (*Instruction, error) {
if err := inst.Validate(); err != nil {
return nil, err
}
return inst.Build(), nil
}
func (inst *InitializeNonceAccount) Validate() error {
// Check whether all (required) parameters are set:
{
if inst.Authorized == nil {
return errors.New("Authorized parameter is not set")
}
}
// 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 *InitializeNonceAccount) EncodeToTree(parent ag_treeout.Branches) {
parent.Child(ag_format.Program(ProgramName, ProgramID)).
//
ParentFunc(func(programBranch ag_treeout.Branches) {
programBranch.Child(ag_format.Instruction("InitializeNonceAccount")).
//
ParentFunc(func(instructionBranch ag_treeout.Branches) {
// Parameters of the instruction:
instructionBranch.Child("Params").ParentFunc(func(paramsBranch ag_treeout.Branches) {
paramsBranch.Child(ag_format.Param("Authorized", *inst.Authorized))
})
// Accounts of the instruction:
instructionBranch.Child("Accounts").ParentFunc(func(accountsBranch ag_treeout.Branches) {
accountsBranch.Child(ag_format.Meta("NonceAccount", inst.AccountMetaSlice[0]))
accountsBranch.Child(ag_format.Meta("$(SysVarRecentBlockHashesPubkey)", inst.AccountMetaSlice[1]))
accountsBranch.Child(ag_format.Meta("$(SysVarRentPubkey)", inst.AccountMetaSlice[2]))
})
})
})
}
func (inst InitializeNonceAccount) MarshalWithEncoder(encoder *ag_binary.Encoder) error {
// Serialize `Authorized` param:
{
err := encoder.Encode(*inst.Authorized)
if err != nil {
return err
}
}
return nil
}
func (inst *InitializeNonceAccount) UnmarshalWithDecoder(decoder *ag_binary.Decoder) error {
// Deserialize `Authorized` param:
{
err := decoder.Decode(&inst.Authorized)
if err != nil {
return err
}
}
return nil
}
// NewInitializeNonceAccountInstruction declares a new InitializeNonceAccount instruction with the provided parameters and accounts.
func NewInitializeNonceAccountInstruction(
// Parameters:
authorized ag_solanago.PublicKey,
// Accounts:
nonceAccount ag_solanago.PublicKey,
SysVarRecentBlockHashesPubkey ag_solanago.PublicKey,
SysVarRentPubkey ag_solanago.PublicKey) *InitializeNonceAccount {
return NewInitializeNonceAccountInstructionBuilder().
SetAuthorized(authorized).
SetNonceAccount(nonceAccount).
SetSysVarRecentBlockHashesPubkeyAccount(SysVarRecentBlockHashesPubkey).
SetSysVarRentPubkeyAccount(SysVarRentPubkey)
}

View File

@ -0,0 +1,31 @@
package system
import (
"bytes"
ag_gofuzz "github.com/google/gofuzz"
ag_require "github.com/stretchr/testify/require"
"strconv"
"testing"
)
func TestEncodeDecode_InitializeNonceAccount(t *testing.T) {
fu := ag_gofuzz.New().NilChance(0)
for i := 0; i < 1; i++ {
t.Run("InitializeNonceAccount"+strconv.Itoa(i), func(t *testing.T) {
{
params := new(InitializeNonceAccount)
fu.Fuzz(params)
params.AccountMetaSlice = nil
buf := new(bytes.Buffer)
err := encodeT(*params, buf)
ag_require.NoError(t, err)
//
got := new(InitializeNonceAccount)
err = decodeT(got, buf.Bytes())
got.AccountMetaSlice = nil
ag_require.NoError(t, err)
ag_require.Equal(t, params, got)
}
})
}
}

View File

@ -1,58 +1,149 @@
package system
import (
bin "github.com/dfuse-io/binary"
solana "github.com/gagliardetto/solana-go"
"github.com/gagliardetto/solana-go/text/format"
"github.com/gagliardetto/treeout"
"encoding/binary"
"errors"
"fmt"
ag_binary "github.com/dfuse-io/binary"
ag_solanago "github.com/gagliardetto/solana-go"
ag_format "github.com/gagliardetto/solana-go/text/format"
ag_treeout "github.com/gagliardetto/treeout"
)
func NewTransferInstruction(
lamports uint64,
from solana.PublicKey,
to solana.PublicKey,
) *Instruction {
return &Instruction{
BaseVariant: bin.BaseVariant{
TypeID: Instruction_Transfer,
Impl: &Transfer{
Lamports: bin.Uint64(lamports),
AccountMetaSlice: []*solana.AccountMeta{
solana.Meta(from).WRITE().SIGNER(),
solana.Meta(to).WRITE(),
},
},
},
}
}
// Transfer lamports
type Transfer struct {
Lamports bin.Uint64
// Number of lamports to transfer to the new account
Lamports *uint64
// [0] = [WRITE, SIGNER] Funding account.
// [1] = [WRITE] Recipient account.
solana.AccountMetaSlice `bin:"-" text:"-"`
// [0] = [WRITE, SIGNER] FundingAccount
// ··········· Funding account
//
// [1] = [WRITE] RecipientAccount
// ··········· Recipient account
ag_solanago.AccountMetaSlice `bin:"-" borsh_skip:"true"`
}
func (inst *Transfer) EncodeToTree(parent treeout.Branches) {
parent.Child(format.Program(ProgramName, ProgramID)).
// NewTransferInstructionBuilder creates a new `Transfer` instruction builder.
func NewTransferInstructionBuilder() *Transfer {
nd := &Transfer{
AccountMetaSlice: make(ag_solanago.AccountMetaSlice, 2),
}
return nd
}
// Number of lamports to transfer to the new account
func (inst *Transfer) SetLamports(lamports uint64) *Transfer {
inst.Lamports = &lamports
return inst
}
// Funding account
func (inst *Transfer) SetFundingAccount(fundingAccount ag_solanago.PublicKey) *Transfer {
inst.AccountMetaSlice[0] = ag_solanago.Meta(fundingAccount).WRITE().SIGNER()
return inst
}
func (inst *Transfer) GetFundingAccount() *ag_solanago.AccountMeta {
return inst.AccountMetaSlice[0]
}
// Recipient account
func (inst *Transfer) SetRecipientAccount(recipientAccount ag_solanago.PublicKey) *Transfer {
inst.AccountMetaSlice[1] = ag_solanago.Meta(recipientAccount).WRITE()
return inst
}
func (inst *Transfer) GetRecipientAccount() *ag_solanago.AccountMeta {
return inst.AccountMetaSlice[1]
}
func (inst Transfer) Build() *Instruction {
return &Instruction{BaseVariant: ag_binary.BaseVariant{
Impl: inst,
TypeID: ag_binary.TypeIDFromUint32(Instruction_Transfer, binary.LittleEndian),
}}
}
// ValidateAndBuild validates the instruction parameters and accounts;
// if there is a validation error, it returns the error.
// Otherwise, it builds and returns the instruction.
func (inst Transfer) ValidateAndBuild() (*Instruction, error) {
if err := inst.Validate(); err != nil {
return nil, err
}
return inst.Build(), nil
}
func (inst *Transfer) Validate() error {
// Check whether all (required) parameters are set:
{
if inst.Lamports == nil {
return errors.New("Lamports parameter is not set")
}
}
// 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 *Transfer) EncodeToTree(parent ag_treeout.Branches) {
parent.Child(ag_format.Program(ProgramName, ProgramID)).
//
ParentFunc(func(programBranch treeout.Branches) {
programBranch.Child(format.Instruction("Transfer")).
ParentFunc(func(programBranch ag_treeout.Branches) {
programBranch.Child(ag_format.Instruction("Transfer")).
//
ParentFunc(func(instructionBranch treeout.Branches) {
//
instructionBranch.Child("Params").ParentFunc(func(paramsBranch treeout.Branches) {
paramsBranch.Child(format.Param("Lamports", inst.Lamports))
ParentFunc(func(instructionBranch ag_treeout.Branches) {
// Parameters of the instruction:
instructionBranch.Child("Params").ParentFunc(func(paramsBranch ag_treeout.Branches) {
paramsBranch.Child(ag_format.Param("Lamports", *inst.Lamports))
})
//
instructionBranch.Child("Accounts").ParentFunc(func(accountsBranch treeout.Branches) {
accountsBranch.Child(format.Account("FundingAccount", inst.AccountMetaSlice[0].PublicKey))
accountsBranch.Child(format.Account("RecipientAccount", inst.AccountMetaSlice[1].PublicKey))
// Accounts of the instruction:
instructionBranch.Child("Accounts").ParentFunc(func(accountsBranch ag_treeout.Branches) {
accountsBranch.Child(ag_format.Meta("FundingAccount", inst.AccountMetaSlice[0]))
accountsBranch.Child(ag_format.Meta("RecipientAccount", inst.AccountMetaSlice[1]))
})
})
})
}
func (inst Transfer) MarshalWithEncoder(encoder *ag_binary.Encoder) error {
// Serialize `Lamports` param:
{
err := encoder.Encode(*inst.Lamports)
if err != nil {
return err
}
}
return nil
}
func (inst *Transfer) UnmarshalWithDecoder(decoder *ag_binary.Decoder) error {
// Deserialize `Lamports` param:
{
err := decoder.Decode(&inst.Lamports)
if err != nil {
return err
}
}
return nil
}
// NewTransferInstruction declares a new Transfer instruction with the provided parameters and accounts.
func NewTransferInstruction(
// Parameters:
lamports uint64,
// Accounts:
fundingAccount ag_solanago.PublicKey,
recipientAccount ag_solanago.PublicKey) *Transfer {
return NewTransferInstructionBuilder().
SetLamports(lamports).
SetFundingAccount(fundingAccount).
SetRecipientAccount(recipientAccount)
}

View File

@ -1,46 +1,223 @@
package system
import (
bin "github.com/dfuse-io/binary"
solana "github.com/gagliardetto/solana-go"
"encoding/binary"
"errors"
"fmt"
ag_binary "github.com/dfuse-io/binary"
ag_solanago "github.com/gagliardetto/solana-go"
ag_format "github.com/gagliardetto/solana-go/text/format"
ag_treeout "github.com/gagliardetto/treeout"
)
func NewTransferWithSeedInstruction(
from solana.PublicKey,
to solana.PublicKey,
basePubKey solana.PublicKey,
owner solana.PublicKey,
seed string,
lamports uint64,
) *Instruction {
return &Instruction{
BaseVariant: bin.BaseVariant{
TypeID: Instruction_TransferWithSeed,
Impl: &TransferWithSeed{
Lamports: bin.Uint64(lamports),
Seed: seed,
Owner: owner,
AccountMetaSlice: []*solana.AccountMeta{
solana.Meta(from).WRITE(),
solana.Meta(basePubKey).SIGNER(),
solana.Meta(to).WRITE(),
},
},
},
}
}
// Transfer lamports from a derived address
type TransferWithSeed struct {
Lamports bin.Uint64
SeedSize int `bin:"sizeof=Seed"`
Seed string
Owner solana.PublicKey
// Amount to transfer
Lamports *uint64
// [0] = [WRITE] Funding account.
// [1] = [SIGNER] Base for funding account.
// [2] = [WRITE] Recipient account.
solana.AccountMetaSlice `bin:"-"`
// Seed to use to derive the funding account address
FromSeed *string
// Owner to use to derive the funding account address
FromOwner *ag_solanago.PublicKey
// [0] = [WRITE] FundingAccount
// ··········· Funding account
//
// [1] = [SIGNER] BaseForFundingAccount
// ··········· Base for funding account
//
// [2] = [WRITE] RecipientAccount
// ··········· Recipient account
ag_solanago.AccountMetaSlice `bin:"-" borsh_skip:"true"`
}
// NewTransferWithSeedInstructionBuilder creates a new `TransferWithSeed` instruction builder.
func NewTransferWithSeedInstructionBuilder() *TransferWithSeed {
nd := &TransferWithSeed{
AccountMetaSlice: make(ag_solanago.AccountMetaSlice, 3),
}
return nd
}
// Amount to transfer
func (inst *TransferWithSeed) SetLamports(lamports uint64) *TransferWithSeed {
inst.Lamports = &lamports
return inst
}
// Seed to use to derive the funding account address
func (inst *TransferWithSeed) SetFromSeed(from_seed string) *TransferWithSeed {
inst.FromSeed = &from_seed
return inst
}
// Owner to use to derive the funding account address
func (inst *TransferWithSeed) SetFromOwner(from_owner ag_solanago.PublicKey) *TransferWithSeed {
inst.FromOwner = &from_owner
return inst
}
// Funding account
func (inst *TransferWithSeed) SetFundingAccount(fundingAccount ag_solanago.PublicKey) *TransferWithSeed {
inst.AccountMetaSlice[0] = ag_solanago.Meta(fundingAccount).WRITE()
return inst
}
func (inst *TransferWithSeed) GetFundingAccount() *ag_solanago.AccountMeta {
return inst.AccountMetaSlice[0]
}
// Base for funding account
func (inst *TransferWithSeed) SetBaseForFundingAccount(baseForFundingAccount ag_solanago.PublicKey) *TransferWithSeed {
inst.AccountMetaSlice[1] = ag_solanago.Meta(baseForFundingAccount).SIGNER()
return inst
}
func (inst *TransferWithSeed) GetBaseForFundingAccount() *ag_solanago.AccountMeta {
return inst.AccountMetaSlice[1]
}
// Recipient account
func (inst *TransferWithSeed) SetRecipientAccount(recipientAccount ag_solanago.PublicKey) *TransferWithSeed {
inst.AccountMetaSlice[2] = ag_solanago.Meta(recipientAccount).WRITE()
return inst
}
func (inst *TransferWithSeed) GetRecipientAccount() *ag_solanago.AccountMeta {
return inst.AccountMetaSlice[2]
}
func (inst TransferWithSeed) Build() *Instruction {
return &Instruction{BaseVariant: ag_binary.BaseVariant{
Impl: inst,
TypeID: ag_binary.TypeIDFromUint32(Instruction_TransferWithSeed, binary.LittleEndian),
}}
}
// ValidateAndBuild validates the instruction parameters and accounts;
// if there is a validation error, it returns the error.
// Otherwise, it builds and returns the instruction.
func (inst TransferWithSeed) ValidateAndBuild() (*Instruction, error) {
if err := inst.Validate(); err != nil {
return nil, err
}
return inst.Build(), nil
}
func (inst *TransferWithSeed) Validate() error {
// Check whether all (required) parameters are set:
{
if inst.Lamports == nil {
return errors.New("Lamports parameter is not set")
}
if inst.FromSeed == nil {
return errors.New("FromSeed parameter is not set")
}
if inst.FromOwner == nil {
return errors.New("FromOwner parameter is not set")
}
}
// 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 *TransferWithSeed) EncodeToTree(parent ag_treeout.Branches) {
parent.Child(ag_format.Program(ProgramName, ProgramID)).
//
ParentFunc(func(programBranch ag_treeout.Branches) {
programBranch.Child(ag_format.Instruction("TransferWithSeed")).
//
ParentFunc(func(instructionBranch ag_treeout.Branches) {
// Parameters of the instruction:
instructionBranch.Child("Params").ParentFunc(func(paramsBranch ag_treeout.Branches) {
paramsBranch.Child(ag_format.Param("Lamports", *inst.Lamports))
paramsBranch.Child(ag_format.Param("FromSeed", *inst.FromSeed))
paramsBranch.Child(ag_format.Param("FromOwner", *inst.FromOwner))
})
// Accounts of the instruction:
instructionBranch.Child("Accounts").ParentFunc(func(accountsBranch ag_treeout.Branches) {
accountsBranch.Child(ag_format.Meta("FundingAccount", inst.AccountMetaSlice[0]))
accountsBranch.Child(ag_format.Meta("BaseForFundingAccount", inst.AccountMetaSlice[1]))
accountsBranch.Child(ag_format.Meta("RecipientAccount", inst.AccountMetaSlice[2]))
})
})
})
}
func (inst TransferWithSeed) MarshalWithEncoder(encoder *ag_binary.Encoder) error {
// Serialize `Lamports` param:
{
err := encoder.Encode(*inst.Lamports)
if err != nil {
return err
}
}
// Serialize `FromSeed` param:
{
err := encoder.Encode(*inst.FromSeed)
if err != nil {
return err
}
}
// Serialize `FromOwner` param:
{
err := encoder.Encode(*inst.FromOwner)
if err != nil {
return err
}
}
return nil
}
func (inst *TransferWithSeed) UnmarshalWithDecoder(decoder *ag_binary.Decoder) error {
// Deserialize `Lamports` param:
{
err := decoder.Decode(&inst.Lamports)
if err != nil {
return err
}
}
// Deserialize `FromSeed` param:
{
err := decoder.Decode(&inst.FromSeed)
if err != nil {
return err
}
}
// Deserialize `FromOwner` param:
{
err := decoder.Decode(&inst.FromOwner)
if err != nil {
return err
}
}
return nil
}
// NewTransferWithSeedInstruction declares a new TransferWithSeed instruction with the provided parameters and accounts.
func NewTransferWithSeedInstruction(
// Parameters:
lamports uint64,
from_seed string,
from_owner ag_solanago.PublicKey,
// Accounts:
fundingAccount ag_solanago.PublicKey,
baseForFundingAccount ag_solanago.PublicKey,
recipientAccount ag_solanago.PublicKey) *TransferWithSeed {
return NewTransferWithSeedInstructionBuilder().
SetLamports(lamports).
SetFromSeed(from_seed).
SetFromOwner(from_owner).
SetFundingAccount(fundingAccount).
SetBaseForFundingAccount(baseForFundingAccount).
SetRecipientAccount(recipientAccount)
}

View File

@ -0,0 +1,31 @@
package system
import (
"bytes"
ag_gofuzz "github.com/google/gofuzz"
ag_require "github.com/stretchr/testify/require"
"strconv"
"testing"
)
func TestEncodeDecode_TransferWithSeed(t *testing.T) {
fu := ag_gofuzz.New().NilChance(0)
for i := 0; i < 1; i++ {
t.Run("TransferWithSeed"+strconv.Itoa(i), func(t *testing.T) {
{
params := new(TransferWithSeed)
fu.Fuzz(params)
params.AccountMetaSlice = nil
buf := new(bytes.Buffer)
err := encodeT(*params, buf)
ag_require.NoError(t, err)
//
got := new(TransferWithSeed)
err = decodeT(got, buf.Bytes())
got.AccountMetaSlice = nil
ag_require.NoError(t, err)
ag_require.Equal(t, params, got)
}
})
}
}

View File

@ -0,0 +1,31 @@
package system
import (
"bytes"
ag_gofuzz "github.com/google/gofuzz"
ag_require "github.com/stretchr/testify/require"
"strconv"
"testing"
)
func TestEncodeDecode_Transfer(t *testing.T) {
fu := ag_gofuzz.New().NilChance(0)
for i := 0; i < 1; i++ {
t.Run("Transfer"+strconv.Itoa(i), func(t *testing.T) {
{
params := new(Transfer)
fu.Fuzz(params)
params.AccountMetaSlice = nil
buf := new(bytes.Buffer)
err := encodeT(*params, buf)
ag_require.NoError(t, err)
//
got := new(Transfer)
err = decodeT(got, buf.Bytes())
got.AccountMetaSlice = nil
ag_require.NoError(t, err)
ag_require.Equal(t, params, got)
}
})
}
}

View File

@ -1,44 +1,199 @@
package system
import (
bin "github.com/dfuse-io/binary"
solana "github.com/gagliardetto/solana-go"
"encoding/binary"
"errors"
"fmt"
ag_binary "github.com/dfuse-io/binary"
ag_solanago "github.com/gagliardetto/solana-go"
ag_format "github.com/gagliardetto/solana-go/text/format"
ag_treeout "github.com/gagliardetto/treeout"
)
func NewWithdrawNonceAccountInstruction(
lamports uint64,
nonceAccount solana.PublicKey,
recipientAccount solana.PublicKey,
nonceAuthority solana.PublicKey,
) *Instruction {
return &Instruction{
BaseVariant: bin.BaseVariant{
TypeID: Instruction_WithdrawNonceAccount,
Impl: &WithdrawNonceAccount{
Lamports: bin.Uint64(lamports),
AccountMetaSlice: []*solana.AccountMeta{
solana.Meta(nonceAccount).WRITE(),
solana.Meta(recipientAccount).WRITE(),
solana.Meta(solana.SysVarRecentBlockHashesPubkey),
solana.Meta(solana.SysVarRentPubkey),
solana.Meta(nonceAuthority).SIGNER(),
},
},
},
}
}
// Withdraw funds from a nonce account
type WithdrawNonceAccount struct {
// The u64 parameter is the lamports to withdraw, which must leave the account balance above the rent exempt reserve or at zero.
Lamports bin.Uint64
Lamports *uint64
// [0] = [WRITE] Nonce account.
// [1] = [WRITE] Recipient account.
// [2] = [] RecentBlockhashes sysvar.
// [3] = [] Rent sysvar.
// [4] = [SIGNER] Nonce authority.
solana.AccountMetaSlice `bin:"-"`
// [0] = [WRITE] NonceAccount
// ··········· Nonce account
//
// [1] = [WRITE] RecipientAccount
// ··········· Recipient account
//
// [2] = [] $(SysVarRecentBlockHashesPubkey)
// ··········· RecentBlockhashes sysvar
//
// [3] = [] $(SysVarRentPubkey)
// ··········· Rent sysvar
//
// [4] = [SIGNER] NonceAuthorityAccount
// ··········· Nonce authority
ag_solanago.AccountMetaSlice `bin:"-" borsh_skip:"true"`
}
// NewWithdrawNonceAccountInstructionBuilder creates a new `WithdrawNonceAccount` instruction builder.
func NewWithdrawNonceAccountInstructionBuilder() *WithdrawNonceAccount {
nd := &WithdrawNonceAccount{
AccountMetaSlice: make(ag_solanago.AccountMetaSlice, 5),
}
nd.AccountMetaSlice[2] = ag_solanago.Meta(ag_solanago.SysVarRecentBlockHashesPubkey)
nd.AccountMetaSlice[3] = ag_solanago.Meta(ag_solanago.SysVarRentPubkey)
return nd
}
// The u64 parameter is the lamports to withdraw, which must leave the account balance above the rent exempt reserve or at zero.
func (inst *WithdrawNonceAccount) SetLamports(lamports uint64) *WithdrawNonceAccount {
inst.Lamports = &lamports
return inst
}
// Nonce account
func (inst *WithdrawNonceAccount) SetNonceAccount(nonceAccount ag_solanago.PublicKey) *WithdrawNonceAccount {
inst.AccountMetaSlice[0] = ag_solanago.Meta(nonceAccount).WRITE()
return inst
}
func (inst *WithdrawNonceAccount) GetNonceAccount() *ag_solanago.AccountMeta {
return inst.AccountMetaSlice[0]
}
// Recipient account
func (inst *WithdrawNonceAccount) SetRecipientAccount(recipientAccount ag_solanago.PublicKey) *WithdrawNonceAccount {
inst.AccountMetaSlice[1] = ag_solanago.Meta(recipientAccount).WRITE()
return inst
}
func (inst *WithdrawNonceAccount) GetRecipientAccount() *ag_solanago.AccountMeta {
return inst.AccountMetaSlice[1]
}
// RecentBlockhashes sysvar
func (inst *WithdrawNonceAccount) SetSysVarRecentBlockHashesPubkeyAccount(SysVarRecentBlockHashesPubkey ag_solanago.PublicKey) *WithdrawNonceAccount {
inst.AccountMetaSlice[2] = ag_solanago.Meta(SysVarRecentBlockHashesPubkey)
return inst
}
func (inst *WithdrawNonceAccount) GetSysVarRecentBlockHashesPubkeyAccount() *ag_solanago.AccountMeta {
return inst.AccountMetaSlice[2]
}
// Rent sysvar
func (inst *WithdrawNonceAccount) SetSysVarRentPubkeyAccount(SysVarRentPubkey ag_solanago.PublicKey) *WithdrawNonceAccount {
inst.AccountMetaSlice[3] = ag_solanago.Meta(SysVarRentPubkey)
return inst
}
func (inst *WithdrawNonceAccount) GetSysVarRentPubkeyAccount() *ag_solanago.AccountMeta {
return inst.AccountMetaSlice[3]
}
// Nonce authority
func (inst *WithdrawNonceAccount) SetNonceAuthorityAccount(nonceAuthorityAccount ag_solanago.PublicKey) *WithdrawNonceAccount {
inst.AccountMetaSlice[4] = ag_solanago.Meta(nonceAuthorityAccount).SIGNER()
return inst
}
func (inst *WithdrawNonceAccount) GetNonceAuthorityAccount() *ag_solanago.AccountMeta {
return inst.AccountMetaSlice[4]
}
func (inst WithdrawNonceAccount) Build() *Instruction {
return &Instruction{BaseVariant: ag_binary.BaseVariant{
Impl: inst,
TypeID: ag_binary.TypeIDFromUint32(Instruction_WithdrawNonceAccount, binary.LittleEndian),
}}
}
// ValidateAndBuild validates the instruction parameters and accounts;
// if there is a validation error, it returns the error.
// Otherwise, it builds and returns the instruction.
func (inst WithdrawNonceAccount) ValidateAndBuild() (*Instruction, error) {
if err := inst.Validate(); err != nil {
return nil, err
}
return inst.Build(), nil
}
func (inst *WithdrawNonceAccount) Validate() error {
// Check whether all (required) parameters are set:
{
if inst.Lamports == nil {
return errors.New("Lamports parameter is not set")
}
}
// 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 *WithdrawNonceAccount) EncodeToTree(parent ag_treeout.Branches) {
parent.Child(ag_format.Program(ProgramName, ProgramID)).
//
ParentFunc(func(programBranch ag_treeout.Branches) {
programBranch.Child(ag_format.Instruction("WithdrawNonceAccount")).
//
ParentFunc(func(instructionBranch ag_treeout.Branches) {
// Parameters of the instruction:
instructionBranch.Child("Params").ParentFunc(func(paramsBranch ag_treeout.Branches) {
paramsBranch.Child(ag_format.Param("Lamports", *inst.Lamports))
})
// Accounts of the instruction:
instructionBranch.Child("Accounts").ParentFunc(func(accountsBranch ag_treeout.Branches) {
accountsBranch.Child(ag_format.Meta("NonceAccount", inst.AccountMetaSlice[0]))
accountsBranch.Child(ag_format.Meta("RecipientAccount", inst.AccountMetaSlice[1]))
accountsBranch.Child(ag_format.Meta("$(SysVarRecentBlockHashesPubkey)", inst.AccountMetaSlice[2]))
accountsBranch.Child(ag_format.Meta("$(SysVarRentPubkey)", inst.AccountMetaSlice[3]))
accountsBranch.Child(ag_format.Meta("NonceAuthorityAccount", inst.AccountMetaSlice[4]))
})
})
})
}
func (inst WithdrawNonceAccount) MarshalWithEncoder(encoder *ag_binary.Encoder) error {
// Serialize `Lamports` param:
{
err := encoder.Encode(*inst.Lamports)
if err != nil {
return err
}
}
return nil
}
func (inst *WithdrawNonceAccount) UnmarshalWithDecoder(decoder *ag_binary.Decoder) error {
// Deserialize `Lamports` param:
{
err := decoder.Decode(&inst.Lamports)
if err != nil {
return err
}
}
return nil
}
// NewWithdrawNonceAccountInstruction declares a new WithdrawNonceAccount instruction with the provided parameters and accounts.
func NewWithdrawNonceAccountInstruction(
// Parameters:
lamports uint64,
// Accounts:
nonceAccount ag_solanago.PublicKey,
recipientAccount ag_solanago.PublicKey,
SysVarRecentBlockHashesPubkey ag_solanago.PublicKey,
SysVarRentPubkey ag_solanago.PublicKey,
nonceAuthorityAccount ag_solanago.PublicKey) *WithdrawNonceAccount {
return NewWithdrawNonceAccountInstructionBuilder().
SetLamports(lamports).
SetNonceAccount(nonceAccount).
SetRecipientAccount(recipientAccount).
SetSysVarRecentBlockHashesPubkeyAccount(SysVarRecentBlockHashesPubkey).
SetSysVarRentPubkeyAccount(SysVarRentPubkey).
SetNonceAuthorityAccount(nonceAuthorityAccount)
}

View File

@ -0,0 +1,31 @@
package system
import (
"bytes"
ag_gofuzz "github.com/google/gofuzz"
ag_require "github.com/stretchr/testify/require"
"strconv"
"testing"
)
func TestEncodeDecode_WithdrawNonceAccount(t *testing.T) {
fu := ag_gofuzz.New().NilChance(0)
for i := 0; i < 1; i++ {
t.Run("WithdrawNonceAccount"+strconv.Itoa(i), func(t *testing.T) {
{
params := new(WithdrawNonceAccount)
fu.Fuzz(params)
params.AccountMetaSlice = nil
buf := new(bytes.Buffer)
err := encodeT(*params, buf)
ag_require.NoError(t, err)
//
got := new(WithdrawNonceAccount)
err = decodeT(got, buf.Bytes())
got.AccountMetaSlice = nil
ag_require.NoError(t, err)
ag_require.Equal(t, params, got)
}
})
}
}

View File

@ -0,0 +1 @@
package system

View File

@ -1,16 +1,5 @@
// Copyright 2020 dfuse Platform Inc.
//
// 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.
// Create new accounts, allocate account data, assign accounts to owning programs,
// transfer lamports from System Program owned accounts and pay transacation fees.
package system
@ -18,62 +7,67 @@ import (
"bytes"
"encoding/binary"
"fmt"
"github.com/davecgh/go-spew/spew"
bin "github.com/dfuse-io/binary"
solana "github.com/gagliardetto/solana-go"
"github.com/gagliardetto/solana-go/text"
"github.com/gagliardetto/treeout"
ag_spew "github.com/davecgh/go-spew/spew"
ag_binary "github.com/dfuse-io/binary"
ag_solanago "github.com/gagliardetto/solana-go"
ag_text "github.com/gagliardetto/solana-go/text"
ag_treeout "github.com/gagliardetto/treeout"
)
var (
ProgramID = solana.MustPublicKeyFromBase58("11111111111111111111111111111111")
)
var ProgramID ag_solanago.PublicKey = ag_solanago.MustPublicKeyFromBase58("11111111111111111111111111111111")
func SetProgramID(pubkey ag_solanago.PublicKey) {
ProgramID = pubkey
ag_solanago.RegisterInstructionDecoder(ProgramID, registryDecodeInstruction)
}
const ProgramName = "System"
func init() {
solana.RegisterInstructionDecoder(ProgramID, registryDecodeInstruction)
if !ProgramID.IsZero() {
ag_solanago.RegisterInstructionDecoder(ProgramID, registryDecodeInstruction)
}
}
const (
// Create a new account.
// Create a new account
Instruction_CreateAccount uint32 = iota
// Assign account to a program.
// Assign account to a program
Instruction_Assign
// Transfer lamports.
// Transfer lamports
Instruction_Transfer
// Create a new account at an address derived from a base pubkey and a seed.
// Create a new account at an address derived from a base pubkey and a seed
Instruction_CreateAccountWithSeed
// Consumes a stored nonce, replacing it with a successor.
// Consumes a stored nonce, replacing it with a successor
Instruction_AdvanceNonceAccount
// Withdraw funds from a nonce account.
// Withdraw funds from a nonce account
Instruction_WithdrawNonceAccount
// Drive state of Uninitalized nonce account to Initialized, setting the nonce value.
// Drive state of Uninitalized nonce account to Initialized, setting the nonce value
Instruction_InitializeNonceAccount
// Change the entity authorized to execute nonce instructions on the account.
// Change the entity authorized to execute nonce instructions on the account
Instruction_AuthorizeNonceAccount
// Allocate space in a (possibly new) account without funding.
// Allocate space in a (possibly new) account without funding
Instruction_Allocate
// Allocate space for and assign an account at an address derived from a base public key and a seed.
// Allocate space for and assign an account at an address derived from a base public key and a seed
Instruction_AllocateWithSeed
// Assign account to a program based on a seed.
// Assign account to a program based on a seed
Instruction_AssignWithSeed
// Transfer lamports from a derived address.
// Transfer lamports from a derived address
Instruction_TransferWithSeed
)
// InstructionIDToName returns the name of the instruction given its ID.
func InstructionIDToName(id uint32) string {
switch id {
case Instruction_CreateAccount:
@ -106,103 +100,92 @@ func InstructionIDToName(id uint32) string {
}
type Instruction struct {
bin.BaseVariant
ag_binary.BaseVariant
}
var _ bin.EncoderDecoder = &Instruction{}
func (inst *Instruction) EncodeToTree(parent ag_treeout.Branches) {
if enToTree, ok := inst.Impl.(ag_text.EncodableToTree); ok {
enToTree.EncodeToTree(parent)
} else {
parent.Child(ag_spew.Sdump(inst))
}
}
var (
// TODO: each instruction must be here:
_ solana.AccountsGettable = &CreateAccount{}
_ solana.AccountsSettable = &CreateAccount{}
_ solana.AccountsGettable = &Assign{}
_ solana.AccountsSettable = &Assign{}
_ solana.AccountsGettable = &Transfer{}
_ solana.AccountsSettable = &Transfer{}
_ solana.AccountsGettable = &CreateAccountWithSeed{}
_ solana.AccountsSettable = &CreateAccountWithSeed{}
_ solana.AccountsGettable = &AdvanceNonceAccount{}
_ solana.AccountsSettable = &AdvanceNonceAccount{}
_ solana.AccountsGettable = &WithdrawNonceAccount{}
_ solana.AccountsSettable = &WithdrawNonceAccount{}
_ solana.AccountsGettable = &InitializeNonceAccount{}
_ solana.AccountsSettable = &InitializeNonceAccount{}
_ solana.AccountsGettable = &AuthorizeNonceAccount{}
_ solana.AccountsSettable = &AuthorizeNonceAccount{}
_ solana.AccountsGettable = &Allocate{}
_ solana.AccountsSettable = &Allocate{}
_ solana.AccountsGettable = &AllocateWithSeed{}
_ solana.AccountsSettable = &AllocateWithSeed{}
_ solana.AccountsGettable = &AssignWithSeed{}
_ solana.AccountsSettable = &AssignWithSeed{}
_ solana.AccountsGettable = &TransferWithSeed{}
_ solana.AccountsSettable = &TransferWithSeed{}
var InstructionImplDef = ag_binary.NewVariantDefinition(
ag_binary.Uint32TypeIDEncoding,
[]ag_binary.VariantType{
{
"CreateAccount", (*CreateAccount)(nil),
},
{
"Assign", (*Assign)(nil),
},
{
"Transfer", (*Transfer)(nil),
},
{
"CreateAccountWithSeed", (*CreateAccountWithSeed)(nil),
},
{
"AdvanceNonceAccount", (*AdvanceNonceAccount)(nil),
},
{
"WithdrawNonceAccount", (*WithdrawNonceAccount)(nil),
},
{
"InitializeNonceAccount", (*InitializeNonceAccount)(nil),
},
{
"AuthorizeNonceAccount", (*AuthorizeNonceAccount)(nil),
},
{
"Allocate", (*Allocate)(nil),
},
{
"AllocateWithSeed", (*AllocateWithSeed)(nil),
},
{
"AssignWithSeed", (*AssignWithSeed)(nil),
},
{
"TransferWithSeed", (*TransferWithSeed)(nil),
},
},
)
func (ins *Instruction) Accounts() (out []*solana.AccountMeta) {
return ins.Impl.(solana.AccountsGettable).GetAccounts()
}
// InstructionImplDef is used for deciding binary,
// encoding and decoding json.
var InstructionImplDef = bin.NewVariantDefinition(
bin.Uint32TypeIDEncoding,
[]bin.VariantType{
// TODO:
{"create_account", (*CreateAccount)(nil)},
{"assign", (*Assign)(nil)},
{"transfer", (*Transfer)(nil)},
{"create_account_with_seed", (*CreateAccountWithSeed)(nil)},
{"advance_nonce_account", (*AdvanceNonceAccount)(nil)},
{"withdraw_nonce_account", (*WithdrawNonceAccount)(nil)},
{"initialize_nonce_account", (*InitializeNonceAccount)(nil)},
{"authorize_nonce_account", (*AuthorizeNonceAccount)(nil)},
{"allocate", (*Allocate)(nil)},
{"allocate_with_seed", (*AllocateWithSeed)(nil)},
{"assign_with_seed", (*AssignWithSeed)(nil)},
{"transfer_with_seed", (*TransferWithSeed)(nil)},
})
func (i *Instruction) ProgramID() solana.PublicKey {
func (inst *Instruction) ProgramID() ag_solanago.PublicKey {
return ProgramID
}
func (i *Instruction) Data() ([]byte, error) {
func (inst *Instruction) Accounts() (out []*ag_solanago.AccountMeta) {
return inst.Impl.(ag_solanago.AccountsGettable).GetAccounts()
}
func (inst *Instruction) Data() ([]byte, error) {
buf := new(bytes.Buffer)
if err := bin.NewBinEncoder(buf).Encode(i); err != nil {
if err := ag_binary.NewBinEncoder(buf).Encode(inst); err != nil {
return nil, fmt.Errorf("unable to encode instruction: %w", err)
}
return buf.Bytes(), nil
}
func (i *Instruction) TextEncode(encoder *text.Encoder, option *text.Option) error {
return encoder.Encode(i.Impl, option)
func (inst *Instruction) TextEncode(encoder *ag_text.Encoder, option *ag_text.Option) error {
return encoder.Encode(inst.Impl, option)
}
func (i *Instruction) UnmarshalWithDecoder(decoder *bin.Decoder) error {
return i.BaseVariant.UnmarshalBinaryVariant(decoder, InstructionImplDef)
func (inst *Instruction) UnmarshalWithDecoder(decoder *ag_binary.Decoder) error {
return inst.BaseVariant.UnmarshalBinaryVariant(decoder, InstructionImplDef)
}
func (i *Instruction) MarshalWithEncoder(encoder *bin.Encoder) error {
err := encoder.WriteUint32(i.TypeID, binary.LittleEndian)
func (inst *Instruction) MarshalWithEncoder(encoder *ag_binary.Encoder) error {
err := encoder.WriteUint32(inst.TypeID.Uint32(), binary.LittleEndian)
if err != nil {
return fmt.Errorf("unable to write variant type: %w", err)
}
return encoder.Encode(i.Impl)
return encoder.Encode(inst.Impl)
}
func registryDecodeInstruction(accounts []*solana.AccountMeta, data []byte) (interface{}, error) {
func registryDecodeInstruction(accounts []*ag_solanago.AccountMeta, data []byte) (interface{}, error) {
inst, err := DecodeInstruction(accounts, data)
if err != nil {
return nil, err
@ -210,26 +193,16 @@ func registryDecodeInstruction(accounts []*solana.AccountMeta, data []byte) (int
return inst, nil
}
func DecodeInstruction(accounts []*solana.AccountMeta, data []byte) (*Instruction, error) {
var inst *Instruction
if err := bin.NewBinDecoder(data).Decode(&inst); err != nil {
func DecodeInstruction(accounts []*ag_solanago.AccountMeta, data []byte) (*Instruction, error) {
inst := new(Instruction)
if err := ag_binary.NewBinDecoder(data).Decode(inst); err != nil {
return nil, fmt.Errorf("unable to decode instruction: %w", err)
}
if v, ok := inst.Impl.(solana.AccountsSettable); ok {
if v, ok := inst.Impl.(ag_solanago.AccountsSettable); ok {
err := v.SetAccounts(accounts)
if err != nil {
return nil, fmt.Errorf("unable to set accounts for instruction: %w", err)
}
}
return inst, nil
}
func (inst *Instruction) EncodeToTree(parent treeout.Branches) {
if enToTree, ok := inst.Impl.(text.EncodableToTree); ok {
enToTree.EncodeToTree(parent)
} else {
parent.Child(spew.Sdump(inst))
}
}

View File

@ -1,23 +0,0 @@
// Copyright 2020 dfuse Platform Inc.
//
// 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 system
import (
"testing"
)
func TestSystemInstructions(t *testing.T) {
t.Skip()
}

View File

@ -0,0 +1,18 @@
package system
import (
"bytes"
"fmt"
ag_binary "github.com/dfuse-io/binary"
)
func encodeT(data interface{}, buf *bytes.Buffer) error {
if err := ag_binary.NewBinEncoder(buf).Encode(data); err != nil {
return fmt.Errorf("unable to encode instruction: %w", err)
}
return nil
}
func decodeT(dst interface{}, data []byte) error {
return ag_binary.NewBinDecoder(data).Decode(dst)
}

1
programs/system/types.go Normal file
View File

@ -0,0 +1 @@
package system

View File

@ -83,7 +83,7 @@ func (i *Instruction) UnmarshalWithDecoder(decoder *bin.Decoder) (err error) {
}
func (i *Instruction) MarshalWithEncoder(encoder *bin.Encoder) error {
err := encoder.WriteUint8(uint8(i.TypeID))
err := encoder.WriteUint8(i.TypeID.Uint8())
if err != nil {
return fmt.Errorf("unable to write variant type: %w", err)
}

View File

@ -42,7 +42,7 @@ func DecodeInstruction(accounts []*solana.AccountMeta, data []byte) (*Instructio
func NewRegisterTokenInstruction(logo Logo, name Name, symbol Symbol, website Website, tokenMetaKey, ownerKey, tokenKey solana.PublicKey) *Instruction {
return &Instruction{
BaseVariant: bin.BaseVariant{
TypeID: 0,
TypeID: bin.TypeIDFromUint32(0, bin.LE()),
Impl: &RegisterToken{
Logo: logo,
Name: name,
@ -66,7 +66,7 @@ var _ bin.EncoderDecoder = &Instruction{}
func (i *Instruction) Accounts() (out []*solana.AccountMeta) {
switch i.TypeID {
case 0:
case bin.TypeIDFromUint32(0, bin.LE()):
accounts := i.Impl.(*RegisterToken).Accounts
out = []*solana.AccountMeta{accounts.TokenMeta, accounts.Owner, accounts.Token}
}
@ -98,7 +98,7 @@ func (i *Instruction) UnmarshalWithDecoder(decoder *bin.Decoder) (err error) {
}
func (i *Instruction) MarshalWithEncoder(encoder *bin.Encoder) error {
err := encoder.WriteUint32(i.TypeID, binary.LittleEndian)
err := encoder.WriteUint32(i.TypeID.Uint32(), binary.LittleEndian)
if err != nil {
return fmt.Errorf("unable to write variant type: %w", err)
}