Upgrade bin package; use generated system program client.
This commit is contained in:
parent
f4fb6389da
commit
3853032c9c
|
@ -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
7
go.mod
|
@ -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
8
go.sum
|
@ -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=
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
},
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
|
@ -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)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
|
@ -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)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
|
@ -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)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
|
@ -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)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
package system
|
|
@ -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))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
}
|
|
@ -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)
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
package system
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue