Skip to content

Commit

Permalink
Merge pull request #148 from pawellewandowski98/feat-104-error-handlimg
Browse files Browse the repository at this point in the history
feat(BUX-104): update bux error handling
  • Loading branch information
mergify[bot] authored Aug 17, 2023
2 parents faece0c + 3f4b15b commit d44309b
Show file tree
Hide file tree
Showing 14 changed files with 340 additions and 278 deletions.
10 changes: 5 additions & 5 deletions access_keys.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,26 @@ package buxclient

import (
"context"

buxmodels "github.com/BuxOrg/bux-models"
"github.com/BuxOrg/go-buxclient/transports"
)

// GetAccessKey gets the access key given by id
func (b *BuxClient) GetAccessKey(ctx context.Context, id string) (*buxmodels.AccessKey, error) {
func (b *BuxClient) GetAccessKey(ctx context.Context, id string) (*buxmodels.AccessKey, transports.ResponseError) {
return b.transport.GetAccessKey(ctx, id)
}

// GetAccessKeys gets all the access keys filtered by the metadata
func (b *BuxClient) GetAccessKeys(ctx context.Context, metadataConditions *buxmodels.Metadata) ([]*buxmodels.AccessKey, error) {
func (b *BuxClient) GetAccessKeys(ctx context.Context, metadataConditions *buxmodels.Metadata) ([]*buxmodels.AccessKey, transports.ResponseError) {
return b.transport.GetAccessKeys(ctx, metadataConditions)
}

// CreateAccessKey creates new access key
func (b *BuxClient) CreateAccessKey(ctx context.Context, metadata *buxmodels.Metadata) (*buxmodels.AccessKey, error) {
func (b *BuxClient) CreateAccessKey(ctx context.Context, metadata *buxmodels.Metadata) (*buxmodels.AccessKey, transports.ResponseError) {
return b.transport.CreateAccessKey(ctx, metadata)
}

// RevokeAccessKey revoked the access key given by id
func (b *BuxClient) RevokeAccessKey(ctx context.Context, id string) (*buxmodels.AccessKey, error) {
func (b *BuxClient) RevokeAccessKey(ctx context.Context, id string) (*buxmodels.AccessKey, transports.ResponseError) {
return b.transport.RevokeAccessKey(ctx, id)
}
18 changes: 9 additions & 9 deletions destinations.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,56 +2,56 @@ package buxclient

import (
"context"

buxmodels "github.com/BuxOrg/bux-models"
"github.com/BuxOrg/go-buxclient/transports"
)

// GetDestinationByID gets the destination by id
func (b *BuxClient) GetDestinationByID(ctx context.Context, id string) (*buxmodels.Destination, error) {
func (b *BuxClient) GetDestinationByID(ctx context.Context, id string) (*buxmodels.Destination, transports.ResponseError) {
return b.transport.GetDestinationByID(ctx, id)
}

// GetDestinationByAddress gets the destination by address
func (b *BuxClient) GetDestinationByAddress(ctx context.Context, address string) (*buxmodels.Destination, error) {
func (b *BuxClient) GetDestinationByAddress(ctx context.Context, address string) (*buxmodels.Destination, transports.ResponseError) {
return b.transport.GetDestinationByAddress(ctx, address)
}

// GetDestinationByLockingScript gets the destination by locking script
func (b *BuxClient) GetDestinationByLockingScript(ctx context.Context,
lockingScript string,
) (*buxmodels.Destination, error) {
) (*buxmodels.Destination, transports.ResponseError) {
return b.transport.GetDestinationByLockingScript(ctx, lockingScript)
}

// GetDestinations gets all destinations that match the metadata filter
func (b *BuxClient) GetDestinations(ctx context.Context,
metadataConditions *buxmodels.Metadata,
) ([]*buxmodels.Destination, error) {
) ([]*buxmodels.Destination, transports.ResponseError) {
return b.transport.GetDestinations(ctx, metadataConditions)
}

// NewDestination create a new destination and return it
func (b *BuxClient) NewDestination(ctx context.Context, metadata *buxmodels.Metadata) (*buxmodels.Destination, error) {
func (b *BuxClient) NewDestination(ctx context.Context, metadata *buxmodels.Metadata) (*buxmodels.Destination, transports.ResponseError) {
return b.transport.NewDestination(ctx, metadata)
}

// UpdateDestinationMetadataByID updates the destination metadata by id
func (b *BuxClient) UpdateDestinationMetadataByID(ctx context.Context, id string,
metadata *buxmodels.Metadata,
) (*buxmodels.Destination, error) {
) (*buxmodels.Destination, transports.ResponseError) {
return b.transport.UpdateDestinationMetadataByID(ctx, id, metadata)
}

// UpdateDestinationMetadataByAddress updates the destination metadata by address
func (b *BuxClient) UpdateDestinationMetadataByAddress(ctx context.Context, address string,
metadata *buxmodels.Metadata,
) (*buxmodels.Destination, error) {
) (*buxmodels.Destination, transports.ResponseError) {
return b.transport.UpdateDestinationMetadataByAddress(ctx, address, metadata)
}

// UpdateDestinationMetadataByLockingScript updates the destination metadata by locking script
func (b *BuxClient) UpdateDestinationMetadataByLockingScript(ctx context.Context, lockingScript string,
metadata *buxmodels.Metadata,
) (*buxmodels.Destination, error) {
) (*buxmodels.Destination, transports.ResponseError) {
return b.transport.UpdateDestinationMetadataByLockingScript(ctx, lockingScript, metadata)
}
4 changes: 2 additions & 2 deletions paymail_addresses.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ package buxclient

import (
"context"

buxmodels "github.com/BuxOrg/bux-models"
"github.com/BuxOrg/go-buxclient/transports"
)

// NewPaymail will create a new paymail
func (b *BuxClient) NewPaymail(ctx context.Context, rawXPub, paymailAddress, avatar, publicName string, metadata *buxmodels.Metadata) error {
func (b *BuxClient) NewPaymail(ctx context.Context, rawXPub, paymailAddress, avatar, publicName string, metadata *buxmodels.Metadata) transports.ResponseError {
return b.transport.NewPaymail(ctx, rawXPub, paymailAddress, avatar, publicName, metadata)
}
20 changes: 10 additions & 10 deletions transactions.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,66 +9,66 @@ import (
)

// GetTransaction get a transaction by id
func (b *BuxClient) GetTransaction(ctx context.Context, txID string) (*buxmodels.Transaction, error) {
func (b *BuxClient) GetTransaction(ctx context.Context, txID string) (*buxmodels.Transaction, transports.ResponseError) {
return b.transport.GetTransaction(ctx, txID)
}

// GetTransactions get all transactions matching search criteria
func (b *BuxClient) GetTransactions(ctx context.Context, conditions map[string]interface{},
metadata *buxmodels.Metadata, queryParams *transports.QueryParams,
) ([]*buxmodels.Transaction, error) {
) ([]*buxmodels.Transaction, transports.ResponseError) {
return b.transport.GetTransactions(ctx, conditions, metadata, queryParams)
}

// GetTransactionsCount get number of user transactions
func (b *BuxClient) GetTransactionsCount(ctx context.Context, conditions map[string]interface{},
metadata *buxmodels.Metadata,
) (int64, error) {
) (int64, transports.ResponseError) {
return b.transport.GetTransactionsCount(ctx, conditions, metadata)
}

// DraftToRecipients initialize a new P2PKH draft transaction to a list of recipients
func (b *BuxClient) DraftToRecipients(ctx context.Context, recipients []*transports.Recipients,
metadata *buxmodels.Metadata,
) (*buxmodels.DraftTransaction, error) {
) (*buxmodels.DraftTransaction, transports.ResponseError) {
return b.transport.DraftToRecipients(ctx, recipients, metadata)
}

// DraftTransaction initialize a new draft transaction
func (b *BuxClient) DraftTransaction(ctx context.Context, transactionConfig *buxmodels.TransactionConfig,
metadata *buxmodels.Metadata,
) (*buxmodels.DraftTransaction, error) {
) (*buxmodels.DraftTransaction, transports.ResponseError) {
return b.transport.DraftTransaction(ctx, transactionConfig, metadata)
}

// RecordTransaction record a new transaction
func (b *BuxClient) RecordTransaction(ctx context.Context, hex, draftID string,
metadata *buxmodels.Metadata,
) (*buxmodels.Transaction, error) {
) (*buxmodels.Transaction, transports.ResponseError) {
return b.transport.RecordTransaction(ctx, hex, draftID, metadata)
}

// UpdateTransactionMetadata update the metadata of a transaction
func (b *BuxClient) UpdateTransactionMetadata(ctx context.Context, txID string,
metadata *buxmodels.Metadata,
) (*buxmodels.Transaction, error) {
) (*buxmodels.Transaction, transports.ResponseError) {
return b.transport.UpdateTransactionMetadata(ctx, txID, metadata)
}

// FinalizeTransaction will finalize the transaction
func (b *BuxClient) FinalizeTransaction(draft *buxmodels.DraftTransaction) (string, error) {
func (b *BuxClient) FinalizeTransaction(draft *buxmodels.DraftTransaction) (string, transports.ResponseError) {
return transports.SignInputs(draft, b.xPriv)
}

// SendToRecipients send to recipients
func (b *BuxClient) SendToRecipients(ctx context.Context, recipients []*transports.Recipients,
metadata *buxmodels.Metadata,
) (*buxmodels.Transaction, error) {
) (*buxmodels.Transaction, transports.ResponseError) {
draft, err := b.DraftToRecipients(ctx, recipients, metadata)
if err != nil {
return nil, err
} else if draft == nil {
return nil, buxerrors.ErrDraftNotFound
return nil, transports.WrapError(buxerrors.ErrDraftNotFound)
}

var hex string
Expand Down
18 changes: 13 additions & 5 deletions transports/authentication.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ package transports
import (
"encoding/hex"
"fmt"
buxerrors "github.com/BuxOrg/bux-models/bux-errors"
"net/http"
"time"

buxmodels "github.com/BuxOrg/bux-models"
buxerrors "github.com/BuxOrg/bux-models/bux-errors"
"github.com/BuxOrg/go-buxclient/utils"
"github.com/bitcoinschema/go-bitcoin/v2"
"github.com/libsv/go-bk/bec"
Expand All @@ -18,11 +18,11 @@ import (
)

// SetSignature will set the signature on the header for the request
func SetSignature(header *http.Header, xPriv *bip32.ExtendedKey, bodyString string) error {
func SetSignature(header *http.Header, xPriv *bip32.ExtendedKey, bodyString string) ResponseError {
// Create the signature
authData, err := createSignature(xPriv, bodyString)
if err != nil {
return err
return WrapError(err)
}

// Set the auth header
Expand All @@ -32,10 +32,12 @@ func SetSignature(header *http.Header, xPriv *bip32.ExtendedKey, bodyString stri
}

// SignInputs will sign all the inputs using the given xPriv key
func SignInputs(dt *buxmodels.DraftTransaction, xPriv *bip32.ExtendedKey) (signedHex string, err error) {
func SignInputs(dt *buxmodels.DraftTransaction, xPriv *bip32.ExtendedKey) (signedHex string, resError ResponseError) {
var err error
// Start a bt draft transaction
var txDraft *bt.Tx
if txDraft, err = bt.NewTxFromString(dt.Hex); err != nil {
resError = WrapError(err)
return
}

Expand All @@ -47,6 +49,7 @@ func SignInputs(dt *buxmodels.DraftTransaction, xPriv *bip32.ExtendedKey) (signe
if ls, err = bscript.NewFromHexString(
input.Destination.LockingScript,
); err != nil {
resError = WrapError(err)
return
}
txDraft.Inputs[index].PreviousTxScript = ls
Expand All @@ -57,6 +60,7 @@ func SignInputs(dt *buxmodels.DraftTransaction, xPriv *bip32.ExtendedKey) (signe
if chainKey, err = xPriv.Child(
input.Destination.Chain,
); err != nil {
resError = WrapError(err)
return
}

Expand All @@ -65,6 +69,7 @@ func SignInputs(dt *buxmodels.DraftTransaction, xPriv *bip32.ExtendedKey) (signe
if numKey, err = chainKey.Child(
input.Destination.Num,
); err != nil {
resError = WrapError(err)
return
}

Expand All @@ -73,6 +78,7 @@ func SignInputs(dt *buxmodels.DraftTransaction, xPriv *bip32.ExtendedKey) (signe
if privateKey, err = bitcoin.GetPrivateKeyFromHDKey(
numKey,
); err != nil {
resError = WrapError(err)
return
}

Expand All @@ -81,13 +87,15 @@ func SignInputs(dt *buxmodels.DraftTransaction, xPriv *bip32.ExtendedKey) (signe
if s, err = GetUnlockingScript(
txDraft, uint32(index), privateKey,
); err != nil {
resError = WrapError(err)
return
}

// Insert the locking script
if err = txDraft.InsertInputUnlockingScript(
uint32(index), s,
); err != nil {
resError = WrapError(err)
return
}
}
Expand Down Expand Up @@ -191,7 +199,7 @@ func getSigningMessage(xPub string, auth *buxmodels.AuthPayload) string {
return fmt.Sprintf("%s%s%s%d", xPub, auth.AuthHash, auth.AuthNonce, auth.AuthTime)
}

func setSignatureHeaders(header *http.Header, authData *buxmodels.AuthPayload) error {
func setSignatureHeaders(header *http.Header, authData *buxmodels.AuthPayload) ResponseError {
// Create the auth header hash
header.Set(buxmodels.AuthHeaderHash, authData.AuthHash)

Expand Down
65 changes: 64 additions & 1 deletion transports/errors.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,72 @@
package transports

import "errors"
import (
"encoding/json"
"errors"
"fmt"
"io"
"net/http"
)

// ErrAdminKey admin key not set
var ErrAdminKey = errors.New("an admin key must be set to be able to create an xpub")

// ErrNoClientSet is when no client is set
var ErrNoClientSet = errors.New("no transport client set")

// ResError is a struct which contain information about error
type ResError struct {
StatusCode int
Message string
}

// ResponseError is an interface for error
type ResponseError interface {
Error() string
GetStatusCode() int
}

// WrapError wraps an error into ResponseError
func WrapError(err error) ResponseError {
if err == nil {
return nil
}

return &ResError{
StatusCode: http.StatusInternalServerError,
Message: err.Error(),
}
}

// WrapResponseError wraps a http response into ResponseError
func WrapResponseError(res *http.Response) ResponseError {
if res == nil {
return nil
}

var errorMsg string

err := json.NewDecoder(res.Body).Decode(&errorMsg)
if err != nil {
// if EOF, then body is empty and we return response status as error message
if !errors.Is(err, io.EOF) {
errorMsg = fmt.Sprintf("bux-server error message can't be decoded. Reason: %s", err.Error())
}
errorMsg = res.Status
}

return &ResError{
StatusCode: res.StatusCode,
Message: errorMsg,
}
}

// Error returns the error message
func (e *ResError) Error() string {
return e.Message
}

// GetStatusCode returns the status code of error
func (e *ResError) GetStatusCode() int {
return e.StatusCode
}
Loading

0 comments on commit d44309b

Please sign in to comment.