-
Notifications
You must be signed in to change notification settings - Fork 4
/
esplora.go
128 lines (103 loc) · 2.98 KB
/
esplora.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"github.com/vulpemventures/go-elements/transaction"
)
type Transaction struct {
TxID string `json:"txid"`
Status struct {
Confirmed bool `json:"confirmed"`
BlockHeight int `json:"block_height"`
BlockHash string `json:"block_hash"`
BlockTime int `json:"block_time"`
} `json:"status"`
}
type Esplora struct {
BaseAPIURL string
NetworkName string
}
var EsploraAPIURLs = map[string]string{
"liquid": "https://blockstream.info/liquid/api",
"testnet": "https://blockstream.info/liquidtestnet/api",
"regtest": "http://localhost:3001",
}
var EsploraURLs = map[string]string{
"liquid": "https://blockstream.info/liquid",
"testnet": "https://blockstream.info/liquidtestnet",
"regtest": "http://localhost:5001",
}
func NewEsplora(networkName string) (*Esplora, error) {
// Get the base API URL for the network
baseAPIURL, ok := EsploraAPIURLs[networkName]
if !ok {
return nil, fmt.Errorf("invalid network %s", networkName)
}
return &Esplora{
BaseAPIURL: baseAPIURL,
NetworkName: networkName,
}, nil
}
func (e *Esplora) FetchTransactionHistory(address string) ([]Transaction, error) {
apiURL := fmt.Sprintf("%s/address/%s/txs", e.BaseAPIURL, address)
resp, err := http.Get(apiURL)
if err != nil {
return nil, fmt.Errorf("error fetching transaction history: %w", err)
}
body, err := io.ReadAll(resp.Body)
resp.Body.Close()
if err != nil {
return nil, fmt.Errorf("error reading response body: %w", err)
}
var transactions []Transaction
err = json.Unmarshal(body, &transactions)
if err != nil {
return nil, fmt.Errorf("error unmarshaling JSON: %w", err)
}
return transactions, nil
}
func (e *Esplora) FetchPrevout(txHash string, txIndex int) (*transaction.TxOutput, error) {
apiURL := fmt.Sprintf("%s/tx/%s/hex", e.BaseAPIURL, txHash)
resp, err := http.Get(apiURL)
if err != nil {
return nil, fmt.Errorf("error fetching raw transaction: %v", err)
}
body, err := io.ReadAll(resp.Body)
resp.Body.Close()
if err != nil {
return nil, fmt.Errorf("error reading response body: %v", err)
}
tx, err := transaction.NewTxFromHex(string(body))
if err != nil {
return nil, fmt.Errorf("error creating transaction from hex: %v", err)
}
txOutput := tx.Outputs[txIndex]
return txOutput, nil
}
func (e *Esplora) FetchUnspents(address string) ([]*UTXO, error) {
apiURL := fmt.Sprintf("%s/address/%s/utxo", e.BaseAPIURL, address)
resp, err := http.Get(apiURL)
if err != nil {
return nil, fmt.Errorf("error fetching UTXOs: %v", err)
}
body, err := io.ReadAll(resp.Body)
resp.Body.Close()
if err != nil {
return nil, fmt.Errorf("error reading response body: %v", err)
}
var utxos []*UTXO
err = json.Unmarshal(body, &utxos)
if err != nil {
return nil, fmt.Errorf("error unmarshaling JSON: %v", err)
}
for _, unspent := range utxos {
prevout, err := e.FetchPrevout(unspent.Txid, unspent.Index)
if err != nil {
return nil, err
}
unspent.Prevout = prevout
}
return utxos, nil
}