func NewChainVerifier(cfgMain *chaincfg.Params, side clients.SidechainClient, position int, script string, chaincodesStr []string, host string) ChainVerifier {
	pubkeys, numOfSigs := crypto.ParseRedeemScript(script)
	if len(chaincodesStr) != len(pubkeys) {
		log.Fatalf("Missing chaincodes for pubkeys %d != %d", len(chaincodesStr), len(pubkeys))
	}
	chaincodes := make([][]byte, len(pubkeys))
	for i_c := range chaincodesStr {
		ccBytes, ccBytesErr := hex.DecodeString(chaincodesStr[i_c])
		if ccBytesErr != nil || len(ccBytes) != 32 {
			log.Fatalf("Invalid chaincode provided %s", chaincodesStr[i_c])
		}
		chaincodes[i_c] = append(chaincodes[i_c], ccBytes...)
	}
	var pubkeysExtended []*hdkeychain.ExtendedKey
	for i_p, pub := range pubkeys {
		pubkeysExtended = append(pubkeysExtended,
			hdkeychain.NewExtendedKey([]byte{}, pub.SerializeCompressed(), chaincodes[i_p], []byte{}, 0, 0, false))
	}
	return ChainVerifier{side, host, cfgMain, position, pubkeysExtended, numOfSigs, 0}
}
Return new Chain Verifier instance that verifies attestations on the side chain
package staychain
import (
	"encoding/hex"
	"encoding/json"
	"fmt"
	"log"
	"net/http"
	"mainstay/clients"
	"mainstay/crypto"
	"mainstay/models"
	"github.com/btcsuite/btcd/btcec"
	"github.com/btcsuite/btcd/chaincfg"
	"github.com/btcsuite/btcd/chaincfg/chainhash"
	"github.com/btcsuite/btcutil/hdkeychain"
)
const (
	ApiAttestationUrl     = "/api/v1/attestation"
	ApiCommitmentUrl      = "/api/v1/commitment"
	ApiCommitmentProofUrl = "/api/v1/commitment/proof"
)
func getApiResponse(url string) (map[string]interface{}, error) {
	resp, getErr := http.Get(url)
	if getErr != nil {
		return nil, &ChainVerifierError{"API request failed"}
	}
	defer resp.Body.Close()
	dec := json.NewDecoder(resp.Body)
	var respJson map[string]interface{}
	decErr := dec.Decode(&respJson)
	if decErr != nil {
		return nil, &ChainVerifierError{"API response decoding failed"}
	}
	respMap, ok := respJson["response"]
	if !ok {
		return nil, &ChainVerifierError{fmt.Sprintf("API response decoding failed\n%v\n", respJson["error"])}
	}
	return respMap.(map[string]interface{}), nil
}
type ChainVerifierInfo struct {
	hash   chainhash.Hash
	height int64
}
func (i *ChainVerifierInfo) Hash() chainhash.Hash {
	return i.hash
}
func (i *ChainVerifierInfo) Height() int64 {
	return i.height
}
type ChainVerifierError struct {
	errstr string
}
func (e *ChainVerifierError) Error() string {
	return e.errstr
}
type ChainVerifier struct {
	sideClient   clients.SidechainClient
	apiHost      string
	cfgMain      *chaincfg.Params
	position     int
	pubkeys      []*hdkeychain.ExtendedKey
	numOfSigs    int
	latestHeight int64
}