refactor
This commit is contained in:
15
verifyer/bitcoin.go
Normal file
15
verifyer/bitcoin.go
Normal file
@@ -0,0 +1,15 @@
|
||||
package verifyer
|
||||
|
||||
import (
|
||||
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||
"github.com/btcsuite/btcd/rpcclient"
|
||||
"github.com/btcsuite/btcd/wire"
|
||||
)
|
||||
|
||||
type Bitcoin interface {
|
||||
GetBlockHash(height int64) (*chainhash.Hash, error)
|
||||
GetBlockHeader(hash *chainhash.Hash) (*wire.BlockHeader, error)
|
||||
}
|
||||
|
||||
var _ Bitcoin = (*esplora)(nil)
|
||||
var _ Bitcoin = (*rpcclient.Client)(nil)
|
||||
7
verifyer/bitcoind.go
Normal file
7
verifyer/bitcoind.go
Normal file
@@ -0,0 +1,7 @@
|
||||
package verifyer
|
||||
|
||||
import "github.com/btcsuite/btcd/rpcclient"
|
||||
|
||||
func NewBitcoindInterface(config rpcclient.ConnConfig) (Bitcoin, error) {
|
||||
return rpcclient.New(&config, nil)
|
||||
}
|
||||
85
verifyer/esplora.go
Normal file
85
verifyer/esplora.go
Normal file
@@ -0,0 +1,85 @@
|
||||
package verifyer
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"slices"
|
||||
|
||||
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||
"github.com/btcsuite/btcd/wire"
|
||||
)
|
||||
|
||||
// esplora is a client for the Esplora API, which provides access to Bitcoin
|
||||
// blockchain data.
|
||||
type esplora struct {
|
||||
httpClient *http.Client
|
||||
baseURL string
|
||||
}
|
||||
|
||||
func NewEsploraClient(url string, timeout time.Duration) Bitcoin {
|
||||
url = strings.TrimSuffix(url, "/")
|
||||
|
||||
h := &http.Client{
|
||||
Timeout: timeout,
|
||||
}
|
||||
|
||||
return esplora{h, url}
|
||||
}
|
||||
|
||||
func (e esplora) GetBlockHash(height int64) (*chainhash.Hash, error) {
|
||||
resp, err := e.httpClient.Get(e.baseURL + "/block-height/" + strconv.FormatInt(height, 10))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get block hash: %w", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
hexb, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to read block hash: %w", err)
|
||||
}
|
||||
|
||||
hash, err := hex.DecodeString(string(hexb))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to decode block hash: %w", err)
|
||||
}
|
||||
if len(hash) != chainhash.HashSize {
|
||||
return nil, fmt.Errorf("got block hash (%x) of invalid size (expected %d)", hash, chainhash.HashSize)
|
||||
}
|
||||
|
||||
slices.Reverse(hash)
|
||||
var chash chainhash.Hash
|
||||
copy(chash[:], hash)
|
||||
return &chash, nil
|
||||
}
|
||||
|
||||
func (e esplora) GetBlockHeader(hash *chainhash.Hash) (*wire.BlockHeader, error) {
|
||||
resp, err := e.httpClient.Get(fmt.Sprintf("%s/block/%s/header", e.baseURL, hash.String()))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
hexb, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
headerHash, err := hex.DecodeString(string(hexb))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
header := &wire.BlockHeader{}
|
||||
if err := header.BtcDecode(bytes.NewBuffer(headerHash), 0, 0); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return header, nil
|
||||
}
|
||||
Reference in New Issue
Block a user