From b049170621d7077043da05f0fc06059a02bb1523 Mon Sep 17 00:00:00 2001 From: Gaze Date: Thu, 6 Jun 2024 21:44:13 +0700 Subject: [PATCH] feat: create common utils for api --- common/http.go | 6 ++++ pkg/btcutils/pkscript.go | 63 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+) create mode 100644 common/http.go create mode 100644 pkg/btcutils/pkscript.go diff --git a/common/http.go b/common/http.go new file mode 100644 index 0000000..d5055b5 --- /dev/null +++ b/common/http.go @@ -0,0 +1,6 @@ +package common + +type HttpResponse[T any] struct { + Error *string `json:"error"` + Result *T `json:"result,omitempty"` +} diff --git a/pkg/btcutils/pkscript.go b/pkg/btcutils/pkscript.go new file mode 100644 index 0000000..d08a0b3 --- /dev/null +++ b/pkg/btcutils/pkscript.go @@ -0,0 +1,63 @@ +package btcutils + +import ( + "encoding/hex" + + "github.com/btcsuite/btcd/btcutil" + "github.com/btcsuite/btcd/chaincfg" + "github.com/btcsuite/btcd/txscript" + "github.com/gaze-network/indexer-network/common" + "github.com/gaze-network/indexer-network/common/errs" + "github.com/pkg/errors" +) + +// ToPkScript converts a string of address or pkscript to bytes of pkscript +func ToPkScript(network common.Network, from string) ([]byte, error) { + if from == "" { + return nil, errors.Wrap(errs.InvalidArgument, "empty input") + } + + defaultNet, err := func() (*chaincfg.Params, error) { + switch network { + case common.NetworkMainnet: + return &chaincfg.MainNetParams, nil + case common.NetworkTestnet: + return &chaincfg.TestNet3Params, nil + default: + return nil, errors.Wrap(errs.InvalidArgument, "invalid network") + } + }() + if err != nil { + return nil, err + } + + // attempt to parse as address + address, err := btcutil.DecodeAddress(from, defaultNet) + if err == nil { + pkScript, err := txscript.PayToAddrScript(address) + if err != nil { + return nil, errors.Wrap(err, "error converting address to pkscript") + } + return pkScript, nil + } + + // attempt to parse as pkscript + pkScript, err := hex.DecodeString(from) + if err != nil { + return nil, errors.Wrap(err, "error decoding pkscript") + } + + return pkScript, nil +} + +// PkScriptToAddress returns the address from the given pkScript. If the pkScript is invalid or not standard, it returns empty string. +func PkScriptToAddress(pkScript []byte, network common.Network) (string, error) { + _, addrs, _, err := txscript.ExtractPkScriptAddrs(pkScript, network.ChainParams()) + if err != nil { + return "", errors.Wrap(err, "error extracting addresses from pkscript") + } + if len(addrs) != 1 { + return "", errors.New("invalid number of addresses extracted from pkscript") + } + return addrs[0].EncodeAddress(), nil +}