naulix

package module
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: May 15, 2026 License: Apache-2.0 Imports: 15 Imported by: 0

README

naulix-go

Official NAULIX SDK for Go. Same resources, retry policy, and webhook helper as the Python and Node SDKs.

NAULIX is an XRPL-native staged-escrow trade settlement platform. Voyages, generic escrows, P2P RLUSD, webhook endpoints — all surfaced here.

Install

go get github.com/DSR-WET/naulix-go

Requires Go 1.21 or later. No third-party dependencies.

Quick start

package main

import (
    "context"
    "fmt"
    "log"
    "os"

    naulix "github.com/DSR-WET/naulix-go"
)

func main() {
    c, err := naulix.NewClient(naulix.ClientOptions{
        APIKey: os.Getenv("NAULIX_API_KEY"),
    })
    if err != nil { log.Fatal(err) }

    voyage, err := c.Voyages.Create(context.Background(), naulix.VoyageCreateParams{
        OriginPortLOCODE:      "IEDUB",
        DestinationPortLOCODE: "DEHAM",
        MMSI:                  "636019825",
        AmountRLUSD:           10_000,
        SellerXRPLAddress:     "rPT1Sjq2YGrBMTttX4GZHjKu9dyfzbpAYe",
        BuyerXRPLAddress:      "rUgw8e2x8wMFeB8N3W2mJj6935wB5wimsm",
    })
    if err != nil { log.Fatal(err) }

    fmt.Println(voyage["frid"], voyage["status"])
}

The key prefix decides which environment you target:

Prefix Environment
sk_test_* sandbox
sk_live_* production

Resources

Field Purpose
client.Voyages Create + track AIS-tracked voyages with four staged escrows.
client.Escrows Generic XRPL escrow primitive (vesting, marketplace, web3 svc).
client.Payments Generic P2P RLUSD send (remittance).
client.APIKeys Create / rotate / revoke API keys.
client.WebhookEndpoints Create webhook destinations + manage delivery.

Errors

Every API failure returns *naulix.Error. Branch on Err.Code, never on Err.Message:

import "errors"

_, err := c.Voyages.Create(ctx, params)
var apiErr *naulix.Error
if errors.As(err, &apiErr) {
    switch apiErr.Code {
    case "voyage_invalid_port_locode":
        // surface field-specific UI error
    case "rate_limited":
        // back off
    default:
        return err
    }
}

Webhooks

The signature helper is standalone — use it whether or not you also use the Client for outbound calls.

import (
    "io"
    "net/http"
    naulix "github.com/DSR-WET/naulix-go"
)

func handleWebhook(w http.ResponseWriter, r *http.Request) {
    raw, _ := io.ReadAll(r.Body)
    sig := r.Header.Get("Naulix-Signature")
    if !naulix.VerifyWebhookSignature(secret, sig, string(raw), naulix.WebhookOptions{}) {
        w.WriteHeader(http.StatusUnauthorized)
        return
    }
    // raw is the canonical bytes — parse JSON here.
}

Verification uses HMAC-SHA-256 with hmac.Equal (constant-time). The helper rejects timestamps older than 5 minutes by default — pass WebhookOptions{ToleranceSec: N} to widen.

Retry + idempotency

Every write call ships with a fresh Idempotency-Key header (UUID v4 generated with crypto/rand). Override per-call via the IdempotencyKey field of the resource's *Params struct if you have your own customer-driven identity.

The transport retries on 5xx and network errors with a fixed exponential schedule (500ms → 1.5s → 4s). 4xx responses are permanent — they return the structured *naulix.Error immediately without retrying.

License

Apache-2.0

Documentation

Overview

SDK-side error type.

Mirrors the NAULIX API error envelope:

{
  "detail": "...",
  "error": {
    "code":    "voyage_invalid_port_locode",
    "message": "...",
    "type":    "invalid_request_error",
    "param":   "origin_port_locode",
    "doc_url": "https://docs.naulix.io/errors/voyage_invalid_port_locode",
    "context": {...}
  }
}

Consumers branch on Err.Code — never on Err.Message, which is human text and can change at any time without an API version bump.

Internal HTTP transport — auth, idempotency-key, retry, error mapping.

Single source of truth for "how the SDK talks to the API". The resource sub-clients compose against this — they don't know about net/http or retry semantics.

Package naulix is the official Go SDK for the NAULIX API — an XRPL-native staged-escrow trade settlement platform.

Quick start:

c, err := naulix.NewClient(naulix.ClientOptions{APIKey: "sk_test_..."})
if err != nil { ... }
voyage, err := c.Voyages.Create(ctx, naulix.VoyageCreateParams{
    OriginPortLOCODE:      "IEDUB",
    DestinationPortLOCODE: "DEHAM",
    MMSI:                  "636019825",
    AmountRLUSD:           10_000,
    SellerXRPLAddress:     "rPT1Sjq2YGrBMTttX4GZHjKu9dyfzbpAYe",
    BuyerXRPLAddress:      "rUgw8e2x8wMFeB8N3W2mJj6935wB5wimsm",
})

Environments: the key prefix decides — sk_test_* → sandbox, sk_live_* → production. No separate base URL needed.

Errors: every API failure returns *naulix.Error. Branch on Err.Code (stable) rather than Err.Message (human text).

Index

Constants

View Source
const Version = "0.1.0"

Version of this SDK. Sent as part of the User-Agent.

Variables

This section is empty.

Functions

func VerifyWebhookSignature

func VerifyWebhookSignature(secret, signatureHeader, body string, opts WebhookOptions) bool

VerifyWebhookSignature verifies a NAULIX webhook signature.

Use this in your webhook handler regardless of whether you also use the Client for outbound API calls — it's standalone.

func handle(w http.ResponseWriter, r *http.Request) {
    raw, _ := io.ReadAll(r.Body)
    sig := r.Header.Get("Naulix-Signature")
    if !naulix.VerifyWebhookSignature(secret, sig, string(raw), naulix.WebhookOptions{}) {
        w.WriteHeader(http.StatusUnauthorized)
        return
    }
    ...
}

Verification uses HMAC-SHA-256 with a constant-time compare. Rejects timestamps more than ToleranceSec away from now (default 300).

Types

type APIKeyCreateParams

type APIKeyCreateParams struct {
	Name         string
	Mode         string // "test" (default) | "live"
	Tier         string // "starter" (default)
	Organisation string // optional
	ContactEmail string // optional
}

APIKeyCreateParams is the POST /v1/api-keys body.

type APIKeys

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

APIKeys manages NAULIX-issued sk_test_* / sk_live_* keys.

func (*APIKeys) Create

func (a *APIKeys) Create(ctx context.Context, p APIKeyCreateParams) (map[string]any, error)

Create mints a new API key. The returned object includes the raw key string ONCE — store it immediately; subsequent calls only return the fingerprint.

func (*APIKeys) List

func (a *APIKeys) List(ctx context.Context) ([]map[string]any, error)

List returns the calling tenant's keys.

func (*APIKeys) Revoke

func (a *APIKeys) Revoke(ctx context.Context, keyID int64) (map[string]any, error)

Revoke disables the key permanently.

func (*APIKeys) Rotate

func (a *APIKeys) Rotate(ctx context.Context, keyID int64) (map[string]any, error)

Rotate invalidates the current secret and issues a new one. The previous secret stops working immediately.

type Client

type Client struct {
	Voyages          *Voyages
	APIKeys          *APIKeys
	Payments         *Payments
	Escrows          *Escrows
	WebhookEndpoints *WebhookEndpoints
	// contains filtered or unexported fields
}

Client is the entry point. Construct with NewClient and then access resources via the exported sub-client fields.

func NewClient

func NewClient(opts ClientOptions) (*Client, error)

NewClient builds a Client with the supplied options.

func (*Client) Mode

func (c *Client) Mode() string

Mode returns "test" for sk_test_* keys, "live" for sk_live_*.

type ClientOptions

type ClientOptions struct {
	// APIKey is the secret key (sk_test_* or sk_live_*). Required.
	APIKey string

	// BaseURL overrides the default https://api.naulix.io. Useful for
	// local development against a self-hosted NAULIX.
	BaseURL string

	// Timeout caps the per-request total duration. Default 30s.
	Timeout time.Duration

	// MaxRetries caps the retry budget. 0 = full schedule (3 retries
	// on 5xx + network errors). Negative is treated as 0.
	MaxRetries int

	// HTTPClient lets callers inject their own http.Client — e.g. with
	// a custom RoundTripper for telemetry. If nil, the SDK builds one
	// with the configured Timeout.
	HTTPClient *http.Client
}

ClientOptions controls how the client talks to the NAULIX API.

type Error

type Error struct {
	// Code is the stable machine-readable code (see docs/error-codes.md).
	Code string
	// Type is the broad category — "invalid_request_error",
	// "authentication_error", "compliance_error", etc.
	Type string
	// Message is the human-readable description.
	Message string
	// StatusCode is the HTTP status the API returned.
	StatusCode int
	// Param is the request field that caused the error, if applicable.
	Param string
	// DocURL links to the remediation page for this code.
	DocURL string
	// Context is optional structured extra context.
	Context map[string]any
	// Raw is the full parsed response body.
	Raw map[string]any
}

Error is the typed error returned by every API call that fails.

func (*Error) Error

func (e *Error) Error() string

type EscrowCreateParams

type EscrowCreateParams struct {
	Amount             float64
	SenderAddress      string
	ReceiverAddress    string
	Currency           string // "" → RLUSD
	FinishAfter        string // ISO-8601 UTC, e.g. "2026-12-01T00:00:00Z"
	CancelAfter        string // ISO-8601 UTC
	UseCryptoCondition bool
	Description        string
	Metadata           map[string]any
	IdempotencyKey     string
}

EscrowCreateParams maps to POST /v1/escrows.

type EscrowListOptions

type EscrowListOptions struct {
	Status string
	Limit  int // 0 → 50
}

EscrowListOptions controls GET /v1/escrows.

type Escrows

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

Escrows is the generic XRPL escrow primitive — vesting, marketplace, web3-service-escrow. Three release shapes:

  • Time-locked: set FinishAfter; release after that timestamp.
  • Crypto-condition: set UseCryptoCondition; fulfillment returned ONCE.
  • Both: AND semantics — XRPL native.

func (*Escrows) Cancel

func (e *Escrows) Cancel(ctx context.Context, escrowID int64) (map[string]any, error)

Cancel releases the funds back to the sender (after CancelAfter has elapsed, on chain).

func (*Escrows) Create

func (e *Escrows) Create(ctx context.Context, p EscrowCreateParams) (map[string]any, error)

Create mints a new escrow.

func (*Escrows) Finish

func (e *Escrows) Finish(ctx context.Context, escrowID int64, fulfillmentHex string) (map[string]any, error)

Finish releases the escrow. For crypto-condition escrows pass fulfillmentHex; for time-locked-only escrows pass an empty string.

func (*Escrows) List

func (e *Escrows) List(ctx context.Context, opts EscrowListOptions) ([]map[string]any, error)

List returns the calling tenant's escrows.

func (*Escrows) Retrieve

func (e *Escrows) Retrieve(ctx context.Context, escrowID int64) (map[string]any, error)

Retrieve returns a single escrow.

func (*Escrows) RevealFulfillment

func (e *Escrows) RevealFulfillment(ctx context.Context, escrowID int64) (map[string]any, error)

RevealFulfillment returns the preimage hex for a crypto-condition escrow. NAULIX hands this out ONCE — store it.

type PaymentSendParams

type PaymentSendParams struct {
	ToAddress      string
	RLUSDAmount    float64
	Memo           string // optional, written as the XRPL transaction memo
	Reference      string // optional internal/customer reference
	IdempotencyKey string // optional client-supplied idempotency key
}

PaymentSendParams maps to POST /v1/payments/send.

type Payments

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

Payments is the generic P2P send primitive — closes the remittance use case without going through the voyage / staged-escrow surface.

resp, err := c.Payments.Send(ctx, naulix.PaymentSendParams{
    ToAddress:   "rABC...",
    RLUSDAmount: 100,
    Memo:        "invoice-42",
})

func (*Payments) Send

func (p *Payments) Send(ctx context.Context, params PaymentSendParams) (map[string]any, error)

Send dispatches an RLUSD payment.

type VoyageCreateParams

type VoyageCreateParams struct {
	OriginPortLOCODE      string
	DestinationPortLOCODE string
	MMSI                  string
	AmountRLUSD           float64
	SellerXRPLAddress     string
	BuyerXRPLAddress      string
	Currency              string  // "" → RLUSD
	WaypointRadiusNM      float64 // 0 → 5.0 nautical miles
	IMO                   string  // optional
	VesselName            string  // optional
	Notes                 string  // optional
	IdempotencyKey        string  // optional client-supplied
}

VoyageCreateParams maps to the POST /v1/voyages request body. Fields follow Go naming (CamelCase) and the SDK translates to the API's snake_case on the wire.

type Voyages

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

Voyages is the resource client for the AIS-tracked staged-escrow voyages pilot.

func (*Voyages) Create

func (v *Voyages) Create(ctx context.Context, p VoyageCreateParams) (map[string]any, error)

Create kicks off a voyage. Returns the partial voyage with status `escrow_minting`; poll Retrieve until status flips to `escrow_locked`.

func (*Voyages) Events

func (v *Voyages) Events(ctx context.Context, voyageID int64) ([]map[string]any, error)

Events returns the full append-only audit log for a voyage.

func (*Voyages) List

func (v *Voyages) List(ctx context.Context) ([]map[string]any, error)

List returns the calling user's voyages, newest first.

func (*Voyages) Retrieve

func (v *Voyages) Retrieve(ctx context.Context, voyageID int64) (map[string]any, error)

Retrieve returns a single voyage with its stage details + latest AIS position.

type WebhookEndpointCreateParams

type WebhookEndpointCreateParams struct {
	URL            string
	Events         []string
	Description    string
	IdempotencyKey string
}

WebhookEndpointCreateParams maps to POST /v1/webhook-endpoints.

type WebhookEndpoints

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

WebhookEndpoints manages outbound webhook destinations + their delivery history.

func (*WebhookEndpoints) Create

Create registers a new endpoint. The response includes the signing secret (whsec_*) ONCE — store it immediately; subsequent reads only return the fingerprint.

func (*WebhookEndpoints) Deliveries

func (w *WebhookEndpoints) Deliveries(ctx context.Context, endpointID int64, limit int) ([]map[string]any, error)

Deliveries returns the delivery history (success + failure) for an endpoint. Default limit 50; pass non-zero to override.

func (*WebhookEndpoints) Disable

func (w *WebhookEndpoints) Disable(ctx context.Context, endpointID int64) (map[string]any, error)

Disable turns off delivery to this endpoint. The row is kept for audit; future events stop firing.

func (*WebhookEndpoints) List

func (w *WebhookEndpoints) List(ctx context.Context) ([]map[string]any, error)

List returns the calling tenant's endpoints.

func (*WebhookEndpoints) Retrieve

func (w *WebhookEndpoints) Retrieve(ctx context.Context, endpointID int64) (map[string]any, error)

Retrieve returns a single endpoint.

func (*WebhookEndpoints) RotateSecret

func (w *WebhookEndpoints) RotateSecret(ctx context.Context, endpointID int64) (map[string]any, error)

RotateSecret invalidates the current whsec_* and issues a new one.

func (*WebhookEndpoints) Test

func (w *WebhookEndpoints) Test(ctx context.Context, endpointID int64) (map[string]any, error)

Test fires a synthetic event at the endpoint so the caller can verify their handler.

type WebhookOptions

type WebhookOptions struct {
	// ToleranceSec is the maximum allowed clock skew vs the signature
	// timestamp. 0 → 300 (5 minutes). Wider values weaken replay
	// protection — only loosen if your infra has known clock drift.
	ToleranceSec int64

	// NowUnix overrides time.Now().Unix() — used by tests.
	NowUnix int64
}

WebhookOptions tunes VerifyWebhookSignature. The zero value works.

Jump to

Keyboard shortcuts

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