planetmint-go/lib/utils.go
Julian Strobl 77cd83655d
refactor(lib): wip
Signed-off-by: Julian Strobl <jmastr@mailbox.org>
2024-11-22 16:22:46 +01:00

112 lines
2.9 KiB
Go

package lib
import (
"bufio"
"bytes"
"encoding/hex"
"encoding/json"
"fmt"
"os"
"os/user"
"path/filepath"
"regexp"
"strconv"
"strings"
"github.com/cosmos/cosmos-sdk/client"
sdk "github.com/cosmos/cosmos-sdk/types"
"sigs.k8s.io/yaml"
)
func readSequenceFromFile(seqFile *os.File) (sequence uint64, err error) {
scanner := bufio.NewScanner(seqFile)
// read the first line
if !scanner.Scan() {
if err := scanner.Err(); err != nil {
return 0, fmt.Errorf("reading sequence file: %w", err)
}
return 0, fmt.Errorf("sequence file empty: %s", seqFile.Name())
}
sequenceString := scanner.Text()
// check for additional lines
if scanner.Scan() {
return 0, fmt.Errorf("malformed sequence file %s: contains multiple lines", seqFile.Name())
}
sequence, err = strconv.ParseUint(sequenceString, 10, 64)
if err != nil {
return 0, fmt.Errorf("parsing sequence number: %w", err)
}
return
}
func getSequenceFromChain(clientCtx client.Context) (sequence uint64, err error) {
account, err := clientCtx.AccountRetriever.GetAccount(clientCtx, clientCtx.FromAddress)
if err != nil {
return 0, fmt.Errorf("retrieving account: %w", err)
}
return account.GetSequence(), nil
}
func getOrCreateSequenceDirectory() (path string, err error) {
usr, err := user.Current()
if err != nil {
return "", fmt.Errorf("getting current user: %w", err)
}
path = filepath.Join(GetConfig().RootDir, "sequence")
// expand tilde to user's home directory
if strings.HasPrefix(path, "~/") {
path = filepath.Join(usr.HomeDir, path[2:])
}
// create directory if it doesn't exist
if err := os.MkdirAll(path, os.ModePerm); err != nil {
return "", fmt.Errorf("creating sequence directory: %w", err)
}
return
}
func openSequenceFile(fromAddress sdk.AccAddress) (file *os.File, err error) {
path, err := getOrCreateSequenceDirectory()
if err != nil {
return
}
addrHex := hex.EncodeToString(fromAddress)
filename := filepath.Join(path, addrHex)
file, err = os.OpenFile(filename, os.O_RDWR|os.O_CREATE, 0644)
if err != nil {
return nil, fmt.Errorf("opening sequence file: %w", err)
}
return
}
// ParseTxResponse converts output buffer to TxResponse
func ParseTxResponse(out *bytes.Buffer) (txResponse sdk.TxResponse, err error) {
// Convert string numbers to actual numbers
numericRegex := regexp.MustCompile(`"([0-9]+?)"`)
jsonStr := numericRegex.ReplaceAllString(out.String(), "${1}")
// We might have YAML here, so we need to convert to JSON first, because TxResponse struct lacks `yaml:"height,omitempty"`, etc.
// Since JSON is a subset of YAML, passing JSON through YAMLToJSON is a no-op and the result is the byte array of the JSON again.
jsonBytes, err := yaml.YAMLToJSON([]byte(jsonStr))
if err != nil {
return sdk.TxResponse{}, fmt.Errorf("converting YAML to JSON: %w", err)
}
if err := json.Unmarshal(jsonBytes, &txResponse); err != nil {
return sdk.TxResponse{}, fmt.Errorf("unmarshaling transaction response: %w", err)
}
return
}