diff --git a/Address.go b/Address.go index 133f723..92a2351 100644 --- a/Address.go +++ b/Address.go @@ -26,8 +26,11 @@ func (a *Address) GetAddressBalance(address string) (*AddressBalance, error) { if err != nil { return nil, err } - // Parse the data into AddressBalance struct if needed - return &AddressBalance{}, nil + var balance AddressBalance + if err := json.Unmarshal(data, &balance); err != nil { + return nil, err + } + return &balance, nil } func (a *Address) GetAddressTransactions(address string) (*AddressTransactions, error) { @@ -36,8 +39,11 @@ func (a *Address) GetAddressTransactions(address string) (*AddressTransactions, if err != nil { return nil, err } - // Parse the data into AddressTransactions struct if needed - return &AddressTransactions{}, nil + var transactions AddressTransactions + if err := json.Unmarshal(data, &transactions); err != nil { + return nil, err + } + return &transactions, nil } func (a *Address) GetUnconfirmedAddressTransactions(address string) (*AddressTransactions, error) { @@ -46,21 +52,27 @@ func (a *Address) GetUnconfirmedAddressTransactions(address string) (*AddressTra if err != nil { return nil, err } - // Parse the data into AddressTransactions struct if needed - return &AddressTransactions{}, nil + var transactions AddressTransactions + if err := json.Unmarshal(data, &transactions); err != nil { + return nil, err + } + return &transactions, nil } func (a *Address) GetAddressUTXO(address string) (*AddressUTXOs, error) { - url := fmt.Sprintf("%s/address/unconfirmed/transactions/%s", a.apiV1URL, address) + url := fmt.Sprintf("%s/address/utxo/%s", a.apiV1URL, address) data, err := a.get(url) if err != nil { return nil, err } - // Parse the data into AddressUTXOs struct if needed - return &AddressUTXOs{}, nil + var utxos AddressUTXOs + if err := json.Unmarshal(data, &utxos); err != nil { + return nil, err + } + return &utxos, nil } -func (a *Address) get(url string) (interface{}, error) { +func (a *Address) get(url string) ([]byte, error) { resp, err := http.Get(url) if err != nil { a.logger(err.Error()) @@ -74,11 +86,5 @@ func (a *Address) get(url string) (interface{}, error) { return nil, err } - var data interface{} - if err := json.Unmarshal(body, &data); err != nil { - a.logger(err.Error()) - return nil, err - } - - return data, nil + return body, nil } diff --git a/Address_test.go b/Address_test.go index 0795a7e..77b7891 100644 --- a/Address_test.go +++ b/Address_test.go @@ -7,63 +7,75 @@ import ( ) func TestGetAddressBalance(t *testing.T) { - mockServer := createMockServer("address/state/mockAddress", `{"mock": "data"}`) + mockServer := createMockServer("address/state/mockAddress", `{"balance": 42}`) defer mockServer.Close() config := SDKConfig{ - BaseAPIURL: mockServer.URL, + BaseAPIURL: mockServer.URL + "/bgl/v1/blockchain", } addressAPI := NewAddress(config) - _, err := addressAPI.GetAddressBalance("mockAddress") + balance, err := addressAPI.GetAddressBalance("mockAddress") if err != nil { t.Errorf("Expected no error, got %v", err) } + if balance.Balance != 42 { + t.Errorf("Expected balance to be decoded, got %d", balance.Balance) + } } func TestGetAddressTransactions(t *testing.T) { - mockServer := createMockServer("address/transactions/mockAddress", `{"mock": "data"}`) + mockServer := createMockServer("address/transactions/mockAddress", `{"page": 2, "list": [{"txId": "abc"}]}`) defer mockServer.Close() config := SDKConfig{ - BaseAPIURL: mockServer.URL, + BaseAPIURL: mockServer.URL + "/bgl/v1/blockchain", } addressAPI := NewAddress(config) - _, err := addressAPI.GetAddressTransactions("mockAddress") + transactions, err := addressAPI.GetAddressTransactions("mockAddress") if err != nil { t.Errorf("Expected no error, got %v", err) } + if transactions.Page != 2 || len(transactions.List) != 1 || transactions.List[0].TxID != "abc" { + t.Errorf("Expected transactions to be decoded, got %#v", transactions) + } } func TestGetUnconfirmedAddressTransactions(t *testing.T) { - mockServer := createMockServer("address/unconfirmed/transactions/mockAddress", `{"mock": "data"}`) + mockServer := createMockServer("address/unconfirmed/transactions/mockAddress", `{"page": 3, "list": [{"txId": "def"}]}`) defer mockServer.Close() config := SDKConfig{ - BaseAPIURL: mockServer.URL, + BaseAPIURL: mockServer.URL + "/bgl/v1/blockchain", } addressAPI := NewAddress(config) - _, err := addressAPI.GetUnconfirmedAddressTransactions("mockAddress") + transactions, err := addressAPI.GetUnconfirmedAddressTransactions("mockAddress") if err != nil { t.Errorf("Expected no error, got %v", err) } + if transactions.Page != 3 || len(transactions.List) != 1 || transactions.List[0].TxID != "def" { + t.Errorf("Expected unconfirmed transactions to be decoded, got %#v", transactions) + } } func TestGetAddressUTXO(t *testing.T) { - mockServer := createMockServer("address/unconfirmed/transactions/mockAddress", `{"mock": "data"}`) + mockServer := createMockServer("address/utxo/mockAddress", `[{"txId": "utxo", "vOut": 1}]`) defer mockServer.Close() config := SDKConfig{ - BaseAPIURL: mockServer.URL, + BaseAPIURL: mockServer.URL + "/bgl/v1/blockchain", } addressAPI := NewAddress(config) - _, err := addressAPI.GetAddressUTXO("mockAddress") + utxos, err := addressAPI.GetAddressUTXO("mockAddress") if err != nil { t.Errorf("Expected no error, got %v", err) } + if len(*utxos) != 1 || (*utxos)[0].TxID != "utxo" || (*utxos)[0].VOut != 1 { + t.Errorf("Expected UTXOs to be decoded, got %#v", utxos) + } } func createMockServer(path, response string) *httptest.Server { diff --git a/Blockchain.go b/Blockchain.go index fe1e0f7..2db0bee 100644 --- a/Blockchain.go +++ b/Blockchain.go @@ -5,14 +5,8 @@ import ( "fmt" "io/ioutil" "net/http" - "time" ) -// SDKConfig represents the configuration for the SDK -type SDKConfig struct { - BaseAPIURL string // Add any other fields as needed -} - // Blockchain represents the blockchain SDK type Blockchain struct { apiV1URL string diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..2753612 --- /dev/null +++ b/Makefile @@ -0,0 +1,5 @@ +setup: + go mod download + +compile: + go test ./... diff --git a/Mempool.go b/Mempool.go index 0b6b7bb..3fb2475 100644 --- a/Mempool.go +++ b/Mempool.go @@ -5,14 +5,8 @@ import ( "fmt" "io/ioutil" "net/http" - "time" ) -// SDKConfig represents the configuration for the SDK -type SDKConfig struct { - BaseAPIURL string // Add any other fields as needed -} - // Mempool represents the mempool SDK type Mempool struct { apiV1URL string diff --git a/api.go b/api.go index 3da0fb8..dcad635 100644 --- a/api.go +++ b/api.go @@ -1,9 +1,5 @@ package blockchain -import ( - "fmt" -) - // BitgesellBlockchainSDK represents the Bitgesell Blockchain SDK type BitgesellBlockchainSDK struct { Blockchain Blockchain diff --git a/examples/example.go b/examples/example.go index b443d16..ff6e82e 100644 --- a/examples/example.go +++ b/examples/example.go @@ -2,13 +2,14 @@ package main import ( "fmt" - "github.com/naftalimurgor/go-bitgesell-toolkit" + + blockchain "github.com/BitgesellOfficial/go-bitgesell-toolkit" ) func main() { // Example usage of the Bitgesell Blockchain SDK - config := blockchain.SDKConfig.SDKConfig{BaseAPIURL: "https://api.bitaps.com/bgl/v1/blockchain"} - bitgesellSDK := blockchain.bitgesell.NewBitgesellBlockchainSDK(config) + config := blockchain.SDKConfig{BaseAPIURL: "https://api.bitaps.com/bgl/v1/blockchain"} + bitgesellSDK := blockchain.NewBitgesellBlockchainSDK(config) // Example: Access Blockchain SDK methods block, err := bitgesellSDK.Blockchain.GetBlockByHash("your_block_hash") @@ -33,4 +34,4 @@ func main() { return } fmt.Println("Mempool Transactions:", mempoolTransactions) -} \ No newline at end of file +} diff --git a/go.mod b/go.mod index 209a559..1935892 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module github.com/naftalimurgor/go-bitgesell-toolkit +module github.com/BitgesellOfficial/go-bitgesell-toolkit go 1.21.6 diff --git a/interfaces.go b/interfaces.go index adcf933..4b69881 100644 --- a/interfaces.go +++ b/interfaces.go @@ -2,113 +2,119 @@ package blockchain // Block represents the block type type Block struct { - Height int `json:"height"` - Hash string `json:"hash"` - Header string `json:"header"` - AdjustedTimestamp int `json:"adjustedTimestamp"` + Height int `json:"height"` + Hash string `json:"hash"` + Header string `json:"header"` + AdjustedTimestamp int `json:"adjustedTimestamp"` } // SDKConfig represents the configuration for the SDK type SDKConfig struct { BaseAPIURL string - Logger func(string) + Logger func(string) APIKey string } +// object represents API fields whose shape varies by endpoint. +type object = map[string]interface{} + // BlockHeader represents the block header type type BlockHeader struct { Data []interface{} `json:"data"` - Time int64 `json:"time"` + Time int64 `json:"time"` } // BlockStats represents the block statistics type type BlockStats struct { - Height int `json:"height"` - Hash string `json:"hash"` - Header string `json:"header"` - Version int `json:"version"` - PreviousBlockHash string `json:"previousBlockHash"` - MerkleRoot string `json:"merkleRoot"` - Bits int `json:"bits"` - Nonce int `json:"nonce"` - Weight int `json:"weight"` - Size int `json:"size"` - StrippedSize int `json:"strippedSize"` - Amount int `json:"amount"` - Target string `json:"target"` - Miner string `json:"miner"` - MedianBlockTime int `json:"medianBlockTime"` - BlockTime int `json:"blockTime"` - ReceivedTimestamp int `json:"receivedTimestamp"` - AdjustedTimestamp int `json:"adjustedTimestamp"` - BitsHex string `json:"bitsHex"` - NonceHex string `json:"nonceHex"` - VersionHex string `json:"versionHex"` - Difficulty int `json:"difficulty"` - BlockDifficulty int `json:"blockDifficulty"` - NextBlockHash string `json:"nextBlockHash"` - EstimatedBlockReward int `json:"estimatedBlockReward"` - BlockReward int `json:"blockReward"` - BlockFeeReward int `json:"blockFeeReward"` - Confirmations int `json:"confirmations"` - TransactionsCount int `json:"transactionsCount"` - Coinbase string `json:"coinbase"` - Statistics object `json:"statistics"` - Time int64 `json:"time"` + Height int `json:"height"` + Hash string `json:"hash"` + Header string `json:"header"` + Version int `json:"version"` + PreviousBlockHash string `json:"previousBlockHash"` + MerkleRoot string `json:"merkleRoot"` + Bits int `json:"bits"` + Nonce int `json:"nonce"` + Weight int `json:"weight"` + Size int `json:"size"` + StrippedSize int `json:"strippedSize"` + Amount int `json:"amount"` + Target string `json:"target"` + Miner string `json:"miner"` + MedianBlockTime int `json:"medianBlockTime"` + BlockTime int `json:"blockTime"` + ReceivedTimestamp int `json:"receivedTimestamp"` + AdjustedTimestamp int `json:"adjustedTimestamp"` + BitsHex string `json:"bitsHex"` + NonceHex string `json:"nonceHex"` + VersionHex string `json:"versionHex"` + Difficulty int `json:"difficulty"` + BlockDifficulty int `json:"blockDifficulty"` + NextBlockHash string `json:"nextBlockHash"` + EstimatedBlockReward int `json:"estimatedBlockReward"` + BlockReward int `json:"blockReward"` + BlockFeeReward int `json:"blockFeeReward"` + Confirmations int `json:"confirmations"` + TransactionsCount int `json:"transactionsCount"` + Coinbase string `json:"coinbase"` + Statistics object `json:"statistics"` + Time int64 `json:"time"` } // Transaction represents the transaction type type Transaction struct { - Segwit bool `json:"segwit"` - RBF bool `json:"rbf"` - TxID string `json:"txId"` - Hash string `json:"hash"` - Version int `json:"version"` - Size int `json:"size"` - VSize int `json:"vSize"` - BSize int `json:"bSize"` - LockTime int `json:"lockTime"` - VIn object `json:"vIn"` - VOut object `json:"vOut"` - Confirmations int `json:"confirmations"` - BlockIndex int `json:"blockIndex"` - Coinbase bool `json:"coinbase"` - Data string `json:"data"` - RawTx string `json:"rawTx"` - Amount int `json:"amount"` - Flag string `json:"flag"` - Weight int `json:"weight"` - Timestamp int64 `json:"timestamp"` - MerkleProof string `json:"merkleProof"` - InputsAmount int `json:"inputsAmount"` - OutputAddresses int `json:"outputAddresses"` - InputAddresses int `json:"inputAddresses"` - Fee int `json:"fee"` - OutputsAmount int `json:"outputsAmount"` - Inputs int `json:"inputs"` - Outputs int `json:"outputs"` + apiV1URL string + logger func(string) + + Segwit bool `json:"segwit"` + RBF bool `json:"rbf"` + TxID string `json:"txId"` + Hash string `json:"hash"` + Version int `json:"version"` + Size int `json:"size"` + VSize int `json:"vSize"` + BSize int `json:"bSize"` + LockTime int `json:"lockTime"` + VIn object `json:"vIn"` + VOut object `json:"vOut"` + Confirmations int `json:"confirmations"` + BlockIndex int `json:"blockIndex"` + Coinbase bool `json:"coinbase"` + Data string `json:"data"` + RawTx string `json:"rawTx"` + Amount int `json:"amount"` + Flag string `json:"flag"` + Weight int `json:"weight"` + Timestamp int64 `json:"timestamp"` + MerkleProof string `json:"merkleProof"` + InputsAmount int `json:"inputsAmount"` + OutputAddresses int `json:"outputAddresses"` + InputAddresses int `json:"inputAddresses"` + Fee int `json:"fee"` + OutputsAmount int `json:"outputsAmount"` + Inputs int `json:"inputs"` + Outputs int `json:"outputs"` } // Transactions represents the transactions type type Transactions struct { - List []Transaction `json:"list"` - Page int `json:"page"` - Pages int `json:"pages"` - Total int `json:"total"` - Limit int `json:"limit"` - Time int64 `json:"time"` + List []Transaction `json:"list"` + Page int `json:"page"` + Pages int `json:"pages"` + Total int `json:"total"` + Limit int `json:"limit"` + Time int64 `json:"time"` } // UTXO represents the Unspent Transaction Output type type UTXO struct { - TxID string `json:"txId"` - VOut int `json:"vOut"` - TxIndex int `json:"txIndex"` - Amount int `json:"amount"` - Address string `json:"address"` - Script string `json:"script"` - Type string `json:"type"` - Time int64 `json:"time"` + TxID string `json:"txId"` + VOut int `json:"vOut"` + TxIndex int `json:"txIndex"` + Amount int `json:"amount"` + Address string `json:"address"` + Script string `json:"script"` + Type string `json:"type"` + Time int64 `json:"time"` } // UTXOs represents an array of UTXO @@ -116,13 +122,13 @@ type UTXOs []UTXO // MempoolTxes represents the mempool transactions type type MempoolTxes struct { - List []interface{} `json:"list"` - Page int `json:"page"` - Limit int `json:"limit"` - Pages int `json:"pages"` - Count int `json:"count"` - FromTimestamp int64 `json:"fromTimestamp"` - Time int64 `json:"time"` + List []interface{} `json:"list"` + Page int `json:"page"` + Limit int `json:"limit"` + Pages int `json:"pages"` + Count int `json:"count"` + FromTimestamp int64 `json:"fromTimestamp"` + Time int64 `json:"time"` } // MempoolState represents the mempool state type @@ -135,10 +141,10 @@ type MempoolState struct { // MempoolRecommendedFee represents the recommended fee from the mempool type type MempoolRecommendedFee struct { - Best int `json:"best"` - Best4h int `json:"best4h"` + Best int `json:"best"` + Best4h int `json:"best4h"` BestHourly int `json:"bestHourly"` - Time int64 `json:"time"` + Time int64 `json:"time"` } // AddressBalance represents the address balance type @@ -168,36 +174,36 @@ type AddressBalance struct { // AddressTransaction represents the address transaction type type AddressTransaction struct { - Segwit bool `json:"segwit"` - RBF bool `json:"rbf"` - TxID string `json:"txId"` - Version int `json:"version"` - Size int `json:"size"` - VSize int `json:"vSize"` - BSize int `json:"bSize"` - LockTime int `json:"lockTime"` - VIn object `json:"vIn"` - VOut object `json:"vOut"` - Confirmations int `json:"confirmations"` - BlockTime int `json:"blockTime"` - BlockIndex int `json:"blockIndex"` - Coinbase bool `json:"coinbase"` - Fee int `json:"fee"` - Data string `json:"data"` - Amount int `json:"amount"` - Weight int `json:"weight"` - BlockHeight int `json:"blockHeight"` - Timestamp int64 `json:"timestamp"` - InputsAmount int `json:"inputsAmount"` - InputAddressCount int `json:"inputAddressCount"` - OutAddressCount int `json:"outAddressCount"` - InputsCount int `json:"inputsCount"` - OutsCount int `json:"outsCount"` - OutputsAmount int `json:"outputsAmount"` - AddressReceived int `json:"addressReceived"` - AddressOuts int `json:"addressOuts"` - AddressSent int `json:"addressSent"` - AddressInputs int `json:"addressInputs"` + Segwit bool `json:"segwit"` + RBF bool `json:"rbf"` + TxID string `json:"txId"` + Version int `json:"version"` + Size int `json:"size"` + VSize int `json:"vSize"` + BSize int `json:"bSize"` + LockTime int `json:"lockTime"` + VIn object `json:"vIn"` + VOut object `json:"vOut"` + Confirmations int `json:"confirmations"` + BlockTime int `json:"blockTime"` + BlockIndex int `json:"blockIndex"` + Coinbase bool `json:"coinbase"` + Fee int `json:"fee"` + Data string `json:"data"` + Amount int `json:"amount"` + Weight int `json:"weight"` + BlockHeight int `json:"blockHeight"` + Timestamp int64 `json:"timestamp"` + InputsAmount int `json:"inputsAmount"` + InputAddressCount int `json:"inputAddressCount"` + OutAddressCount int `json:"outAddressCount"` + InputsCount int `json:"inputsCount"` + OutsCount int `json:"outsCount"` + OutputsAmount int `json:"outputsAmount"` + AddressReceived int `json:"addressReceived"` + AddressOuts int `json:"addressOuts"` + AddressSent int `json:"addressSent"` + AddressInputs int `json:"addressInputs"` } // AddressTransactions represents the address transactions type @@ -228,3 +234,6 @@ type TransactionMerkelProof struct { MerkleProof string `json:"merkleProof"` Time int64 `json:"time"` } + +// TransactionMerkleProof preserves the conventional spelling for callers. +type TransactionMerkleProof = TransactionMerkelProof