weeasycrypto

package module
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: Jul 17, 2026 License: MIT Imports: 18 Imported by: 0

README

weeasycrypto (Go)

Official Go SDK for the WeEasyCrypto tenant API: deposit addresses, balances, deposits, withdrawals, and signed webhooks.

  • Zero dependencies outside the Go standard library.
  • Signing you never hand-write. Every request carries an Ed25519 signature (X-Timestamp + X-Signature, stdlib crypto/ed25519) computed over the exact bytes sent on the wire — the platform holds only your public key and can verify, never forge. Webhook deliveries are Ed25519-signed too (v1a, per-tenant platform key) — verified with your tenant's public key, ±300 s tolerance.
  • Amounts are decimal strings, never floats. ParseAmount / FormatAmount use *big.Int integer arithmetic only.

⚠️ Server-side only. Your Ed25519 PrivateKey must never reach a client bundle — it was generated locally when the key was issued and the platform cannot recover it.

Install

go get github.com/weeasycrypto/sdk/go

Quickstart

import weeasycrypto "github.com/weeasycrypto/sdk/go"

cv, err := weeasycrypto.New(weeasycrypto.Options{
	BaseURL:       "https://api.example.com",
	APIKey:        os.Getenv("WEEASYCRYPTO_API_KEY"),     // keyId, e.g. "ck_…"
	PrivateKey:    os.Getenv("WEEASYCRYPTO_PRIVATE_KEY"), // hex Ed25519 seed, generated at issuance
	WebhookPublicKey: os.Getenv("WEEASYCRYPTO_WEBHOOK_PUBLIC_KEY"), // portal → Settings → Integrations
})

// Issue a deposit address
addr, err := cv.Addresses.Create(ctx, weeasycrypto.CreateAddressParams{
	Label: "user-42", ChainKey: "tron",
})
_ = addr.Family // "EVM" | "TRON" | "BTC" | "SOL" | "TON"

// Balances — amounts are decimal strings, never floats
balances, err := cv.Balances.List(ctx)

// Deposits with auto-pagination
for d, err := range cv.Deposits.Iterate(ctx, weeasycrypto.ListDepositsParams{
	Status: weeasycrypto.DepositConfirmed,
}) {
	if err != nil {
		return err
	}
	fmt.Println(d.TxHash, d.Amount)
}

Withdrawals — the idempotency contract

RequestID is your idempotency key. Persist it in your own database before calling; the SDK deliberately never generates one, because a regenerated key after a crash is how double-payouts happen.

w, err := cv.Withdrawals.Create(ctx, weeasycrypto.CreateWithdrawalParams{
	RequestID:   "wd-20260710-0001", // yours, persisted first
	ChainKey:    "eth-mainnet",
	TokenSymbol: "USDT",
	To:          "0x…",
	Amount:      "100.5", // always a string
})
var apiErr *weeasycrypto.APIError
if errors.As(err, &apiErr) && apiErr.IsDuplicateRequest() {
	// Safety signal, not a failure: an earlier attempt already created it.
	// Look the withdrawal up via the id you stored against this RequestID.
}

// Poll to a terminal status (webhooks are the push-based alternative)
final, err := cv.Withdrawals.WaitUntilFinal(ctx, w.ID, weeasycrypto.WaitOptions{})
if final.Status == weeasycrypto.WithdrawalConfirmed {
	fmt.Println(*final.TxHash)
}

Network errors on Withdrawals.Create / CreateBatch are retried automatically with the same RequestID — that can never double-spend. Addresses.Create has no idempotency key, so it is never auto-retried; List recent addresses before creating again if the outcome was unknown.

Webhooks

Deliveries carry X-Webhook-Signature: t={ts},v1a={hex} — an Ed25519 signature over {ts}.{body} made with a per-tenant platform key. Verification needs only your tenant's public key (webhookSignPublicKey in the merchant portal, Settings → Integrations); there is no shared secret to protect.

http.HandleFunc("/webhook", func(w http.ResponseWriter, r *http.Request) {
	rawBody, _ := io.ReadAll(r.Body) // exact bytes — do not re-serialize
	event, err := cv.Webhooks.Parse(rawBody, r.Header.Get("X-Webhook-Signature"))
	if err != nil {
		w.WriteHeader(http.StatusBadRequest)
		return
	}
	switch event.Type {
	case "deposit.confirmed":
		data, _ := event.DepositEventData()
		credit(data.DepositID, data.Amount)
	case "withdrawal.completed":
		data, _ := event.WithdrawalEventData()
		markPaid(data.RequestID)
	default:
		// New event types appear over time — ignore what you don't know.
	}
	w.WriteHeader(http.StatusOK)
})

Errors

All API failures surface as *weeasycrypto.APIError (match with errors.As, then on Status / Code). Transport failures surface as *weeasycrypto.NetworkError — for withdrawal calls those are safe to retry with the same RequestID.

Testing

go vet ./... && go test ./...

Signing is verified against the shared golden vectors in ../vectors/signing-vectors.json.

Documentation

Overview

Package weeasycrypto is the official Go SDK for the WeEasyCrypto tenant API: deposit addresses, balances, deposits, withdrawals, and signed webhooks. Zero dependencies outside the standard library.

Amounts are always decimal strings, never floats. requestId is YOUR idempotency key — persist it before calling, the SDK never generates one.

Index

Constants

View Source
const (
	CodeBadRequest          = "BAD_REQUEST"
	CodeInvalidAmount       = "INVALID_AMOUNT"
	CodeUnauthorized        = "UNAUTHORIZED"
	CodeForbidden           = "FORBIDDEN"
	CodeNotFound            = "NOT_FOUND"
	CodeDuplicateRequest    = "DUPLICATE_REQUEST"
	CodeStateConflict       = "STATE_CONFLICT"
	CodeValidationFailed    = "VALIDATION_FAILED"
	CodeInsufficientBalance = "INSUFFICIENT_BALANCE"
	CodeRateLimited         = "RATE_LIMITED"
	CodeInternalError       = "INTERNAL_ERROR"
)

Stable error codes emitted by the API envelope. The server may introduce new codes at any time — always compare against the constant, never enumerate exhaustively.

Variables

This section is empty.

Functions

func FormatAmount

func FormatAmount(raw *big.Int, decimals int) string

FormatAmount converts a minimal-unit *big.Int back to a human-readable decimal string (trailing zeros trimmed).

FormatAmount(big.NewInt(100500000), 6) // "100.5"

func ParseAmount

func ParseAmount(human string, decimals int) (*big.Int, error)

ParseAmount converts a human-readable decimal string to a minimal-unit *big.Int. Strict: rejects negatives, exponents, and more fractional digits than decimals — the same rules the server applies (400 INVALID_AMOUNT).

ParseAmount("100.5", 6) // 100500000

Types

type APIError

type APIError struct {
	Status  int
	Code    string
	Message string
	// RetryAfter is the suggested wait from the Retry-After header on 429
	// responses; 0 when the server didn't send one.
	RetryAfter time.Duration
}

APIError is a non-2xx API response. Code is the stable machine-readable error code from the response envelope; Status is the HTTP status. Match with errors.As and then on Status / Code:

var apiErr *weeasycrypto.APIError
if errors.As(err, &apiErr) && apiErr.IsDuplicateRequest() { … }

func (*APIError) Error

func (e *APIError) Error() string

func (*APIError) IsDuplicateRequest

func (e *APIError) IsDuplicateRequest() bool

IsDuplicateRequest reports whether a 409 means the requestId was already used: the withdrawal exists and the retry was idempotent-safe. Treat it as success-shaped — look the withdrawal up via your own requestId → id mapping rather than surfacing an error.

type AddressesService

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

AddressesService is /v1/addresses — deposit address issuance and listing.

func (*AddressesService) Create

Create issues a deposit address.

Not retried automatically on network errors (no idempotency key): if the outcome is unknown, List recent addresses before creating again — duplicate addresses carry no fund risk but pollute your label bookkeeping.

func (*AddressesService) Iterate

Iterate auto-paginates over all addresses.

func (*AddressesService) List

List returns addresses, newest first.

type Balance

type Balance struct {
	ChainKey  string `json:"chainKey"`
	Symbol    string `json:"symbol"`
	TokenID   string `json:"tokenId"`
	Available string `json:"available"`
	Locked    string `json:"locked"`
}

Balance is a per-token balance. Available / Locked are human-readable decimal strings — convert with ParseAmount, never with strconv.ParseFloat.

type BalancesService

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

BalancesService is /v1/balances — per-token balances.

func (*BalancesService) List

func (s *BalancesService) List(ctx context.Context) ([]Balance, error)

List returns all token balances. Available / Locked are human-readable decimal strings — convert with ParseAmount if you need minimal units, never with strconv.ParseFloat.

type Chain

type Chain struct {
	Key                   string       `json:"key"`
	Name                  string       `json:"name"`
	Family                ChainFamily  `json:"family"`
	ChainID               *int64       `json:"chainId"`
	NativeSymbol          string       `json:"nativeSymbol"`
	NativeDecimals        int          `json:"nativeDecimals"`
	RequiredConfirmations int          `json:"requiredConfirmations"`
	ExplorerURL           *string      `json:"explorerUrl"`
	Tokens                []ChainToken `json:"tokens"`
}

Chain is an enabled chain. ChainID is only meaningful for the EVM family — nil elsewhere.

type ChainFamily

type ChainFamily string

ChainFamily determines address format and derivation scheme.

const (
	FamilyEVM  ChainFamily = "EVM"
	FamilyTRON ChainFamily = "TRON"
	FamilyBTC  ChainFamily = "BTC"
	FamilySOL  ChainFamily = "SOL"
	FamilyTON  ChainFamily = "TON"
)

type ChainToken

type ChainToken struct {
	ID              string  `json:"id"`
	Symbol          string  `json:"symbol"`
	Name            string  `json:"name"`
	ContractAddress *string `json:"contractAddress"`
	Decimals        int     `json:"decimals"`
	MinDeposit      string  `json:"minDeposit"`
}

ChainToken is an enabled token on a chain. ContractAddress is nil for native coins; MinDeposit is a human decimal string.

type ChainsService

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

ChainsService is /v1/chains — enabled chains and their tokens.

func (*ChainsService) List

func (s *ChainsService) List(ctx context.Context) ([]Chain, error)

List returns enabled chains with their enabled tokens. ChainID is non-nil only on the EVM family.

type Client

type Client struct {
	Addresses   *AddressesService
	Balances    *BalancesService
	Chains      *ChainsService
	Deposits    *DepositsService
	Withdrawals *WithdrawalsService
	Webhooks    *WebhooksService
	// contains filtered or unexported fields
}

Client is the WeEasyCrypto tenant-API client.

cv, err := weeasycrypto.New(weeasycrypto.Options{
	BaseURL:    "https://api.example.com",
	APIKey:     os.Getenv("WEEASYCRYPTO_API_KEY"),     // keyId, e.g. "ck_…"
	PrivateKey: os.Getenv("WEEASYCRYPTO_PRIVATE_KEY"), // hex Ed25519 seed
})
addr, err := cv.Addresses.Create(ctx, weeasycrypto.CreateAddressParams{Label: "user-42", ChainKey: "tron"})

func New

func New(opts Options) (*Client, error)

New validates Options and builds a Client.

type CreateAddressParams

type CreateAddressParams struct {
	Label    string `json:"label,omitempty"`
	ChainKey string `json:"chainKey,omitempty"`
}

CreateAddressParams — both fields optional. ChainKey decides the address family (omitted ⇒ EVM).

type CreateWithdrawalBatchParams

type CreateWithdrawalBatchParams struct {
	RequestID string                `json:"requestId"`
	Items     []WithdrawalBatchItem `json:"items"`
}

CreateWithdrawalBatchParams creates 1..200 withdrawals under one batch-level idempotency key (same discipline as CreateWithdrawalParams).

type CreateWithdrawalParams

type CreateWithdrawalParams struct {
	RequestID   string `json:"requestId"`
	ChainKey    string `json:"chainKey"`
	TokenSymbol string `json:"tokenSymbol"`
	To          string `json:"to"`
	Amount      string `json:"amount"`
}

CreateWithdrawalParams — RequestID is YOUR idempotency key (max 128 chars). Persist it in your own database BEFORE calling: replaying the same RequestID after a crash can never double-spend. The SDK deliberately does not generate one for you. A 409 DUPLICATE_REQUEST response means the withdrawal already exists and is a safety signal, not a failure. Amount is a human-readable decimal STRING, e.g. "100.5" — never a float.

type Deposit

type Deposit struct {
	ID          string        `json:"id"`
	ChainKey    string        `json:"chainKey"`
	TokenSymbol string        `json:"tokenSymbol"`
	Address     string        `json:"address"`
	TxHash      string        `json:"txHash"`
	LogIndex    int           `json:"logIndex"`
	FromAddress *string       `json:"fromAddress"`
	Amount      string        `json:"amount"`
	AmountRaw   string        `json:"amountRaw"`
	BlockNumber string        `json:"blockNumber"`
	Status      DepositStatus `json:"status"`
	ConfirmedAt *string       `json:"confirmedAt"`
	CreatedAt   string        `json:"createdAt"`
}

Deposit is a detected deposit. FromAddress is nil on BTC (multi-input txs have no single payer); LogIndex is the vout on BTC. Tx hashes are chain-native (no 0x prefix on TRON/BTC). Amount is a human decimal string, AmountRaw a minimal-unit integer string, BlockNumber a decimal string (may exceed int64 on some chains — kept as string).

type DepositAddress

type DepositAddress struct {
	ID      string      `json:"id"`
	Address string      `json:"address"`
	Family  ChainFamily `json:"family"`
	// Index is the HD derivation index. Same index + same family ⇒ same address.
	Index     int     `json:"index"`
	Label     *string `json:"label"`
	CreatedAt string  `json:"createdAt"`
}

DepositAddress is a deposit address issued to your tenant. Address is rendered in the chain-native display format (EVM = EIP-55 checksum, TRON = base58, SOL = base58 case-sensitive, TON = base64url case-sensitive).

type DepositEventData

type DepositEventData struct {
	DepositID   string        `json:"depositId"`
	ChainKey    string        `json:"chainKey"`
	TxHash      string        `json:"txHash"`
	LogIndex    int           `json:"logIndex"`
	Address     string        `json:"address"`
	FromAddress *string       `json:"fromAddress"`
	TokenID     string        `json:"tokenId"`
	TokenSymbol string        `json:"tokenSymbol"`
	Amount      string        `json:"amount"`
	AmountRaw   string        `json:"amountRaw"`
	BlockNumber string        `json:"blockNumber"`
	Status      DepositStatus `json:"status"`
	Family      ChainFamily   `json:"family,omitempty"`
}

DepositEventData is the payload of deposit.detected / deposit.confirmed. Family is additive and may be empty if chain config lookup degraded.

type DepositStatus

type DepositStatus string

DepositStatus values. The server may add new statuses over time.

const (
	DepositPending   DepositStatus = "PENDING"
	DepositConfirmed DepositStatus = "CONFIRMED"
	DepositOrphaned  DepositStatus = "ORPHANED"
	DepositDust      DepositStatus = "DUST"
)

type DepositsService

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

DepositsService is /v1/deposits — deposit history.

func (*DepositsService) Iterate

Iterate auto-paginates over deposits.

func (*DepositsService) List

List returns deposits, newest first.

type Hooks

type Hooks struct {
	OnRequest  func(method, path string, attempt int)
	OnResponse func(method, path string, status int, duration time.Duration, attempt int)
	OnRetry    func(method, path string, attempt int, delay time.Duration, reason string)
}

Hooks are observability callbacks — wire them to your own logger/tracer. The SDK never logs by itself.

type InvalidAmountError

type InvalidAmountError struct{ Message string }

InvalidAmountError is returned by ParseAmount / FormatAmount on malformed input.

func (*InvalidAmountError) Error

func (e *InvalidAmountError) Error() string

type ListDepositsParams

type ListDepositsParams struct {
	PaginationParams
	Status      DepositStatus
	ChainKey    string
	TokenSymbol string
	Address     string
	TxHash      string
}

ListDepositsParams filters the deposit listing. Zero values are omitted.

type ListWithdrawalsParams

type ListWithdrawalsParams struct {
	PaginationParams
	Status   WithdrawalStatus
	ChainKey string
}

ListWithdrawalsParams filters the withdrawal listing.

type NetworkError

type NetworkError struct {
	Message string
	Cause   error
}

NetworkError means the request never produced an HTTP response (DNS failure, connection reset, timeout). For withdrawal calls this is safe to retry with the SAME requestId — the server-side idempotency key guarantees at most one withdrawal.

func (*NetworkError) Error

func (e *NetworkError) Error() string

func (*NetworkError) Unwrap

func (e *NetworkError) Unwrap() error

type Options

type Options struct {
	// BaseURL is the API origin, e.g. "https://api.example.com". Path
	// prefixes are honored.
	BaseURL string
	// APIKey is the key ID as issued (e.g. "ck_…") — a public identifier;
	// the secret part is PrivateKey.
	APIKey string
	// PrivateKey is the hex 32-byte Ed25519 seed generated in the merchant
	// portal when the key was issued. It signs every request; the platform
	// holds only the matching public key. Server-side only — never ship it
	// to a browser or mobile app.
	PrivateKey string
	// WebhookPublicKey is the tenant's webhook verification public key (hex,
	// 32 bytes) — copy it from the merchant portal (Settings → Integrations).
	// Not a secret. Required only if you use Client.Webhooks.
	WebhookPublicKey string
	// Timeout per request. Default 30s.
	Timeout time.Duration
	// MaxRetries for retryable failures. Default 3; set DisableRetries to
	// turn retries off entirely.
	MaxRetries     int
	DisableRetries bool
	// RetryBaseDelay is the base backoff delay (full jitter, exponential).
	// Default 500ms.
	RetryBaseDelay time.Duration
	// WebhookTolerance is the accepted webhook timestamp skew. Default 300s.
	WebhookTolerance time.Duration
	// HTTPClient overrides the default http.Client — proxies, test stubs.
	HTTPClient *http.Client
	Hooks      Hooks
}

Options configures a Client.

type Page

type Page[T any] struct {
	Items    []T `json:"items"`
	Total    int `json:"total"`
	Page     int `json:"page"`
	PageSize int `json:"pageSize"`
}

Page is one page of results, mirroring the server's pagination shape.

type PaginationParams

type PaginationParams struct {
	Page     int
	PageSize int
}

PaginationParams selects a page. Page is 1-based (default 1); PageSize is 1..200 (default 20). Zero values are omitted.

type SweepEventData

type SweepEventData struct {
	SweepJobID string      `json:"sweepJobId"`
	ChainKey   string      `json:"chainKey"`
	Address    string      `json:"address"`
	Token      string      `json:"token"`
	Amount     string      `json:"amount"`
	AmountRaw  string      `json:"amountRaw"`
	TxHash     string      `json:"txHash"`
	Family     ChainFamily `json:"family,omitempty"`
}

SweepEventData is the payload of sweep.completed.

type TimeoutError

type TimeoutError struct{ Message string }

TimeoutError means a client-side wait (e.g. Withdrawals.WaitUntilFinal) exceeded its time budget. The withdrawal keeps processing server-side.

func (*TimeoutError) Error

func (e *TimeoutError) Error() string

type VerifyOptions

type VerifyOptions struct {
	Tolerance time.Duration
	// Now is the current unix time in seconds — injectable for tests.
	Now int64
}

VerifyOptions overrides per call. Zero values mean the client-level defaults (tolerance 300s, wall clock).

type WaitOptions

type WaitOptions struct {
	Interval time.Duration
	Timeout  time.Duration
}

WaitOptions configures WaitUntilFinal. Zero values mean the defaults: 5s interval, 10min timeout.

type WebhookEvent

type WebhookEvent struct {
	// ID is globally unique, e.g. "deposit.confirmed:<depositId>" — use for dedup.
	ID        string          `json:"id"`
	Type      string          `json:"type"`
	CreatedAt string          `json:"createdAt"`
	Data      json.RawMessage `json:"data"`
}

WebhookEvent is a verified webhook event. Known types: deposit.detected, deposit.confirmed, withdrawal.completed, withdrawal.failed, sweep.completed. New event types may be introduced at any time — they parse fine and Data stays available as raw JSON (evolution contract: ignore what you don't know, never reject).

func (*WebhookEvent) DepositEventData

func (e *WebhookEvent) DepositEventData() (*DepositEventData, error)

DepositEventData decodes the payload of deposit.detected / deposit.confirmed.

func (*WebhookEvent) SweepEventData

func (e *WebhookEvent) SweepEventData() (*SweepEventData, error)

SweepEventData decodes the payload of sweep.completed.

func (*WebhookEvent) WithdrawalEventData

func (e *WebhookEvent) WithdrawalEventData() (*WithdrawalEventData, error)

WithdrawalEventData decodes the payload of withdrawal.completed / withdrawal.failed.

type WebhookVerificationError

type WebhookVerificationError struct{ Message string }

WebhookVerificationError is a webhook signature mismatch, malformed header, or timestamp outside tolerance.

func (*WebhookVerificationError) Error

func (e *WebhookVerificationError) Error() string

type WebhooksService

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

WebhooksService verifies and parses signed webhooks. The platform signs each delivery with a per-tenant Ed25519 key (`v1a`); verification needs only the tenant's public key — no shared secret.

// Raw body must be the exact bytes received — do not re-serialize JSON.
event, err := cv.Webhooks.Parse(rawBody, r.Header.Get("X-Webhook-Signature"))

func (*WebhooksService) Parse

func (s *WebhooksService) Parse(rawBody []byte, signatureHeader string, opts ...VerifyOptions) (*WebhookEvent, error)

Parse verifies then decodes the event. Unknown event types do NOT error — they surface with Type as-is and Data as raw JSON, so new platform events never break your endpoint.

func (*WebhooksService) Verify

func (s *WebhooksService) Verify(rawBody []byte, signatureHeader string, opts ...VerifyOptions) error

Verify checks the `X-Webhook-Signature: t={ts},v1a={hex}` header against the raw body with the tenant's Ed25519 public key. Returns *WebhookVerificationError on any mismatch.

type Withdrawal

type Withdrawal struct {
	ID          string           `json:"id"`
	RequestID   string           `json:"requestId"`
	BatchID     *string          `json:"batchId"`
	ChainKey    string           `json:"chainKey"`
	TokenSymbol string           `json:"tokenSymbol"`
	To          string           `json:"to"`
	Amount      string           `json:"amount"`
	AmountRaw   string           `json:"amountRaw"`
	Status      WithdrawalStatus `json:"status"`
	TxHash      *string          `json:"txHash"`
	FailReason  *string          `json:"failReason"`
	ConfirmedAt *string          `json:"confirmedAt"`
	CreatedAt   string           `json:"createdAt"`
}

Withdrawal — TxHash is non-nil only once the transaction has been broadcast; ConfirmedAt only once confirmed.

type WithdrawalBatch

type WithdrawalBatch struct {
	BatchID     string       `json:"batchId"`
	RequestID   string       `json:"requestId"`
	CreatedAt   string       `json:"createdAt"`
	Withdrawals []Withdrawal `json:"withdrawals"`
}

WithdrawalBatch is the result of a batch creation.

type WithdrawalBatchItem

type WithdrawalBatchItem struct {
	ChainKey    string `json:"chainKey"`
	TokenSymbol string `json:"tokenSymbol"`
	To          string `json:"to"`
	Amount      string `json:"amount"`
}

WithdrawalBatchItem is one entry of CreateWithdrawalBatchParams.

type WithdrawalEventData

type WithdrawalEventData struct {
	ID          string      `json:"id"`
	RequestID   string      `json:"requestId"`
	ChainKey    string      `json:"chainKey"`
	TokenSymbol string      `json:"tokenSymbol"`
	To          string      `json:"to"`
	Amount      string      `json:"amount"`
	AmountRaw   string      `json:"amountRaw"`
	TxHash      *string     `json:"txHash"`
	FailReason  *string     `json:"failReason"`
	Family      ChainFamily `json:"family,omitempty"`
}

WithdrawalEventData is the payload of withdrawal.completed / withdrawal.failed.

type WithdrawalStatus

type WithdrawalStatus string

WithdrawalStatus values. Terminal: CONFIRMED, FAILED, REJECTED, CANCELED.

const (
	WithdrawalPendingApproval WithdrawalStatus = "PENDING_APPROVAL"
	WithdrawalApproved        WithdrawalStatus = "APPROVED"
	WithdrawalQueued          WithdrawalStatus = "QUEUED"
	WithdrawalBroadcast       WithdrawalStatus = "BROADCAST"
	WithdrawalConfirmed       WithdrawalStatus = "CONFIRMED"
	WithdrawalRejected        WithdrawalStatus = "REJECTED"
	WithdrawalCanceled        WithdrawalStatus = "CANCELED"
	WithdrawalFailed          WithdrawalStatus = "FAILED"
)

func (WithdrawalStatus) IsFinal

func (s WithdrawalStatus) IsFinal() bool

IsFinal reports whether the status is terminal.

type WithdrawalsService

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

WithdrawalsService is /v1/withdrawals + /v1/withdrawal-batches — the money path.

func (*WithdrawalsService) Create

Create creates a withdrawal. PERSIST params.RequestID IN YOUR OWN DATABASE BEFORE CALLING — it is the idempotency key that makes crash-replay safe. Network errors on this call are auto-retried with the same RequestID (can never double-spend); a 409 with IsDuplicateRequest() == true means an earlier attempt already succeeded.

func (*WithdrawalsService) CreateBatch

CreateBatch creates up to 200 withdrawals under one batch-level RequestID (same idempotency discipline as Create).

func (*WithdrawalsService) Get

Get fetches one withdrawal by its server-side id.

func (*WithdrawalsService) Iterate

Iterate auto-paginates over withdrawals.

func (*WithdrawalsService) List

List returns withdrawals, newest first. Filters: Status, ChainKey.

func (*WithdrawalsService) WaitUntilFinal

func (s *WithdrawalsService) WaitUntilFinal(ctx context.Context, id string, opts WaitOptions) (*Withdrawal, error)

WaitUntilFinal polls Get(id) until the withdrawal reaches a terminal status (CONFIRMED | FAILED | REJECTED | CANCELED). Pure client-side polling — webhooks (withdrawal.completed / withdrawal.failed) are the push-based alternative. Returns *TimeoutError if the budget is exceeded; the withdrawal keeps processing server-side.

Jump to

Keyboard shortcuts

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