From 8ebbb0bf41af8a9ed3326bead321b5adb22db0a2 Mon Sep 17 00:00:00 2001 From: lumtis Date: Wed, 9 Oct 2024 14:51:51 +0200 Subject: [PATCH] fix generation --- Makefile | 21 +++++--- go-idl/generator/generate.go | 97 ++++++++++++++++++++++++------------ go-idl/generator/main.go | 2 +- go-idl/types/idl.go | 2 +- 4 files changed, 82 insertions(+), 40 deletions(-) diff --git a/Makefile b/Makefile index dc31335..6c9f443 100644 --- a/Makefile +++ b/Makefile @@ -10,11 +10,20 @@ fmt: @./scripts/fmt.sh -# Variables -GENERATOR_DIR := go-idl/generator -IDL_FILE := target/idl/gateway.json -OUTPUT_DIR := go-idl/generated/gateway.go +# directories for Go code generation +IDL_DIR := target/idl +GENERATED_DIR := generated -# Generate go code +# generate Go code from IDL files +.PHONY: generate generate: - go run $(GENERATOR_DIR) $(IDL_FILE) $(OUTPUT_DIR) \ No newline at end of file + @for file in $(wildcard $(IDL_DIR)/*.json); do \ + base_name=$$(basename $$file .json); \ + output_file="$(GENERATED_DIR)/$$base_name.go"; \ + echo "Generating $$output_file from $$file"; \ + (cd go-idl && go run generator/main.go "$$file" "$$output_file"); \ + done + +# clean generated files +clean: + rm -rf $(GENERATED_DIR)/*.go \ No newline at end of file diff --git a/go-idl/generator/generate.go b/go-idl/generator/generate.go index 5db8f3c..404414d 100644 --- a/go-idl/generator/generate.go +++ b/go-idl/generator/generate.go @@ -7,18 +7,25 @@ import ( "github.com/protocol-contracts-solana/go-idl/types" ) +const ( + codeGenerationDisclaimer = `// Code generated by go-idl. DO NOT EDIT.` + idlPrefix = "IDL" + discrimatorNamePrefix = "Discriminator" +) + // generateIDLFile generates the Go code for the IDL struct. func generateIDLFile(packagename, varname string, idl *types.IDL) string { var sb strings.Builder // header + sb.WriteString(fmt.Sprintf("%s\n", codeGenerationDisclaimer)) sb.WriteString(fmt.Sprintf("package %s\n\n", packagename)) sb.WriteString("import (\n") sb.WriteString(" \"github.com/protocol-contracts-solana/go-idl/types\"\n") sb.WriteString(")\n\n") // IDL struct - sb.WriteString(fmt.Sprintf("var %s IDL = ", varname)) + sb.WriteString(fmt.Sprintf("var %s%s = ", idlPrefix, varname)) sb.WriteString(generateIDLTypeCode(idl)) return sb.String() @@ -28,9 +35,9 @@ func generateIDLFile(packagename, varname string, idl *types.IDL) string { func generateIDLTypeCode(idl *types.IDL) string { var sb strings.Builder - sb.WriteString(fmt.Sprintf("IDL{\n")) + sb.WriteString(fmt.Sprintf("types.IDL{\n")) sb.WriteString(fmt.Sprintf(" Address: %q,\n", idl.Address)) - sb.WriteString(fmt.Sprintf(" Metadata: Metadata{\n")) + sb.WriteString(fmt.Sprintf(" Metadata: types.Metadata{\n")) sb.WriteString(fmt.Sprintf(" Name: %q,\n", idl.Metadata.Name)) sb.WriteString(fmt.Sprintf(" Version: %q,\n", idl.Metadata.Version)) sb.WriteString(fmt.Sprintf(" Spec: %q,\n", idl.Metadata.Spec)) @@ -38,51 +45,74 @@ func generateIDLTypeCode(idl *types.IDL) string { sb.WriteString(" },\n") // write instructions - sb.WriteString(" Instructions: []Instruction{\n") + sb.WriteString(" Instructions: []types.Instruction{\n") for _, instr := range idl.Instructions { sb.WriteString(" {\n") sb.WriteString(fmt.Sprintf(" Name: %q,\n", instr.Name)) - sb.WriteString(fmt.Sprintf(" Discriminator: %v,\n", instr.Discriminator)) - sb.WriteString(" Accounts: []Account{\n") + sb.WriteString(fmt.Sprintf(" Discriminator: %v,\n", generateDiscriminatorCode( + instr.Discriminator, + ))) + sb.WriteString(" Accounts: []types.Account{\n") for _, acc := range instr.Accounts { sb.WriteString(generateAccountCode(acc)) } sb.WriteString(" },\n") - sb.WriteString(" Args: []Arg{\n") - for _, arg := range instr.Args { - sb.WriteString(fmt.Sprintf(" {Name: %q, Type: %v},\n", arg.Name, arg.Type)) - } - sb.WriteString(" },\n") + + // TODO: args generation + //sb.WriteString(" Args: []types.Arg{\n") + //for _, arg := range instr.Args { + // sb.WriteString(fmt.Sprintf(" {Name: %q, Type: %v},\n", arg.Name, arg.Type)) + //} + //sb.WriteString(" },\n") + sb.WriteString(" },\n") } sb.WriteString(" },\n") // write accounts - sb.WriteString(" Accounts: []Account{\n") + sb.WriteString(" Accounts: []types.Account{\n") for _, acc := range idl.Accounts { sb.WriteString(generateAccountCode(acc)) } sb.WriteString(" },\n") // write errors - sb.WriteString(" Errors: []Error{\n") + sb.WriteString(" Errors: []types.Error{\n") for _, err := range idl.Errors { sb.WriteString(fmt.Sprintf(" {Code: %d, Name: %q, Msg: %q},\n", err.Code, err.Name, err.Msg)) } sb.WriteString(" },\n") // write types - sb.WriteString(" Types: []Type{\n") - for _, typ := range idl.Types { - sb.WriteString(fmt.Sprintf(" {Name: %q, Type: TypeField{Kind: %q, Fields: []Field{\n", typ.Name, typ.Type.Kind)) - for _, field := range typ.Type.Fields { - sb.WriteString(fmt.Sprintf(" {Name: %q, Type: %v},\n", field.Name, field.Type)) + // TODO: types generation + //sb.WriteString(" Types: []types.Type{\n") + //for _, typ := range idl.Types { + // sb.WriteString(fmt.Sprintf(" {Name: %q, Type: TypeField{Kind: %q, Fields: []Field{\n", typ.Name, typ.Type.Kind)) + // for _, field := range typ.Type.Fields { + // sb.WriteString(fmt.Sprintf(" {Name: %q, Type: %v},\n", field.Name, field.Type)) + // } + // sb.WriteString(" }}},\n") + //} + //sb.WriteString(" },\n") + + sb.WriteString("}\n") + return sb.String() +} + +// generateDiscriminatorCode generates the Go code for a discriminator. +// use format [8]byte{...} +func generateDiscriminatorCode(discriminator [8]byte) string { + var sb strings.Builder + + sb.WriteString("[8]byte{") + for i, b := range discriminator { + sb.WriteString(fmt.Sprintf("%d", b)) + if i < len(discriminator)-1 { + sb.WriteString(", ") } - sb.WriteString(" }}},\n") } - sb.WriteString(" },\n") + sb.WriteString("}") - sb.WriteString("}\n") return sb.String() } @@ -96,17 +126,20 @@ func generateAccountCode(acc types.Account) string { sb.WriteString(fmt.Sprintf(" Signer: %t,\n", acc.Signer)) sb.WriteString(fmt.Sprintf(" Address: %q,\n", acc.Address)) - if acc.PDA != nil { - sb.WriteString(" PDA: &PDA{\n") - sb.WriteString(" Seeds: []Seed{\n") - for _, seed := range acc.PDA.Seeds { - sb.WriteString(fmt.Sprintf(" {Kind: %q, Value: %v},\n", seed.Kind, seed.Value)) - } - sb.WriteString(" },\n") - sb.WriteString(" },\n") - } else { - sb.WriteString(" PDA: nil,\n") - } + // TODO: PDA generation + //if acc.PDA != nil { + // sb.WriteString(" PDA: &types.PDA{\n") + // sb.WriteString(" Seeds: []types.Seed{\n") + // for _, seed := range acc.PDA.Seeds { + // sb.WriteString(fmt.Sprintf(" {Kind: %q, Value: %v},\n", seed.Kind, seed.Value)) + // } + // sb.WriteString(" },\n") + // sb.WriteString(" },\n") + //} else { + // sb.WriteString(" PDA: nil,\n") + //} + + sb.WriteString(" PDA: nil,\n") sb.WriteString(" },\n") return sb.String() diff --git a/go-idl/generator/main.go b/go-idl/generator/main.go index b067afd..7dc8b0a 100644 --- a/go-idl/generator/main.go +++ b/go-idl/generator/main.go @@ -61,7 +61,7 @@ func writeGoFile(idl *types.IDL, outputPath string) error { } // write the Go code to the file - _, err = file.WriteString(generateIDLFile("solana", "IDL", idl)) + _, err = file.WriteString(generateIDLFile("solana", "Gateway", idl)) if err != nil { return fmt.Errorf("failed to write to file: %w", err) } diff --git a/go-idl/types/idl.go b/go-idl/types/idl.go index e84344f..70363af 100644 --- a/go-idl/types/idl.go +++ b/go-idl/types/idl.go @@ -18,7 +18,7 @@ type Metadata struct { type Instruction struct { Name string `json:"name"` - Discriminator []byte `json:"discriminator"` + Discriminator [8]byte `json:"discriminator"` Accounts []Account `json:"accounts"` Args []Arg `json:"args"` }