Skip to content

Commit

Permalink
Merge pull request #16 from DarkLord017/implemented_core
Browse files Browse the repository at this point in the history
Implemented core
  • Loading branch information
Sh0g0-1758 authored Sep 22, 2024
2 parents 9000ffb + adac2a1 commit a64ef4b
Showing 1 changed file with 160 additions and 0 deletions.
160 changes: 160 additions & 0 deletions athena_abi/core.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
package athena_abi

import (
"errors"
"log"
)

type StarknetABI struct {
ABIName *string
ClassHash []byte
Functions map[string]AbiFunction
Events map[string]AbiEvent
Constructor []AbiParameter
L1Handler *AbiFunction
ImplementedInterfaces map[string]AbiInterface
}

// Declare errors
var (
errParseDefinedTypes = errors.New("unable to parse defined types")
errParseInterfaces = errors.New("unable to parse interfaces")
errParseFunctions = errors.New("unable to parse functions")
errParseEvents = errors.New("unable to parse events")
errParseConstructor = errors.New("unable to parse constructor")
errParseL1Handler = errors.New("unable to parse L1 handler")
errParseImplementedInterfaces = errors.New("unable to parse implemented interfaces")
)

// Parse Starknet ABI from JSON
// @param abiJSON
// @param abiname
// @param classHash
func StarknetAbiFromJSON(abiJson []map[string]interface{}, abiName string, classHash []byte) (*StarknetABI, error) {
groupedAbi := GroupAbiByType(abiJson)

// Parse defined types (structs and enums)
definedTypes, err := ParseEnumsAndStructs(groupedAbi["type_def"])
if err != nil {
sortedDefs, errDef := TopoSortTypeDefs(groupedAbi["type_def"])
if errDef == nil {
defineTypes, errDtypes := ParseEnumsAndStructs(sortedDefs)
definedTypes = defineTypes
errDef = errDtypes
}
if errDef != nil {
return nil, errParseDefinedTypes
}
log.Println("ABI Struct and Enum definitions out of order & required topological sorting")
}

// Parse interfaces
var definedInterfaces []AbiInterface
for _, iface := range groupedAbi["interface"] {
functions := []AbiFunction{}
for _, funcData := range iface["items"].([]interface{}) {
parsedAbi, errWhileParsing := ParseAbiFunction(funcData.(map[string]interface{}), definedTypes)
if errWhileParsing != nil {
return nil, errParseInterfaces
}
functions = append(functions, *parsedAbi)
}
definedInterfaces = append(definedInterfaces, AbiInterface{
name: iface["name"].(string),
functions: functions,
})
}

// Parse functions
functions := make(map[string]AbiFunction)
for _, functionData := range groupedAbi["function"] {
funcName := functionData["name"].(string)
abiFunc, errParsingFunctions := ParseAbiFunction(functionData, definedTypes)
if errParsingFunctions != nil {
return nil, errParseFunctions
}
functions[funcName] = *abiFunc
}

// Add functions from interfaces
for _, iface := range definedInterfaces {
for _, function := range iface.functions {
functions[function.name] = function
}
}

// Parse events
parsedAbiEvents := []AbiEvent{}
for _, eventData := range groupedAbi["event"] {
parsedEvent, errParsingEvent := ParseAbiEvent(eventData, definedTypes)
if errParsingEvent != nil {
return nil, errParseEvents
}
parsedAbiEvents = append(parsedAbiEvents, *parsedEvent)
}

events := make(map[string]AbiEvent)
for _, event := range parsedAbiEvents {
if event.name != "" {
events[event.name] = event
}
}

// Parse constructor
var constructor []AbiParameter
if len(groupedAbi["constructor"]) == 1 {
for _, paramData := range groupedAbi["constructor"][0]["inputs"].([]interface{}) {
param := paramData.(map[string]interface{})
typed, errorParsingType := parseType(param["type"].(string), definedTypes)
if errorParsingType != nil {
return nil, errParseConstructor
}
constructor = append(constructor, AbiParameter{
Name: param["name"].(string),
Type: typed,
})
}
} else {
constructor = nil
}

// Parse L1 handler
var l1Handler *AbiFunction
if len(groupedAbi["l1_handler"]) == 1 {
handler, errorParsingFunction := ParseAbiFunction(groupedAbi["l1_handler"][0], definedTypes)
if errorParsingFunction != nil {
return nil, errParseL1Handler
}
l1Handler = handler
} else {
l1Handler = nil
}

// Parse implemented interfaces
implementedInterfaces := make(map[string]AbiInterface)
implArray, ok := groupedAbi["impl"]
if !ok {
return nil, errParseImplementedInterfaces
}
for _, implData := range implArray {
implMap := implData
if ifaceName, ok := implMap["interface_name"].(string); ok {
for _, iface := range definedInterfaces {
if iface.name == ifaceName {
implementedInterfaces[iface.name] = iface
}
}
}
}

// Return the populated StarknetAbi struct
return &StarknetABI{
ABIName: &abiName,
ClassHash: classHash,
Functions: functions,
Events: events,
Constructor: constructor,
L1Handler: l1Handler,
ImplementedInterfaces: implementedInterfaces,
}, nil
}

0 comments on commit a64ef4b

Please sign in to comment.