minercraft

package module
v2.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 3, 2024 License: MIT Imports: 22 Imported by: 8

README

go-minercraft

Interact with Bitcoin Miner APIs via mAPI or ARC (unofficial Go library of Minercraft)

Release Build Status Report codecov Go mAPI ARC
Mergify Status Gitpod Ready-to-Code


Table of Contents


Installation

go-minercraft requires a supported release of Go.

go get -u github.com/tonicpow/go-minercraft/v2

If you want to install the deprecated V1:

go get -u github.com/tonicpow/go-minercraft@v1

Documentation

View the generated documentation

GoDoc

This package interacts with BSV miners using the Merchant API specification.

View documentation on hosting your own mAPI server.

Features
Library Deployment

goreleaser for easy binary or library deployment to GitHub and can be installed via: brew install goreleaser.

The .goreleaser.yml file is used to configure goreleaser.

Use make release-snap to create a snapshot version of the release, and finally make release to ship to production.

Makefile Commands

View all makefile commands

make help

List of all current commands:

all                   Runs multiple commands
clean                 Remove previous builds and any test cache data
clean-mods            Remove all the Go mod cache
coverage              Shows the test coverage
diff                  Show the git diff
generate              Runs the go generate command in the base of the repo
godocs                Sync the latest tag with GoDocs
help                  Show this help message
install               Install the application
install-go            Install the application (Using Native Go)
install-releaser      Install the GoReleaser application
lint                  Run the golangci-lint application (install if not found)
release               Full production release (creates release in GitHub)
release               Runs common.release then runs godocs
release-snap          Test the full release (build binaries)
release-test          Full production test release (everything except deploy)
replace-version       Replaces the version in HTML/JS (pre-deploy)
tag                   Generate a new tag and push (tag version=0.0.0)
tag-remove            Remove a tag if found (tag-remove version=0.0.0)
tag-update            Update an existing tag to current commit (tag-update version=0.0.0)
test                  Runs lint and ALL tests
test-ci               Runs all tests via CI (exports coverage)
test-ci-no-race       Runs all tests via CI (no race) (exports coverage)
test-ci-short         Runs unit tests via CI (exports coverage)
test-no-lint          Runs just tests
test-short            Runs vet, lint and tests (excludes integration tests)
test-unit             Runs tests and outputs coverage
uninstall             Uninstall the application (and remove files)
update-linter         Update the golangci-lint package (macOS only)
vet                   Run the Go vet application

Examples & Tests

All unit tests and examples run via GitHub Actions and uses Go version 1.19.x. View the configuration file.

Run all tests (including integration tests)

make test

Run tests (excluding integration tests)

make test-short

Benchmarks

Run the Go benchmarks:

make bench

Code Standards

Read more about this Go project's code standards.


Usage

View the examples


Maintainers

MrZ
MrZ

Contributing

View the contributing guidelines and please follow the code of conduct.

How can I help?

All kinds of contributions are welcome 🙌! The most basic way to show your support is to star 🌟 the project, or to raise issues 💬. You can also support this project by becoming a sponsor on GitHub 👏 or by making a bitcoin donation to ensure this journey continues indefinitely! 🚀

Stars

Credits

Unwriter & Interplanaria for their original contribution: Minercraft which was the inspiration for this library.

nChain & team for developing the brfc-merchant-api specifications.

wregulski for adding ARC support.


License

License

Documentation

Overview

Package minercraft is an unofficial Go version of Unwriter's Minercraft

If you have any suggestions or comments, please feel free to open an issue on this GitHub repository!

By TonicPow Inc (https://tonicpow.com)

Index

Examples

Constants

View Source
const (
	// MinerTaal is the name of the known miner for "Taal"
	MinerTaal = "Taal"

	// MinerGorillaPool is the name of the known miner for "GorillaPool"
	MinerGorillaPool = "GorillaPool"

	// MinerMempool is the name of the known miner for "Mempool"
	MinerMempool = "Mempool"

	// MinerMatterpool is the name of the known miner for "Matterpool"
	MinerMatterpool = "Matterpool"
)
View Source
const KnownMiners = `` /* 247-byte string literal not displayed */

KnownMiners is a pre-filled list of known miners

View Source
const KnownMinersAPIs = `` /* 1133-byte string literal not displayed */

KnownMinersAPIs is a pre-filled list of known miners with their APIs Any pre-filled tokens are for free use only update your custom token with client.MinerUpdateToken("name", "token")

View Source
const KnownMinersAPIsAll = `` /* 1133-byte string literal not displayed */

KnownMinersAPIsAll is a pre-filled list of known miners with their APIs Any pre-filled tokens are for free use only update your custom token with client.MinerUpdateToken("name", "token") deprecated: use KnownMinersAPIsAll instead

View Source
const KnownMinersAll = `` /* 492-byte string literal not displayed */

KnownMinersAll is a pre-filled list of known miners deprecated: use KnownMiners instead

View Source
const (
	// MerkleFormatTSC can be set when calling SubmitTransaction to request a MerkleProof in TSC format.
	MerkleFormatTSC = "TSC"
)
View Source
const QueryTransactionFailure = "failure"

QueryTransactionFailure is on failure

View Source
const QueryTransactionInMempoolFailure = "Transaction in mempool but not yet in block"

QueryTransactionInMempoolFailure in mempool but not in a block yet

View Source
const QueryTransactionSuccess = "success"

QueryTransactionSuccess is on success

Variables

View Source
var Routes = []APIRoute{
	{
		Name: PolicyQuote,
		Routes: []APISpecificRoute{
			{Route: mAPIRoutePolicyQuote, APIType: MAPI},
			{Route: arcRoutePolicyQuote, APIType: Arc},
		},
	},
	{
		Name: FeeQuote,
		Routes: []APISpecificRoute{
			{Route: mAPIRouteFeeQuote, APIType: MAPI},
		},
	},
	{
		Name: QueryTx,
		Routes: []APISpecificRoute{
			{Route: mAPIRouteQueryTx, APIType: MAPI},
			{Route: arcRouteQueryTx, APIType: Arc},
		},
	},
	{
		Name: SubmitTx,
		Routes: []APISpecificRoute{
			{Route: mAPIRouteSubmitTx, APIType: MAPI},
			{Route: arcRouteSubmitTx, APIType: Arc},
		},
	},
	{
		Name: SubmitTxs,
		Routes: []APISpecificRoute{
			{Route: mAPIRouteSubmitTxs, APIType: MAPI},
			{Route: arcRouteSubmitTxs, APIType: Arc},
		},
	},
}

Routes is a list of known actions with it's routes for the different APIs

Functions

func ActionRouteByAPIType

func ActionRouteByAPIType(actionName APIActionName, apiType APIType) (string, error)

ActionRouteByAPIType will return the route for a given action and API type

func IsRetryable

func IsRetryable(err error) bool

IsRetryable can be passed an error to check if it is retryable

Types

type API

type API struct {
	Type  APIType `json:"type,omitempty"`
	Token string  `json:"token,omitempty"`
	URL   string  `json:"url,omitempty"`
}

API is a configuration per miner, including connection url, auth token, etc

type APIActionName

type APIActionName string

APIActionName is the name of the action for the API

const (
	// PolicyQuote is the name of the PolicyQuote API action
	PolicyQuote APIActionName = "PolicyQuote"
	// FeeQuote is the name of the FeeQuote API action
	FeeQuote APIActionName = "FeeQuote"
	// QueryTx is the name of the Query Transaction API action
	QueryTx APIActionName = "QueryTx"
	// SubmitTx is the name of the Submit Transaction API action
	SubmitTx APIActionName = "SubmitTx"
	// SubmitTxs is the name of the Submit multiple Transactions API action
	SubmitTxs APIActionName = "SubmitTxs"
)

type APINotFoundError

type APINotFoundError struct {
	MinerID string
	APIType APIType
}

APINotFoundError is returned when an API definition is not found for a miner

func (*APINotFoundError) Error

func (e *APINotFoundError) Error() string

Error returns the error message related to the APINotFoundError

type APIRoute

type APIRoute struct {
	Name   APIActionName      `json:"name,omitempty"`
	Routes []APISpecificRoute `json:"routes,omitempty"`
}

APIRoute contains the routes for a specific API related to a specific action

type APISpecificRoute

type APISpecificRoute struct {
	Route   string  `json:"route,omitempty"`
	APIType APIType `json:"apitype,omitempty"`
}

APISpecificRoute contains route definition for a specific API type

type APIType

type APIType string

APIType is the type of available APIs

const (
	// MAPI stands for Merchant API
	MAPI APIType = "mAPI"
	// Arc stands for Arc API
	Arc APIType = "Arc"
)

type ActionRouteNotFoundError

type ActionRouteNotFoundError struct {
	ActionName APIActionName
	APIType    APIType
}

ActionRouteNotFoundError is returned when an action route is not found for a miner

func (*ActionRouteNotFoundError) Error

func (e *ActionRouteNotFoundError) Error() string

Error returns the error message related to the ActionRouteNotFoundError

type Client

type Client struct {
	Options *ClientOptions // Client options config
	// contains filtered or unexported fields
}

Client is the parent struct that contains the miner clients and list of miners to use

func (*Client) APIType

func (c *Client) APIType() APIType

APIType will return the API type

func (*Client) AddMiner

func (c *Client) AddMiner(miner Miner, apis []API) error

AddMiner will add a new miner to the list of miners

Example

ExampleClient_AddMiner example using AddMiner()

client, err := NewClient(nil, nil, testAPIType, nil, nil)
if err != nil {
	fmt.Printf("error occurred: %s", err.Error())
	return
}

// Add a miner
if err = client.AddMiner(Miner{Name: testMinerName}, []API{{URL: testMinerURL, Type: testAPIType}}); err != nil {
	fmt.Printf("error occurred: %s", err.Error())
	return
}

// Get miner by name
fmt.Printf("created new miner named: %s", client.MinerByName(testMinerName).Name)
Output:

created new miner named: TestMiner

func (*Client) BestQuote

func (c *Client) BestQuote(ctx context.Context, feeCategory, feeType string) (*FeeQuoteResponse, error)

BestQuote will check all known miners and compare rates, returning the best rate/quote

Note: this might return different results each time if miners have the same rates as it's a race condition on which results come back first

Example

ExampleClient_BestQuote example using BestQuote()

// Create a client (using a test client vs NewClient())
client := newTestClient(&mockHTTPValidBestQuote{})

// Create a req
_, err := client.BestQuote(context.Background(), mapi.FeeCategoryMining, mapi.FeeTypeData)
if err != nil {
	fmt.Printf("error occurred: %s", err.Error())
	return
}

// Note: cannot show response since the miner might be different each time
fmt.Printf("got best quote!")
Output:

got best quote!

func (*Client) FastestQuote

func (c *Client) FastestQuote(ctx context.Context, timeout time.Duration) (*FeeQuoteResponse, error)

FastestQuote will check all known miners and return the fastest quote response

Note: this might return different results each time if miners have the same rates as it's a race condition on which results come back first

Example

ExampleClient_FastestQuote example using FastestQuote()

// Create a client (using a test client vs NewClient())
client := newTestClient(&mockHTTPValidFastestQuote{})

// Create a req
_, err := client.FastestQuote(context.Background(), defaultFastQuoteTimeout)
if err != nil {
	fmt.Printf("error occurred: %s", err.Error())
	return
}

// Note: cannot show response since the miner might be different each time
fmt.Printf("got fastest quote!")
Output:

got fastest quote!

func (*Client) FeeQuote

func (c *Client) FeeQuote(ctx context.Context, miner *Miner) (*FeeQuoteResponse, error)

FeeQuote will fire a Merchant API request to retrieve the fees from a given miner

This endpoint is used to get the different fees quoted by a miner. It returns a JSONEnvelope with a payload that contains the fees charged by a specific BSV miner. The purpose of the envelope is to ensure strict consistency in the message content for the purpose of signing responses.

Specs: https://github.com/bitcoin-sv-specs/brfc-merchantapi#2-get-fee-quote

Example

ExampleClient_FeeQuote example using FeeQuote()

// Create a client (using a test client vs NewClient())
client := newTestClient(&mockHTTPValidFeeQuote{})

// Create a req
response, err := client.FeeQuote(context.Background(), client.MinerByName(MinerTaal))
if err != nil {
	fmt.Printf("error occurred: %s", err.Error())
	return
}

fmt.Printf("got quote from: %s", response.Miner.Name)
Output:

got quote from: Taal

func (*Client) MinerAPIByMinerID

func (c *Client) MinerAPIByMinerID(minerID string, apiType APIType) (*API, error)

MinerAPIByMinerID will return a miner's API given a miner id and API type

func (*Client) MinerAPIsByMinerID

func (c *Client) MinerAPIsByMinerID(minerID string) *MinerAPIs

MinerAPIsByMinerID will return a miner's APIs given a miner id

func (*Client) MinerByID

func (c *Client) MinerByID(minerID string) *Miner

MinerByID will return a miner given a miner id

Example

ExampleClient_MinerByID example using MinerByID()

client, err := NewClient(nil, nil, testAPIType, nil, nil)
if err != nil {
	fmt.Printf("error occurred: %s", err.Error())
	return
}

// Add a miner
if err = client.AddMiner(Miner{Name: testMinerName, MinerID: testMinerID}, []API{{URL: testMinerURL, Type: testAPIType}}); err != nil {
	fmt.Printf("error occurred: %s", err.Error())
	return
}

// Get miner by id
fmt.Printf("created new miner named: %s", client.MinerByID(testMinerID).Name)
Output:

created new miner named: TestMiner

func (*Client) MinerByName

func (c *Client) MinerByName(name string) *Miner

MinerByName will return a miner given a name

Example

ExampleClient_MinerByName example using MinerByName()

client, err := NewClient(nil, nil, testAPIType, nil, nil)
if err != nil {
	fmt.Printf("error occurred: %s", err.Error())
	return
}

// Add a miner
if err = client.AddMiner(Miner{Name: testMinerName}, []API{{URL: testMinerURL, Type: testAPIType}}); err != nil {
	fmt.Printf("error occurred: %s", err.Error())
	return
}

// Get miner by name
fmt.Printf("created new miner named: %s", client.MinerByName(testMinerName).Name)
Output:

created new miner named: TestMiner

func (*Client) MinerUpdateToken

func (c *Client) MinerUpdateToken(name, token string, apiType APIType)

MinerUpdateToken will find a miner by name and update the token

Example

ExampleClient_MinerUpdateToken example using MinerUpdateToken()

client, err := NewClient(nil, nil, testAPIType, nil, nil)
if err != nil {
	fmt.Printf("error occurred: %s", err.Error())
	return
}

// Update existing miner token
client.MinerUpdateToken(MinerTaal, "9999", testAPIType)

taal := client.MinerByName(MinerTaal)
api, err := client.MinerAPIByMinerID(taal.MinerID, client.APIType())
if err != nil {
	fmt.Printf("error occurred: %s", err.Error())
	return
}

// Get miner by id
fmt.Printf("miner token found: %s", api.Token)
Output:

miner token found: 9999

func (*Client) Miners

func (c *Client) Miners() []*Miner

Miners will return the list of miners

func (*Client) PolicyQuote

func (c *Client) PolicyQuote(ctx context.Context, miner *Miner) (*PolicyQuoteResponse, error)

PolicyQuote will fire a Merchant&Arc API request to retrieve the policy from a given miner

This endpoint is used to get the different policies quoted by a miner. It returns a JSONEnvelope with a payload that contains the policies used by a specific BSV miner. The purpose of the envelope is to ensure strict consistency in the message content for the purpose of signing responses. This is a superset of the fee quote service, as it also includes information on DSNT IP addresses and miner policies.

Specs: https://github.com/bitcoin-sv-specs/brfc-merchantapi#1-get-policy-quote Specs: https://docs.gorillapool.io/arc/api.html#get-the-policy-settings

Example

ExampleClient_FeeQuote example using PolicyQuote()

// Create a client (using a test client vs NewClient())
client := newTestClient(&mockHTTPValidPolicyQuote{})

// Create a req
response, err := client.PolicyQuote(context.Background(), client.MinerByName(MinerTaal))
if err != nil {
	fmt.Printf("error occurred: %s", err.Error())
	return
}

fmt.Printf("got quote from: %s", response.Miner.Name)
Output:

got quote from: Taal

func (*Client) QueryTransaction

func (c *Client) QueryTransaction(ctx context.Context, miner *Miner, txID string, opts ...QueryTransactionOptFunc) (*QueryTransactionResponse, error)

QueryTransaction will fire a Merchant API request to check the status of a transaction

This endpoint is used to check the current status of a previously submitted transaction. It returns a JSONEnvelope with a payload that contains the transaction status. The purpose of the envelope is to ensure strict consistency in the message content for the purpose of signing responses.

You can provide optional arguments using the WithQuery... option functions, an example is shown:

QueryTransaction(ctx, miner, abc123, WithQueryMerkleProof(), WithQueryTSCMerkleFormat())

This is backwards compatible with the previous non-optional version of this function and be called with 0 options:

QueryTransaction(ctx, miner, abc123)

In this case the defaults are used which is to not request a proof. Specs: https://github.com/bitcoin-sv-specs/brfc-merchantapi#4-query-transaction-status

Example

ExampleClient_QueryTransaction example using QueryTransaction()

// Create a client (using a test client vs NewClient())
client := newTestClient(&mockHTTPValidQuery{})

// Create a req
response, err := client.QueryTransaction(context.Background(), client.MinerByName(MinerTaal), testTx)
if err != nil {
	fmt.Printf("error occurred: %s", err.Error())
	return
}

fmt.Printf("got tx status %s from: %s", response.Query.ReturnResult, response.Miner.Name)
Output:

got tx status success from: Taal

func (*Client) RemoveMiner

func (c *Client) RemoveMiner(miner *Miner) bool

RemoveMiner will remove a miner from the list

Example

ExampleClient_MinerUpdateToken example using RemoveMiner()

client, err := NewClient(nil, nil, testAPIType, nil, nil)
if err != nil {
	fmt.Printf("error occurred: %s", err.Error())
	return
}

// Update existing miner token
client.RemoveMiner(client.MinerByName(MinerTaal))

// Show response
fmt.Printf("total miners: %d", len(client.Miners()))
Output:

total miners: 1

func (*Client) SubmitTransaction

func (c *Client) SubmitTransaction(ctx context.Context, miner *Miner, tx *Transaction) (*SubmitTransactionResponse, error)

SubmitTransaction will fire a Merchant API request to submit a given transaction

This endpoint is used to send a raw transaction to a miner for inclusion in the next block that the miner creates. It returns a JSONEnvelope with a payload that contains the response to the transaction submission. The purpose of the envelope is to ensure strict consistency in the message content for the purpose of signing responses.

Specs: https://github.com/bitcoin-sv-specs/brfc-merchantapi#3-submit-transaction

Example

ExampleClient_SubmitTransaction example using SubmitTransaction()

// Create a client (using a test client vs NewClient())
client := newTestClient(&mockHTTPValidSubmission{})

tx := &Transaction{RawTx: submitTestExampleTx}

// Create a req
response, err := client.SubmitTransaction(context.Background(), client.MinerByName(MinerTaal), tx)
if err != nil {
	fmt.Printf("error occurred: %s", err.Error())
	return
}

fmt.Printf("submitted tx to: %s", response.Miner.Name)
Output:

submitted tx to: Taal

func (*Client) SubmitTransactions

func (c *Client) SubmitTransactions(ctx context.Context, miner *Miner, txs []Transaction) (*SubmitTransactionsResponse, error)

SubmitTransactions is used for submitting batched transactions

Reference: https://github.com/bitcoin-sv-specs/brfc-merchantapi#5-submit-multiple-transactions

func (*Client) UserAgent

func (c *Client) UserAgent() string

UserAgent will return the user agent

type ClientInterface

type ClientInterface interface {
	MinerService
	QuoteService
	TransactionService
	UserAgent() string
	APIType() APIType
}

ClientInterface is the MinerCraft client interface

func NewClient

func NewClient(clientOptions *ClientOptions, customHTTPClient HTTPInterface,
	apiType APIType, customMiners []*Miner, customMinersAPIDef []*MinerAPIs) (client ClientInterface, err error)

NewClient creates a new client for requests

clientOptions: inject custom client options on load customHTTPClient: use your own custom HTTP client customMiners: use your own custom list of miners

Example

ExampleNewClient example using NewClient()

client, err := NewClient(nil, nil, testAPIType, nil, nil)
if err != nil {
	fmt.Printf("error occurred: %s", err.Error())
	return
}

fmt.Printf("created new client with %d default miners", len(client.Miners()))
Output:

created new client with 2 default miners

type ClientOptions

type ClientOptions struct {
	BackOffExponentFactor          float64       `json:"back_off_exponent_factor"`
	BackOffInitialTimeout          time.Duration `json:"back_off_initial_timeout"`
	BackOffMaximumJitterInterval   time.Duration `json:"back_off_maximum_jitter_interval"`
	BackOffMaxTimeout              time.Duration `json:"back_off_max_timeout"`
	DialerKeepAlive                time.Duration `json:"dialer_keep_alive"`
	DialerTimeout                  time.Duration `json:"dialer_timeout"`
	RequestRetryCount              int           `json:"request_retry_count"`
	RequestTimeout                 time.Duration `json:"request_timeout"`
	TransportExpectContinueTimeout time.Duration `json:"transport_expect_continue_timeout"`
	TransportIdleTimeout           time.Duration `json:"transport_idle_timeout"`
	TransportMaxIdleConnections    int           `json:"transport_max_idle_connections"`
	TransportTLSHandshakeTimeout   time.Duration `json:"transport_tls_handshake_timeout"`
	UserAgent                      string        `json:"user_agent"`
}

ClientOptions holds all the configuration for connection, dialer and transport

func DefaultClientOptions

func DefaultClientOptions() (clientOptions *ClientOptions)

DefaultClientOptions will return a ClientOptions struct with the default settings. Useful for starting with the default and then modifying as needed

Example

ExampleDefaultClientOptions example using DefaultClientOptions()

options := DefaultClientOptions()
options.UserAgent = "Custom UserAgent v1.0"
client, err := NewClient(options, nil, testAPIType, nil, nil)
if err != nil {
	fmt.Printf("error occurred: %s", err.Error())
	return
}

fmt.Printf("created new client with user agent: %s", client.UserAgent())
Output:

created new client with user agent: Custom UserAgent v1.0

type ErrRetryable

type ErrRetryable struct {
	// contains filtered or unexported fields
}

ErrRetryable indicates a retryable error.

To check an error is a retryable error do:

errors.Is(err, minercraft.Retryable)

func (ErrRetryable) As

func (e ErrRetryable) As(target interface{}) bool

As will return true if the error can be cast to the target.

func (ErrRetryable) Error

func (e ErrRetryable) Error() string

func (ErrRetryable) Is

func (e ErrRetryable) Is(err error) bool

Is allows the underlying error to be checked that it is a certain error type.

func (ErrRetryable) IsRetryable

func (e ErrRetryable) IsRetryable()

IsRetryable returns true denoting this is retryable.

type ErrorResponse

type ErrorResponse struct {
	Type    string `json:"type"`
	Title   string `json:"title"`
	Status  int    `json:"status"`
	Detail  string `json:"detail"`
	TraceID string `json:"traceId"`
	// Errors will return a list of formatting errors in the case of a bad request
	// being sent to mAPI.
	Errors map[string][]string `json:"errors"`
}

ErrorResponse is the response returned from mAPI on error.

func (ErrorResponse) Error

func (e ErrorResponse) Error() string

Error defines the ErrorResponse as an error, an error can be converted to it using the below:

 var errResp ErrorResponse
 if errors.As(testErr, &errResp) {
	 // handle error
	 fmt.Println(errResp.Title)
 }

type FeeQuoteResponse

type FeeQuoteResponse struct {
	JSONEnvelope
	Quote *mapi.FeePayload `json:"quote"` // Custom field for unmarshalled payload data
}

FeeQuoteResponse is the raw response from the Merchant API request

Specs: https://github.com/bitcoin-sv-specs/brfc-merchantapi#2-get-fee-quote

type HTTPInterface

type HTTPInterface interface {
	Do(req *http.Request) (*http.Response, error)
}

HTTPInterface is used for the http client (mocking heimdall)

type JSONEnvelope

type JSONEnvelope struct {
	Miner     *Miner  `json:"miner"`     // Custom field for our internal Miner configuration
	Validated bool    `json:"validated"` // Custom field if the signature has been validated
	APIType   APIType `json:"apiType"`   // Custom field for the API type
	envelope.JSONEnvelope
}

JSONEnvelope is a standard response from the Merchant API requests

This type wraps the go-bk JSONEnvelope which performs validation of the signatures (if we have any) and will return true / false if valid.

We wrap this, so we can append some additional miner info and a validated helper property to indicate if the envelope is or isn't valid. Consumers can also independently validate the envelope.

type Miner

type Miner struct {
	MinerID string `json:"miner_id,omitempty"`
	Name    string `json:"name,omitempty"`
}

Miner is a configuration per miner, including connection url, auth token, etc

func DefaultMiners

func DefaultMiners() (miners []*Miner, err error)

DefaultMiners will parse the config JSON and return a list of miners

Example

ExampleDefaultMiners example using DefaultMiners()

miners, _ := DefaultMiners()
fmt.Printf("total miners: %d", len(miners))
Output:

total miners: 2

func MinerByID

func MinerByID(miners []*Miner, minerID string) *Miner

MinerByID will return a miner from a given set of miners

func MinerByName

func MinerByName(miners []*Miner, minerName string) *Miner

MinerByName will return a miner from a given set of miners

type MinerAPIs

type MinerAPIs struct {
	MinerID string `json:"miner_id,omitempty"`
	APIs    []API  `json:"apis,omitempty"`
}

MinerAPIs is a configuration per miner, including connection url, auth token, etc

func DefaultMinersAPIs

func DefaultMinersAPIs() (minerAPIs []*MinerAPIs, err error)

DefaultMinersAPIs will parse the config JSON and return a list of miner APIs

type MinerService

type MinerService interface {
	AddMiner(miner Miner, apis []API) error
	MinerByID(minerID string) *Miner
	MinerByName(name string) *Miner
	Miners() []*Miner
	MinerAPIsByMinerID(minerID string) *MinerAPIs
	MinerAPIByMinerID(minerID string, apiType APIType) (*API, error)
	MinerUpdateToken(name, token string, apiType APIType)
	RemoveMiner(miner *Miner) bool
}

MinerService is the MinerCraft miner related methods

type PolicyPayload

type PolicyPayload struct {
	UnifiedFeePayload                        // Inherit the same structure as the fee payload
	Callbacks         []*mapi.PolicyCallback `json:"callbacks"` // IP addresses of double-spend notification servers such as mAPI reference implementation
	Policies          *UnifiedPolicy         `json:"policies"`  // values of miner policies as configured by the mAPI reference implementation administrator
}

PolicyPayload is the unmarshalled version of the payload envelope

type PolicyQuoteArcAdapter

type PolicyQuoteArcAdapter struct {
	*arc.PolicyQuoteModel
}

PolicyQuoteArcAdapter is the adapter for the Arc response

func (*PolicyQuoteArcAdapter) GetPolicyData

func (a *PolicyQuoteArcAdapter) GetPolicyData() *PolicyPayload

GetPolicyData will return the policy data from the arc adapter

type PolicyQuoteMapiAdapter

type PolicyQuoteMapiAdapter struct {
	*mapi.PolicyQuoteModel
}

PolicyQuoteMapiAdapter is the adapter for the mAPI response

func (*PolicyQuoteMapiAdapter) GetPolicyData

func (a *PolicyQuoteMapiAdapter) GetPolicyData() *PolicyPayload

GetPolicyData will return the policy data from the mapi adapter

type PolicyQuoteModelAdapter

type PolicyQuoteModelAdapter interface {
	GetPolicyData() *PolicyPayload
}

PolicyQuoteModelAdapter is the interface for the adapter to get the policy quote response

type PolicyQuoteResponse

type PolicyQuoteResponse struct {
	JSONEnvelope
	Quote *PolicyPayload `json:"quote"` // Custom field for unmarshalled payload data
}

PolicyQuoteResponse is the raw response from the API request

Specs: https://github.com/bitcoin-sv-specs/brfc-merchantapi#1-get-policy-quote

type QueryTransactionOptFunc

type QueryTransactionOptFunc func(o *queryTransactionOpts)

QueryTransactionOptFunc defines an optional argument that can be passed to the QueryTransaction method.

func WithQueryMerkleFormat

func WithQueryMerkleFormat(s string) QueryTransactionOptFunc

WithQueryMerkleFormat can be used to overwrite the default format of TSC with another value.

func WithQueryMerkleProof

func WithQueryMerkleProof() QueryTransactionOptFunc

WithQueryMerkleProof will request that a merkle proof is returned in the query response.

func WithQueryTSCMerkleFormat

func WithQueryTSCMerkleFormat() QueryTransactionOptFunc

WithQueryTSCMerkleFormat is the default option and doesn't need to be passed however can be added for code clarity.

func WithoutQueryMerkleProof

func WithoutQueryMerkleProof() QueryTransactionOptFunc

WithoutQueryMerkleProof is the default option and doesn't need to be passed however can be added for code clarity.

type QueryTransactionResponse

type QueryTransactionResponse struct {
	JSONEnvelope
	Query *QueryTxResponse `json:"query"` // Custom field for unmarshalled payload data
}

QueryTransactionResponse is the raw response from the Merchant API request

Specs: https://github.com/bitcoin-sv-specs/brfc-merchantapi#4-query-transaction-status

type QueryTxArcAdapter

type QueryTxArcAdapter struct {
	*arc.QueryTxModel
}

QueryTxArcAdapter is the adapter for the Arc response

func (*QueryTxArcAdapter) GetQueryTxResponse

func (m *QueryTxArcAdapter) GetQueryTxResponse() *QueryTxResponse

GetQueryTxResponse will return the query tx response from arc adapter

type QueryTxMapiAdapter

type QueryTxMapiAdapter struct {
	*mapi.QueryTxModel
}

QueryTxMapiAdapter is the adapter for the mAPI response

func (*QueryTxMapiAdapter) GetQueryTxResponse

func (m *QueryTxMapiAdapter) GetQueryTxResponse() *QueryTxResponse

GetQueryTxResponse will return the query tx response from mapi adapter

type QueryTxModelAdapter

type QueryTxModelAdapter interface {
	GetQueryTxResponse() *QueryTxResponse
}

QueryTxModelAdapter is the interface for the adapter to get the query tx response

type QueryTxResponse

type QueryTxResponse struct {
	// Pola wspólne dla obu typów API
	BlockHash   string `json:"blockHash,omitempty"`
	BlockHeight int64  `json:"blockHeight,omitempty"`
	Timestamp   string `json:"timestamp,omitempty"`
	TxID        string `json:"txid,omitempty"`
	// ArcAPI specific fields
	TxStatus arc.TxStatus `json:"txStatus,omitempty"`
	// mAPI specific fields
	APIVersion            string          `json:"apiVersion,omitempty"`
	ReturnResult          string          `json:"returnResult,omitempty"`
	ResultDescription     string          `json:"resultDescription,omitempty"`
	MinerID               string          `json:"minerId,omitempty"`
	Confirmations         int64           `json:"confirmations,omitempty"`
	TxSecondMempoolExpiry int64           `json:"txSecondMempoolExpiry,omitempty"`
	MerkleProof           *bc.MerkleProof `json:"merkleProof,omitempty"`
}

QueryTxResponse is the unmarshalled version of the payload envelope

type QuoteService

type QuoteService interface {
	BestQuote(ctx context.Context, feeCategory, feeType string) (*FeeQuoteResponse, error)
	FastestQuote(ctx context.Context, timeout time.Duration) (*FeeQuoteResponse, error)
	FeeQuote(ctx context.Context, miner *Miner) (*FeeQuoteResponse, error)
	PolicyQuote(ctx context.Context, miner *Miner) (*PolicyQuoteResponse, error)
}

QuoteService is the MinerCraft quote related requests

type RawSubmitTransactionsResponse

type RawSubmitTransactionsResponse struct {
	Encoding  string `json:"encoding"`
	MimeType  string `json:"mimetype"`
	Payload   string `json:"payload"`
	PublicKey string `json:"publicKey"`
	Signature string `json:"signature"`
}

RawSubmitTransactionsResponse is the response returned from mapi where payload is a string.

type RequestResponse

type RequestResponse struct {
	BodyContents []byte `json:"body_contents"` // Raw body response
	Error        error  `json:"error"`         // If an error occurs
	Method       string `json:"method"`        // Method is the HTTP method used
	PostData     string `json:"post_data"`     // PostData is the post data submitted if POST/PUT request
	StatusCode   int    `json:"status_code"`   // StatusCode is the last code from the request
	URL          string `json:"url"`           // URL is used for the request
}

RequestResponse is the response from a request

type Retryable

type Retryable interface {
	// IsRetryable if a method has this method then it's a retryable error.
	IsRetryable()
}

Retryable can be implemented to identify a struct as retryable, in this case an error can be deemed retryable.

type SubmitTransactionResponse

type SubmitTransactionResponse struct {
	JSONEnvelope
	Results *UnifiedSubmissionPayload `json:"results"` // Custom field for unmarshalled payload data
}

SubmitTransactionResponse is the raw response from the Merchant API request

Specs: https://github.com/bitcoin-sv-specs/brfc-merchantapi#3-submit-transaction

type SubmitTransactionsResponse

type SubmitTransactionsResponse struct {
	Encoding  string            `json:"encoding"`
	MimeType  string            `json:"mimetype"`
	Payload   UnifiedTxsPayload `json:"payload"`
	PublicKey string            `json:"publicKey"`
	Signature string            `json:"signature"`
}

SubmitTransactionsResponse is the formatted response which converts payload string to payloads.

type SubmitTxArcAdapter

type SubmitTxArcAdapter struct {
	*arc.SubmitTxModel
}

SubmitTxArcAdapter is the adapter for the Arc response

func (*SubmitTxArcAdapter) GetSubmitTxResponse

func (a *SubmitTxArcAdapter) GetSubmitTxResponse() *UnifiedSubmissionPayload

GetSubmitTxResponse will return the unified response for Arc adapter

type SubmitTxMapiAdapter

type SubmitTxMapiAdapter struct {
	*mapi.SubmitTxModel
}

SubmitTxMapiAdapter is the adapter for the mAPI response

func (*SubmitTxMapiAdapter) GetSubmitTxResponse

func (a *SubmitTxMapiAdapter) GetSubmitTxResponse() *UnifiedSubmissionPayload

GetSubmitTxResponse will return the unified response for mAPI adapter

type SubmitTxModelAdapter

type SubmitTxModelAdapter interface {
	GetSubmitTxResponse() *UnifiedSubmissionPayload
}

SubmitTxModelAdapter is the interface for the adapter to get the submit tx response

type Transaction

type Transaction struct {
	CallBackEncryption string       `json:"callBackEncryption,omitempty"`
	CallBackToken      string       `json:"callBackToken,omitempty"`
	CallBackURL        string       `json:"callBackUrl,omitempty"`
	DsCheck            bool         `json:"dsCheck,omitempty"`
	MerkleFormat       string       `json:"merkleFormat,omitempty"`
	MerkleProof        bool         `json:"merkleProof,omitempty"`
	RawTx              string       `json:"rawtx"`
	WaitForStatus      arc.TxStatus `json:"waitForStatus,omitempty"`
}

Transaction is the body contents in the "submit transaction" request

type TransactionService

type TransactionService interface {
	QueryTransaction(ctx context.Context, miner *Miner, txID string, opts ...QueryTransactionOptFunc) (*QueryTransactionResponse, error)
	SubmitTransaction(ctx context.Context, miner *Miner, tx *Transaction) (*SubmitTransactionResponse, error)
	SubmitTransactions(ctx context.Context, miner *Miner, txs []Transaction) (*SubmitTransactionsResponse, error)
}

TransactionService is the MinerCraft transaction related methods

type UnifiedFeePayload

type UnifiedFeePayload struct {
	mapi.FeePayloadFields
	Fees []*bt.Fee `json:"fees"`
}

UnifiedFeePayload is the unmarshalled version of the payload envelope

type UnifiedPolicy

type UnifiedPolicy struct {
	AcceptNonStdOutputs             bool              `json:"acceptnonstdoutputs"`
	DataCarrier                     bool              `json:"datacarrier"`
	DataCarrierSize                 uint32            `json:"datacarriersize"`
	LimitAncestorCount              uint32            `json:"limitancestorcount"`
	LimitCpfpGroupMembersCount      uint32            `json:"limitcpfpgroupmemberscount"`
	MaxNonStdTxValidationDuration   uint32            `json:"maxnonstdtxvalidationduration"`
	MaxScriptNumLengthPolicy        uint32            `json:"maxscriptnumlengthpolicy"`
	MaxScriptSizePolicy             uint32            `json:"maxscriptsizepolicy"`
	MaxStackMemoryUsagePolicy       uint64            `json:"maxstackmemoryusagepolicy"`
	MaxStdTxValidationDuration      uint32            `json:"maxstdtxvalidationduration"`
	MaxTxSizePolicy                 uint32            `json:"maxtxsizepolicy"`
	SkipScriptFlags                 []mapi.ScriptFlag `json:"skipscriptflags"`
	MaxConsolidationFactor          uint32            `json:"minconsolidationfactor"`
	MaxConsolidationInputScriptSize uint32            `json:"maxconsolidationinputscriptsize"`
	MinConfConsolidationInput       uint32            `json:"minconfconsolidationinput"`
	AcceptNonStdConsolidationInput  bool              `json:"acceptnonstdconsolidationinput"`

	// Additional fields for Policy in API2
	MaxTxSigOpsCount uint32 `json:"maxtxsigopscount"`
}

UnifiedPolicy is the unmarshalled version of the policy

type UnifiedSubmissionPayload

type UnifiedSubmissionPayload struct {
	// mAPI
	APIVersion                string                 `json:"apiVersion"`
	ConflictedWith            []*mapi.ConflictedWith `json:"conflictedWith"`
	CurrentHighestBlockHash   string                 `json:"currentHighestBlockHash"`
	CurrentHighestBlockHeight int64                  `json:"currentHighestBlockHeight"`
	MinerID                   string                 `json:"minerId"`
	ResultDescription         string                 `json:"resultDescription"`
	ReturnResult              string                 `json:"returnResult"`
	Timestamp                 string                 `json:"timestamp"`
	TxID                      string                 `json:"txid"`
	TxSecondMempoolExpiry     int64                  `json:"txSecondMempoolExpiry"`
	// FailureRetryable if true indicates the tx can be resubmitted to mAPI.
	FailureRetryable bool `json:"failureRetryable"`

	// Arc
	BlockHash   string       `json:"blockHash,omitempty"`
	BlockHeight int64        `json:"blockHeight,omitempty"`
	ExtraInfo   string       `json:"extraInfo,omitempty"`
	Status      int          `json:"status,omitempty"`
	Title       string       `json:"title,omitempty"`
	TxStatus    arc.TxStatus `json:"txStatus,omitempty"`
}

UnifiedSubmissionPayload is the unmarshalled version of the payload envelope

type UnifiedTx

type UnifiedTx struct {
	// mAPI specific fields
	ConflictedWith    []mapi.ConflictedWith `json:"conflictedWith,omitempty"`
	ResultDescription string                `json:"resultDescription"`
	ReturnResult      string                `json:"returnResult"`
	TxID              string                `json:"txid"`

	// FailureRetryable if true indicates the tx can be resubmitted to mAPI.
	FailureRetryable bool `json:"failureRetryable"`

	// Arc specific fields
	BlockHash   string       `json:"blockHash,omitempty"`
	BlockHeight int64        `json:"blockHeight,omitempty"`
	ExtraInfo   string       `json:"extraInfo,omitempty"`
	Status      int          `json:"status,omitempty"`
	Timestamp   time.Time    `json:"timestamp,omitempty"`
	Title       string       `json:"title,omitempty"`
	TxStatus    arc.TxStatus `json:"txStatus,omitempty"`
}

UnifiedTx is the transaction format in the mapi txs response.

type UnifiedTxsPayload

type UnifiedTxsPayload struct {
	APIVersion                string      `json:"apiVersion"`
	CurrentHighestBlockHash   string      `json:"currentHighestBlockHash"`
	CurrentHighestBlockHeight int         `json:"currentHighestBlockHeight"`
	FailureCount              int         `json:"failureCount"`
	MinerID                   string      `json:"minerId"`
	Timestamp                 time.Time   `json:"timestamp"`
	Txs                       []UnifiedTx `json:"txs"`
	TxSecondMempoolExpiry     int         `json:"txSecondMempoolExpiry"`
}

UnifiedTxsPayload is the structure of the json payload string in the MapiResponse.

Directories

Path Synopsis
apis
arc
Package arc provides the API structures for the ARC service
Package arc provides the API structures for the ARC service
mapi
Package mapi provides the API structures for the mAPI service
Package mapi provides the API structures for the mAPI service
examples

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL