From eb0a6ecb9c221137bf11cd8930581df6577062a3 Mon Sep 17 00:00:00 2001 From: bos-hieu <12520839@gm.uit.edu.vn> Date: Thu, 6 Mar 2025 10:27:26 +0700 Subject: [PATCH 1/2] feat: support gen addr key chain bech32 --- address.go | 66 ++++++++++++++-------------- go.mod | 2 +- go.sum | 3 ++ gobcy_test.go | 15 ++++--- types.go | 116 +++++++++++++++++++++++++++++--------------------- 5 files changed, 113 insertions(+), 89 deletions(-) diff --git a/address.go b/address.go index c415a46..3b82450 100644 --- a/address.go +++ b/address.go @@ -5,9 +5,9 @@ import ( "strconv" ) -//GetAddrBal returns balance information for a given public -//address. Fastest Address API call, but does not -//include transaction details. +// GetAddrBal returns balance information for a given public +// address. Fastest Address API call, but does not +// include transaction details. func (api *API) GetAddrBal(hash string, params map[string]string) (addr Addr, err error) { u, err := api.buildURL("/addrs/"+hash+"/balance", params) if err != nil { @@ -17,11 +17,11 @@ func (api *API) GetAddrBal(hash string, params map[string]string) (addr Addr, er return } -//GetAddr returns information for a given public -//address, including a slice of confirmed and unconfirmed -//transaction outpus via the TXRef arrays in the Address -//type. Returns more information than GetAddrBal, but -//slightly slower. +// GetAddr returns information for a given public +// address, including a slice of confirmed and unconfirmed +// transaction outpus via the TXRef arrays in the Address +// type. Returns more information than GetAddrBal, but +// slightly slower. func (api *API) GetAddr(hash string, params map[string]string) (addr Addr, err error) { u, err := api.buildURL("/addrs/"+hash, params) if err != nil { @@ -31,9 +31,9 @@ func (api *API) GetAddr(hash string, params map[string]string) (addr Addr, err e return } -//GetAddrNext returns a given Addr's next page of TXRefs, -//if Addr.HasMore is true. If HasMore is false, will -//return an error. It assumes default API URL parameters. +// GetAddrNext returns a given Addr's next page of TXRefs, +// if Addr.HasMore is true. If HasMore is false, will +// return an error. It assumes default API URL parameters. func (api *API) GetAddrNext(this Addr) (next Addr, err error) { if !this.HasMore { err = errors.New("Func GetAddrNext: this Addr doesn't have more TXRefs according to its HasMore") @@ -44,10 +44,10 @@ func (api *API) GetAddrNext(this Addr) (next Addr, err error) { return } -//GetAddrFull returns information for a given public -//address, including a slice of TXs associated -//with this address. Returns more data than GetAddr since -//it includes full transactions, but slowest Address query. +// GetAddrFull returns information for a given public +// address, including a slice of TXs associated +// with this address. Returns more data than GetAddr since +// it includes full transactions, but slowest Address query. func (api *API) GetAddrFull(hash string, params map[string]string) (addr Addr, err error) { u, err := api.buildURL("/addrs/"+hash+"/full", params) if err != nil { @@ -57,9 +57,9 @@ func (api *API) GetAddrFull(hash string, params map[string]string) (addr Addr, e return } -//GetAddrFullNext returns a given Addr's next page of TXs, -//if Addr.HasMore is true. If HasMore is false, will -//return an error. It assumes default API URL parameters, like GetAddrFull. +// GetAddrFullNext returns a given Addr's next page of TXs, +// if Addr.HasMore is true. If HasMore is false, will +// return an error. It assumes default API URL parameters, like GetAddrFull. func (api *API) GetAddrFullNext(this Addr) (next Addr, err error) { if !this.HasMore { err = errors.New("Func GetAddrFullNext: this Addr doesn't have more TXs according to its HasMore") @@ -70,12 +70,12 @@ func (api *API) GetAddrFullNext(this Addr) (next Addr, err error) { return } -//GenAddrKeychain generates a public/private key pair for use with -//transactions within the specified coin/chain. Please note that -//this call must be made over SSL, and it is not recommended to keep -//large amounts in these addresses, or for very long. -func (api *API) GenAddrKeychain() (pair AddrKeychain, err error) { - u, err := api.buildURL("/addrs", nil) +// GenAddrKeychain generates a public/private key pair for use with +// transactions within the specified coin/chain. Please note that +// this call must be made over SSL, and it is not recommended to keep +// large amounts in these addresses, or for very long. +func (api *API) GenAddrKeychain(params *GenAddrKeychainParams) (pair AddrKeychain, err error) { + u, err := api.buildURL(params.GetURL(), nil) if err != nil { return } @@ -83,11 +83,11 @@ func (api *API) GenAddrKeychain() (pair AddrKeychain, err error) { return } -//GenAddrMultisig generates a P2SH multisignature address using an array -//of PubKeys and the ScriptType from a AddrKeychain. Other fields are -//ignored, and the ScriptType must be a "multisig-n-of-m" type. Returns -//an AddrKeychain with the same PubKeys, ScriptType, and the proper -//P2SH address in the AddrKeychain's address field. +// GenAddrMultisig generates a P2SH multisignature address using an array +// of PubKeys and the ScriptType from a AddrKeychain. Other fields are +// ignored, and the ScriptType must be a "multisig-n-of-m" type. Returns +// an AddrKeychain with the same PubKeys, ScriptType, and the proper +// P2SH address in the AddrKeychain's address field. func (api *API) GenAddrMultisig(multi AddrKeychain) (addr AddrKeychain, err error) { if len(multi.PubKeys) == 0 || multi.ScriptType == "" { err = errors.New("GenAddrMultisig: PubKeys or ScriptType are empty.") @@ -101,9 +101,9 @@ func (api *API) GenAddrMultisig(multi AddrKeychain) (addr AddrKeychain, err erro return } -//Faucet funds the AddrKeychain with an amount. Only works on BlockCypher's -//Testnet and Bitcoin Testnet3. Returns the transaction hash funding -//your AddrKeychain. +// Faucet funds the AddrKeychain with an amount. Only works on BlockCypher's +// Testnet and Bitcoin Testnet3. Returns the transaction hash funding +// your AddrKeychain. func (api *API) Faucet(a AddrKeychain, amount int) (txhash string, err error) { if !(api.Coin == "bcy" && api.Chain == "test") && !(api.Coin == "btc" && api.Chain == "test3") { err = errors.New("Faucet: Cannot use Faucet unless on BlockCypher Testnet or Bitcoin Testnet3.") @@ -118,7 +118,7 @@ func (api *API) Faucet(a AddrKeychain, amount int) (txhash string, err error) { Amount int `json:"amount"` } var addr string - //for easy funding/testing of OAPAddresses + // for easy funding/testing of OAPAddresses if a.OriginalAddress != "" { addr = a.OriginalAddress } else { diff --git a/go.mod b/go.mod index c4fbdca..2ca096a 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/blockcypher/gobcy/v2 -go 1.18 +go 1.23.0 require github.com/btcsuite/btcd/btcec/v2 v2.3.2 diff --git a/go.sum b/go.sum index ef25978..8a7fb8f 100644 --- a/go.sum +++ b/go.sum @@ -1,7 +1,10 @@ github.com/btcsuite/btcd/btcec/v2 v2.3.2 h1:5n0X6hX0Zk+6omWcihdYvdAlGf2DfasC0GMf7DClJ3U= github.com/btcsuite/btcd/btcec/v2 v2.3.2/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04= github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 h1:q0rUy8C/TYNBQS1+CGKw68tLOFYSNEs0TFnxxnS9+4U= +github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y= +github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 h1:8UrgZ3GkP4i/CLijOJx79Yu+etlyjdBU4sfcs2WYQMs= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= diff --git a/gobcy_test.go b/gobcy_test.go index f6af579..008ea5b 100644 --- a/gobcy_test.go +++ b/gobcy_test.go @@ -23,22 +23,23 @@ func TestMain(m *testing.M) { bcy.Token = "$TOKEN" //Create/fund the test addresses var err error - keys1, err = bcy.GenAddrKeychain() + keys1, err = bcy.GenAddrKeychain(NewGenAddrKeychainParams()) if err != nil { - log.Fatal("Error generating test addresses: ", err) + log.Fatal("[Keys1] Error generating test addresses: ", err) } - keys2, err = bcy.GenAddrKeychain() + keys2, err = bcy.GenAddrKeychain(NewGenAddrKeychainParams().SetBech32()) if err != nil { - log.Fatal("Error generating test addresses: ", err) + log.Fatal("[Keys2] Error generating test addresses: ", err) } txhash1, err = bcy.Faucet(keys1, 1e5) if err != nil { - log.Fatal("Error funding test addresses: ", err) + log.Fatal("[txhash1] Error funding test addresses: ", err) } txhash2, err = bcy.Faucet(keys2, 2e5) if err != nil { - log.Fatal("Error funding test addresses: ", err) + log.Fatal("[txhash2] Error funding test addresses: ", err) } + os.Exit(m.Run()) } @@ -296,7 +297,7 @@ func TestAsset(t *testing.T) { if err != nil { t.Error("GenAssetKeychain error encountered: ", err) } - funder, err := bcy.GenAddrKeychain() + funder, err := bcy.GenAddrKeychain(NewGenAddrKeychainParams()) if err != nil { t.Error("GenAddrKeychain error encountered: ", err) } diff --git a/types.go b/types.go index 2febcd8..75f991d 100644 --- a/types.go +++ b/types.go @@ -2,11 +2,12 @@ package gobcy import ( "math/big" + "strconv" "time" ) -//TokenUsage represents information about -//the limits and usage against your token. +// TokenUsage represents information about +// the limits and usage against your token. type TokenUsage struct { Limits Usage `json:"limits"` Hits Usage `json:"hits"` @@ -30,8 +31,8 @@ type UsageHistory struct { Time time.Time `json:",omitempty"` } -//Blockchain represents information about -//the state of a blockchain. +// Blockchain represents information about +// the state of a blockchain. type Blockchain struct { Name string `json:"name"` Height int `json:"height"` @@ -47,8 +48,8 @@ type Blockchain struct { LastForkHash string `json:"last_fork_hash"` } -//Block represents information about the state -//of a given block in a blockchain. +// Block represents information about the state +// of a given block in a blockchain. type Block struct { Hash string `json:"hash"` Height int `json:"height"` @@ -71,8 +72,8 @@ type Block struct { NextTXs string `json:"next_txids"` } -//TX represents information about the state -//of a given transaction in a blockchain. +// TX represents information about the state +// of a given transaction in a blockchain. type TX struct { BlockHash string `json:"block_hash,omitempty"` BlockHeight int `json:"block_height,omitempty"` @@ -109,7 +110,7 @@ type TX struct { Outputs []TXOutput `json:"outputs"` } -//TXInput represents the state of a transaction input +// TXInput represents the state of a transaction input type TXInput struct { PrevHash string `json:"prev_hash,omitempty"` OutputIndex int `json:"output_index,omitempty"` @@ -122,7 +123,7 @@ type TXInput struct { WalletName string `json:"wallet_name,omitempty"` } -//TXOutput represents the state of a transaction output +// TXOutput represents the state of a transaction output type TXOutput struct { SpentBy string `json:"spent_by,omitempty"` Value big.Int `json:"value"` @@ -133,8 +134,8 @@ type TXOutput struct { DataString string `json:"data_string,omitempty"` } -//TXConf represents information about the -//confidence of an unconfirmed transaction. +// TXConf represents information about the +// confidence of an unconfirmed transaction. type TXConf struct { Age int `json:"age_millis"` ReceiveCount int `json:"receive_count,omitempty"` @@ -142,8 +143,8 @@ type TXConf struct { TXHash string `json:"txhash"` } -//TXRef represents summarized data about a -//transaction input or output. +// TXRef represents summarized data about a +// transaction input or output. type TXRef struct { Address string `json:"address,omitempty"` BlockHeight int `json:"block_height"` @@ -165,10 +166,10 @@ type TXRef struct { ReceivedCount big.Int `json:"received_count,omitempty"` } -//TXSkel represents the return call to BlockCypher's -//txs/new endpoint, and includes error information, -//hex transactions that need to be signed, and space -//for the signed transactions and associated public keys. +// TXSkel represents the return call to BlockCypher's +// txs/new endpoint, and includes error information, +// hex transactions that need to be signed, and space +// for the signed transactions and associated public keys. type TXSkel struct { Trans TX `json:"tx"` ToSign []string `json:"tosign"` @@ -180,17 +181,17 @@ type TXSkel struct { } `json:"errors,omitempty"` } -//NullData represents the call and return to BlockCypher's -//Data API, allowing you to embed up to 80 bytes into -//a blockchain via an OP_RETURN. +// NullData represents the call and return to BlockCypher's +// Data API, allowing you to embed up to 80 bytes into +// a blockchain via an OP_RETURN. type NullData struct { Data string `json:"data"` Encoding string `json:"encoding,omitempty"` Hash string `json:"hash,omitempty"` } -//Addr represents information about the state -//of a public address. +// Addr represents information about the state +// of a public address. type Addr struct { Address string `json:"address,omitempty"` Wallet Wallet `json:"wallet,omitempty"` @@ -211,10 +212,10 @@ type Addr struct { HasMore bool `json:"hasMore,omitempty"` } -//AddrKeychain represents information about a generated -//public-private key pair from BlockCypher's address -//generation API. Large amounts are not recommended to be -//stored with these addresses. +// AddrKeychain represents information about a generated +// public-private key pair from BlockCypher's address +// generation API. Large amounts are not recommended to be +// stored with these addresses. type AddrKeychain struct { Address string `json:"address,omitempty"` Private string `json:"private,omitempty"` @@ -226,17 +227,17 @@ type AddrKeychain struct { OAPAddress string `json:"oap_address,omitempty"` } -//Wallet represents information about a standard wallet. -//Typically, wallets can be used wherever an address can be -//used within the API. +// Wallet represents information about a standard wallet. +// Typically, wallets can be used wherever an address can be +// used within the API. type Wallet struct { Name string `json:"name,omitempty"` Addresses []string `json:"addresses,omitempty"` } -//HDWallet represents information about a Hierarchical Deterministic -//(HD) wallet. Like regular Wallets, HDWallets can be used wherever an -//address can be used within the API. +// HDWallet represents information about a Hierarchical Deterministic +// (HD) wallet. Like regular Wallets, HDWallets can be used wherever an +// address can be used within the API. type HDWallet struct { Name string `json:"name,omitempty"` ExtPubKey string `json:"extended_public_key,omitempty"` @@ -251,19 +252,19 @@ type HDWallet struct { } `json:"chains,omitempty"` } -//Hook represents a WebHook/WebSockets event. -//BlockCypher supports the following events: +// Hook represents a WebHook/WebSockets event. +// BlockCypher supports the following events: // Event = "unconfirmed-tx" // Event = "new-block" // Event = "confirmed-tx" // Event = "tx-confirmation" // Event = "double-spend-tx" // Event = "tx-confidence" -//Hash, Address, and Script are all optional; creating -//a WebHook with any of them will filter the resulting -//notifications, if appropriate. ID is returned by -//BlockCyphers servers after Posting a new WebHook; you -//shouldn't manually generate this field. +// Hash, Address, and Script are all optional; creating +// a WebHook with any of them will filter the resulting +// notifications, if appropriate. ID is returned by +// BlockCyphers servers after Posting a new WebHook; you +// shouldn't manually generate this field. type Hook struct { ID string `json:"id,omitempty"` Event string `json:"event"` @@ -277,8 +278,8 @@ type Hook struct { CallbackErrs int `json:"callback_errors,omitempty"` } -//PayFwd represents a reference to -//a Payment Forwarding request. +// PayFwd represents a reference to +// a Payment Forwarding request. type PayFwd struct { ID string `json:"id,omitempty"` Destination string `json:"destination"` @@ -292,8 +293,8 @@ type PayFwd struct { TXHistory []string `json:"transactions,omitempty"` } -//Payback represents a Payment Forwarding Callback. -//It's more fun to call it a "payback." +// Payback represents a Payment Forwarding Callback. +// It's more fun to call it a "payback." type Payback struct { Value big.Int `json:"value"` Destination string `json:"destination"` @@ -302,8 +303,8 @@ type Payback struct { InputHash string `json:"input_transaction_hash"` } -//OAPIssue represents a request for issuance or transfer of -//an Open Asset on a blockchain. +// OAPIssue represents a request for issuance or transfer of +// an Open Asset on a blockchain. type OAPIssue struct { Priv string `json:"from_private"` ToAddr string `json:"to_address"` @@ -311,8 +312,8 @@ type OAPIssue struct { Metadata string `json:"metadata,omitempty"` } -//OAPTX represents an Open Asset protocol transaction, generated -//when issuing or transferring assets. +// OAPTX represents an Open Asset protocol transaction, generated +// when issuing or transferring assets. type OAPTX struct { Ver int `json:"ver"` AssetID string `json:"assetid"` @@ -333,3 +334,22 @@ type OAPTX struct { OrigOutputIndex int `json:"original_output_index"` } `json:"outputs"` } + +type GenAddrKeychainParams struct { + Bech32 bool `json:"bech32,omitempty"` +} + +func NewGenAddrKeychainParams() *GenAddrKeychainParams { + return &GenAddrKeychainParams{} +} + +// SetBech32 sets the Bech32 field to true. +// default is false. +func (g *GenAddrKeychainParams) SetBech32() *GenAddrKeychainParams { + g.Bech32 = true + return g +} + +func (g GenAddrKeychainParams) GetURL() string { + return "/addrs?bech32=" + strconv.FormatBool(g.Bech32) +} \ No newline at end of file From 611e2cddc4717dab422b7db495d8cc58c1236fd9 Mon Sep 17 00:00:00 2001 From: bos-hieu <12520839@gm.uit.edu.vn> Date: Thu, 6 Mar 2025 10:28:13 +0700 Subject: [PATCH 2/2] chore: add gitignore --- .gitignore | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7fce9b8 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +# IDE +.idea + +# Environment +.env \ No newline at end of file