alchemyws

package module
v0.3.0 Latest Latest
Warning

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

Go to latest
Published: Jul 1, 2025 License: MIT Imports: 7 Imported by: 0

README

Alchemy WS Client (Go)

A minimal and idiomatic Go client for Alchemy WebSocket API.

This library provides real-time access to Ethereum transaction events using Alchemy WebSocket interface. It supports subscriptions for:

  • Mined transactions (hash or full payload)

  • Pending transactions (hash or full payload)

Designed for use in Go services where performance, clarity, and reliability matter.

⚠️ Warning: This library is currently in active development (v0.3.0). The API is evolving, and improvements are ongoing.

Features

  • Subscribe to mined transactions as either:

    • transaction hashes (lightweight mode)

    • full transaction objects (full mode)

  • Subscribe to pending transactions as either:

    • transaction hashes (lightweight mode)

    • full transaction objects (full mode)

  • Subscribe to new block headers (newHeads):

    • receive full block metadata for every new chain head

    • includes support for handling chain reorganizations (reorgs)

  • Subscribe to logs (logs):

    • filter logs by address and topic combinations

    • receive logs from newly mined blocks

    • handles reorgs and removed flag for dropped logs

  • Subscribe to raw pending transaction hashes via newPendingTransactions:

    • lightweight stream of transaction hashes from Alchemy mempool
  • Non-blocking, buffered channels for event streams

  • Graceful handling of decode failures and malformed messages

  • Idiomatic Go API with minimal dependencies

Installation

To install the Alchemy WS Client, use go get:

go get github.com/yermakovsa/alchemyws

Then import it in your Go code:

import github.com/yermakovsa/alchemyws

This library requires Go 1.18+.

Usage

Here is a basic example to get you started with subscribing to mined and pending transactions using the Alchemy WS Client:

package main

import (
	"context"
	"fmt"
	"log"
	"os"
	"os/signal"
	"syscall"

	"github.com/yermakovsa/alchemyws"
)

func main() {
	// Replace with your actual Alchemy API key
	apiKey := "your-alchemy-api-key"

	client, err := alchemyws.NewAlchemyClient(apiKey, nil)
	if err != nil {
		log.Fatalf("failed to create client: %v", err)
	}
	defer client.Close()

	minedCh, err := client.SubscribeMined(alchemyws.MinedTxOptions{
		Addresses: []alchemyws.AddressFilter{
			{From: "0x28C6c06298d514Db089934071355E5743bf21d60"}, // Binance hot wallet ETH
		},
		HashesOnly: false,
	})
	if err != nil {
		log.Fatalf("failed to subscribe to mined transactions: %v", err)
	}

	pendingCh, err := client.SubscribePending(alchemyws.PendingTxOptions{
		FromAddress: []string{"0x28C6c06298d514Db089934071355E5743bf21d60"}, // Binance hot wallet ETH
		HashesOnly:  false,
	})
	if err != nil {
		log.Fatalf("failed to subscribe to pending transactions: %v", err)
	}

	ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
	defer stop()

	fmt.Println("Listening for mined and pending transactions...")

	for {
		select {
		case minedTx := <-minedCh:
			fmt.Printf("Mined transaction: %+v\n", minedTx)
		case pendingTx := <-pendingCh:
			fmt.Printf("Pending transaction: %+v\n", pendingTx)
		case <-ctx.Done():
			fmt.Println("Shutting down...")
			return
		}
	}
}
Key Points:
  • Use NewAlchemyClient to create a new client instance with your API key.

  • Call SubscribeMined and SubscribePending to receive channels streaming mined and pending transactions.

  • Handle incoming events by reading from the returned channels.

  • Gracefully handle termination signals to close the client properly.

⚙️ For more complete usage examples, including subscriptions to newHeads, see the examples/ directory.

API Reference

func NewAlchemyClient(apiKey string, logger *log.Logger) (*AlchemyClient, error)

Creates a new Alchemy WebSocket client.

Parameters:
  • apiKey - Your Alchemy API key (required).
  • logger - Optional logger for debugging
Returns:
  • *AlchemyClient - Client instance.
  • error - Initialization error, if any.
func (a *AlchemyClient) SubscribeMined(opts MinedTxOptions) (<-chan MinedTxEvent, error)

Subscribes to mined transaction events with optional filtering.

Parameters
  • opts - Subscription options:
    • Addresses []AddressFilter - Filter transactions by sender (From) and receiver (To) addresses.
    • IncludeRemoved bool - If true, includes events for removed transactions (e.g., chain reorganizations).
    • HashesOnly bool - If true, only transaction hashes are sent instead of full transaction data.
Returns
  • <-chan MinedTxEvent - Channel delivering mined transaction events.
  • error - Subscription error, if any.
func (a *AlchemyClient) SubscribePending(opts PendingTxOptions) (<-chan PendingTxEvent, error)

Subscribes to pending transaction events with optional filtering.

Parameters
  • opts - Subscription options:
    • FromAddress []string - Filter pending transactions by sender addresses.
    • ToAddress []string - Filter pending transactions by receiver addresses.
    • HashesOnly bool - If true, only transaction hashes are sent instead of full transaction data.
Returns
  • <-chan PendingTxEvent - Channel delivering pending transaction events.
  • error - Subscription error, if any.
func (a *AlchemyClient) SubscribeNewHeads() (<-chan NewHeadEvent, error)

Subscribes to new block headers (newHeads) as they are added to the blockchain.

This subscription emits a new event each time a block is appended to the chain, including during chain reorganizations. In case of reorgs, multiple headers with the same block number may be emitted. The most recent one should be considered correct.

Parameters

None

Returns
  • <-chan NewHeadEvent - Channel delivering new block header events.
  • error - Subscription error, if any.
func (a *AlchemyClient) SubscribeLogs(filter LogsFilter) (<-chan LogEvent, error)

Subscribes to logs emitted in new blocks based on address and topic filters.

This subscription provides log events for contracts emitting logs that match the given criteria. It also supports handling of chain reorganizations via the removed field.

Parameters
  • filter - Log subscription filter options:
    • Address string - Filter logs by emitting contract address(es).
    • Topics [][]string - Up to 4 indexed topic filters for the log event signature and parameters.
Returns
  • <-chan LogEvent - Channel delivering log events.
  • error - Subscription error, if any.
func (a *AlchemyClient) SubscribeNewPendingTransactions() (<-chan string, error)

Subscribes to raw pending transaction hashes via the newPendingTransactions method.

This stream emits transaction hashes for all transactions seen in the Alchemy mempool (no filtering or full objects provided).

Parameters

None

Returns
  • <-chan string - Channel delivering pending transaction hashes.
  • error - Subscription error, if any.
func (a *AlchemyClient) Close() error

Closes the WebSocket connection and cleans up resources.

Returns
  • error - Error on close failure, if any.

License

This project is licensed under the MIT License.

You are free to use, modify, and distribute this software in both personal and commercial projects, as long as you include the original license and copyright

Documentation

Index

Constants

View Source
const (
	AlchemyWSURL                 = "wss://eth-mainnet.g.alchemy.com/v2/"
	JSONRPCVersion               = "2.0"
	MethodMined                  = "alchemy_minedTransactions"
	MethodPending                = "alchemy_pendingTransactions"
	MethodNewHeads               = "newHeads"
	MethodLogs                   = "logs"
	MethodNewPendingTransactions = "newPendingTransactions"
)

Variables

This section is empty.

Functions

This section is empty.

Types

type AddressFilter

type AddressFilter struct {
	From string `json:"from,omitempty"`
	To   string `json:"to,omitempty"`
}

AddressFilter can filter transactions by sender and receiver addresses.

type AlchemyClient

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

func NewAlchemyClient

func NewAlchemyClient(apiKey string, logger *log.Logger) (*AlchemyClient, error)

NewAlchemyClient connects to Alchemy's WebSocket API and starts a single read loop

func (*AlchemyClient) Close

func (a *AlchemyClient) Close() error

Close shuts down the WebSocket connection

func (*AlchemyClient) SubscribeLogs added in v0.2.0

func (a *AlchemyClient) SubscribeLogs(filter LogsFilter) (<-chan LogEvent, error)

func (*AlchemyClient) SubscribeMined

func (a *AlchemyClient) SubscribeMined(opts MinedTxOptions) (<-chan MinedTxEvent, error)

SubscribeMined subscribes to mined transactions

func (*AlchemyClient) SubscribeNewHeads added in v0.1.1

func (a *AlchemyClient) SubscribeNewHeads() (<-chan NewHeadEvent, error)

SubscribeNewHeads subscribes to new block headers added to the blockchain.

func (*AlchemyClient) SubscribeNewPendingTransactions added in v0.3.0

func (a *AlchemyClient) SubscribeNewPendingTransactions() (<-chan string, error)

SubscribeNewPendingTransactions subscribes to pending transaction hashes.

func (*AlchemyClient) SubscribePending

func (a *AlchemyClient) SubscribePending(opts PendingTxOptions) (<-chan PendingTxEvent, error)

SubscribePending subscribes to pending transactions

type LogEvent added in v0.2.0

type LogEvent struct {
	Address          string   `json:"address"`
	BlockHash        string   `json:"blockHash"`
	BlockNumber      string   `json:"blockNumber"`
	Data             string   `json:"data"`
	LogIndex         string   `json:"logIndex"`
	Topics           []string `json:"topics"`
	TransactionHash  string   `json:"transactionHash"`
	TransactionIndex string   `json:"transactionIndex"`
	Removed          bool     `json:"removed,omitempty"`
}

LogEvent represents a log emitted by the logs subscription.

type LogsFilter added in v0.2.0

type LogsFilter struct {
	Address string     `json:"address,omitempty"`
	Topics  [][]string `json:"topics,omitempty"` // can be null, string, or array of strings
}

LogsFilter represents the subscription filter for logs.

type MinedTxEvent

type MinedTxEvent struct {
	Removed     bool        `json:"removed"`
	Transaction Transaction `json:"transaction,omitempty"`
	Hash        string      `json:"hash,omitempty"`
}

MinedTxEvent wraps the transaction and removal status.

type MinedTxOptions

type MinedTxOptions struct {
	Addresses      []AddressFilter `json:"addresses,omitempty"`
	IncludeRemoved bool            `json:"includeRemoved,omitempty"`
	HashesOnly     bool            `json:"hashesOnly,omitempty"`
}

MinedTxOptions defines the parameters for the subscription request.

type NewHeadEvent added in v0.1.1

type NewHeadEvent struct {
	Number           string `json:"number"`
	ParentHash       string `json:"parentHash"`
	Nonce            string `json:"nonce"`
	Sha3Uncles       string `json:"sha3Uncles"`
	LogsBloom        string `json:"logsBloom"`
	TransactionsRoot string `json:"transactionsRoot"`
	StateRoot        string `json:"stateRoot"`
	ReceiptsRoot     string `json:"receiptsRoot"`
	Miner            string `json:"miner"`
	Difficulty       string `json:"difficulty"`
	ExtraData        string `json:"extraData"`
	GasLimit         string `json:"gasLimit"`
	GasUsed          string `json:"gasUsed"`
	Timestamp        string `json:"timestamp"`
}

NewHeadEvent represents a new block header received via the newHeads subscription.

type PendingTxEvent

type PendingTxEvent struct {
	Transaction Transaction `json:"transaction,omitempty"`
	Hash        string      `json:"hash,omitempty"`
}

PendingTxEvent represents either a full pending transaction or a hash depending on the HashesOnly flag in subscription.

type PendingTxOptions

type PendingTxOptions struct {
	FromAddress []string `json:"fromAddress,omitempty"`
	ToAddress   []string `json:"toAddress,omitempty"`
	HashesOnly  bool     `json:"hashesOnly,omitempty"`
}

PendingTxOptions defines parameters for subscribing to pending transactions

type Transaction

type Transaction struct {
	BlockHash        string `json:"blockHash"`
	BlockNumber      string `json:"blockNumber"`
	From             string `json:"from"`
	Gas              string `json:"gas"`
	GasPrice         string `json:"gasPrice"`
	Hash             string `json:"hash"`
	Input            string `json:"input"`
	Nonce            string `json:"nonce"`
	To               string `json:"to"`
	TransactionIndex string `json:"transactionIndex"`
	Value            string `json:"value"`
	V                string `json:"v"`
	R                string `json:"r"`
	S                string `json:"s"`
	Type             string `json:"type"`
}

Transaction is the generic Ethereum transaction format for mined or pending When pending, many fields may be null.

type WSConn

type WSConn interface {
	Read(ctx context.Context) (websocket.MessageType, []byte, error)
	Write(ctx context.Context, typ websocket.MessageType, p []byte) error
	Close(code websocket.StatusCode, reason string) error
}

Directories

Path Synopsis
examples
subscribe_logs command

Jump to

Keyboard shortcuts

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