github.com/calmw/chainpulse


Install
go get github.com/calmw/chainpulse

Documentation

ChainPulse Go SDK

Go SDK for ChainPulse query and webhook services.

go get github.com/calmw/chainpulse

Layout

.
├── client.go          # Client options and construction
├── request.go         # HTTP transport, HMAC signing, error handling
├── query.go           # Query API methods
├── query_params.go    # Query API common parameters
├── webhook.go         # Webhook management and signature helpers
├── models.go          # Public response/request models
├── errors.go          # APIError
└── examples/
    ├── query/
    ├── create_webhook/
    └── webhook_receiver/

Query API

Query responses format timestamps as YYYY-MM-DD HH:mm:ss (UTC). SDK models use FlexTime for blockTime, updatedAt, and webhook createdAt. Requires v1.0.2+ (or this repo's sdk/golang); v1.0.0/v1.0.1 used time.Time and failed to decode Query/Webhook payloads.

Query service uses HMAC headers:

  • X-API-Key
  • X-API-Timestamp
  • X-API-Nonce
  • X-API-Signature

The SDK signs requests automatically.

package main

import (
	"context"
	"fmt"

	chainpulse "github.com/calmw/chainpulse"
)

func main() {
	client := chainpulse.NewClient(
		chainpulse.WithQueryBaseURL("https://query.chainpulse.cc"),
		chainpulse.WithAPIKey("ck_live_xxx", "sk_live_xxx"),
	)

	tx, err := client.GetTransaction(context.Background(), "0xabc")
	if err != nil {
		panic(err)
	}
	fmt.Println(tx.TxHash)
}

Common query methods (optional QueryParams: chainId, consistency, includeRemoved, limit):

  • GetTransaction(ctx, txHash, params...)
  • ListTransactionInternalTransactions(ctx, txHash, params...)
  • ListAddressTransactions(ctx, address, params...)
  • ListAddressBalances(ctx, address, params...)
  • ListNFTBalances(ctx, address, standard, params...)
  • ListEvents(ctx, options, params...)
  • ListContractEvents(ctx, contractAddress, options, params...)

Example with consistency:

tx, err := client.GetTransaction(ctx, "0xabc", chainpulse.QueryParams{
	ChainID:     56,
	Consistency: "stable",
})

Webhook Management

Webhook subscription management uses the server API bearer token from user login.

client := chainpulse.NewClient(
	chainpulse.WithServerAPIURL("https://chainpulse.cc/api"),
	chainpulse.WithBearerToken("user_jwt_token"),
)

created, err := client.CreateWebhook(context.Background(), chainpulse.WebhookConfig{
	URL:    "https://example.com/webhook",
	Events: []string{"coin.balance_changed", "token.balance_changed", "contract.event"},
})
if err != nil {
	panic(err)
}
fmt.Println(created.WebhookID, created.Secret)

Examples

See examples/README.md for the full integration walkthrough.

Query address balances:

cd examples/query
CHAINPULSE_API_KEY=ck_live_xxx \
CHAINPULSE_API_SECRET=sk_live_xxx \
go run .

Create a webhook subscription:

cd examples/create_webhook
CHAINPULSE_BEARER_TOKEN=user_jwt_token \
CHAINPULSE_WEBHOOK_URL=https://your-service.example.com/webhook \
go run .

Run a webhook receiver:

cd examples/webhook_receiver
CHAINPULSE_WEBHOOK_SECRET=whsec_xxx go run .

Webhook methods:

  • CreateWebhook(ctx, config)
  • ListWebhooks(ctx)
  • UpdateWebhook(ctx, webhookID, config)
  • DeleteWebhook(ctx, webhookID)

Webhook Receiver

Use VerifyWebhookSignature to verify payloads received from the webhook service.

func handler(w http.ResponseWriter, r *http.Request) {
	body, _ := io.ReadAll(r.Body)
	ok := chainpulse.VerifyWebhookSignature(
		"whsec_xxx",
		r.Header.Get("X-Bot-Timestamp"),
		body,
		r.Header.Get("X-Bot-Signature"),
		5*time.Minute,
	)
	if !ok {
		http.Error(w, "invalid signature", http.StatusUnauthorized)
		return
	}

	event, err := chainpulse.ParseWebhookEvent(body)
	if err != nil {
		// Platform timestamps use YYYY-MM-DD HH:mm:ss; use chainpulse >= v1.0.1 (FlexTime).
		http.Error(w, "invalid payload", http.StatusBadRequest)
		return
	}
	fmt.Println(event.EventType, event.TxHash)
}