A Go SDK for the Derive exchange (formerly Lyra) — a layer-2 derivatives venue with perps, options, and spot.
Covers REST (public + private), WebSocket (public + private + subscriptions), and EIP-712 order signing with session keys.
Out of scope: on-chain operations (deposit, withdraw, session-key
registration). Those require an EVM toolchain (e.g.
go-ethereum) and aren't
bundled here — this SDK is the JSON-RPC trading surface only. Once
funds are deposited via the Derive UI or your own contract calls,
every order / RFQ / quote / cancel flow runs through this SDK.
v0.x — pre-1.0; the public API may still change. Track the current
version via the Release
badge above. Breaking changes between 0.x versions follow Conventional
Commits' feat!: discipline and are listed under "BREAKING CHANGES"
in CHANGELOG.md. For migration prose with
before/after snippets, see MIGRATING.md.
This project follows Semantic Versioning. Releases are computed from Conventional Commits by release-please; the type→bump mapping lives in docs/release-process.md.
go get github.com/amiwrpremium/go-deriveRequires Go 1.25+.
Built and CI-tested against Go 1.25 and Go 1.26 on Linux, macOS and Windows. Tracks the Derive API as documented at docs.derive.xyz — see CHANGELOG.md for the API drift addressed in each release.
package main
import (
"context"
"fmt"
"log"
"os"
"github.com/amiwrpremium/go-derive/pkg/auth"
"github.com/amiwrpremium/go-derive/pkg/derive"
"github.com/amiwrpremium/go-derive/pkg/enums"
"github.com/amiwrpremium/go-derive/pkg/types"
)
func main() {
// NewLocalSigner takes a raw hex private key. For production setups,
// see pkg/auth.NewSessionKeySigner — registers a hot session key
// delegating from a long-lived owner address.
signer, err := auth.NewLocalSigner(os.Getenv("DERIVE_PRIVATE_KEY"))
if err != nil {
log.Fatal(err)
}
c, err := derive.NewClient(
derive.WithTestnet(), // start on testnet; switch to derive.WithMainnet() once integration is verified
derive.WithSigner(signer),
derive.WithSubaccount(123),
)
if err != nil {
log.Fatal(err)
}
defer c.Close()
ctx := context.Background()
instruments, err := c.REST.GetInstruments(ctx, types.InstrumentsQuery{
Currency: "BTC",
Kind: enums.InstrumentTypePerp,
})
if err != nil {
log.Fatal(err)
}
fmt.Println(len(instruments), "BTC perps")
}See examples/ for more — and
docs/getting-started.md for a step-by-step walkthrough.
pkg/derive top-level facade (REST + WS)
pkg/rest HTTP-backed JSON-RPC client
pkg/ws WebSocket-backed JSON-RPC + typed subscriptions
pkg/auth EIP-712 signing, session keys
pkg/types, pkg/enums domain types, named-string enums
pkg/errors sentinel errors + APIError
internal/jsonrpc JSON-RPC 2.0 framing
internal/transport HTTP + WS transports (shared interface)
internal/methods RPC method definitions (shared by REST + WS)
internal/netconf endpoints + EIP-712 domains per network
internal/codec decimal/u256/address encoding
internal/retry exponential backoff
The Derive API is JSON-RPC 2.0 over both HTTP and WebSocket — same method names, same params. The SDK reflects that: a single Transport interface backs both pkg/rest and pkg/ws, so each method is defined once.
pkg/derive— start here. The top-level facade bundles a REST client and a WS client sharing one signer and subaccount, which is what most callers want.pkg/restalone — when you only need HTTP RPCs (e.g. periodic history pulls from a non-trading process).pkg/wsalone — when you only need streaming (e.g. a feed recorder that doesn't place orders).
Both pkg/rest and pkg/ws expose the full RPC method surface
independently; the facade is a shortcut, not a feature gate.
See docs/architecture.md for the full design.
The full doc set lives under docs/:
| Topic | |
|---|---|
| Concepts | getting-started · architecture · transports · auth · subscriptions · numerics · error handling · rate limiting · reconnection |
| Process | examples · testing · ci · release process · known tool issues |
| Security | security index · repo policy · threat model |
Every push and pull request runs:
| Check | Tool | Workflow |
|---|---|---|
| Format | gofmt -l |
ci.yml |
| Vet | go vet |
ci.yml |
| Build | go build on Linux/macOS/Windows × Go 1.25/1.26 |
ci.yml |
| Tests | go test -race -coverprofile |
ci.yml |
| Mod tidy | go mod tidy diff check |
ci.yml |
| Vulnerabilities | govulncheck |
ci.yml |
| Linters | golangci-lint, staticcheck |
lint.yml |
| Extra linters | markdownlint, yamllint, actionlint, editorconfig-checker, typos | extra-lint.yml |
| Security (SAST) | CodeQL, gosec, Semgrep (security-audit + golang + secrets), Codacy | codeql.yml, gosec.yml, semgrep.yml, codacy.yml |
| Filesystem / IaC scan | Trivy (filesystem + secret + config) | trivy.yml |
| Secret scanning | Gitleaks (git history) + TruffleHog (entropy, verified-only) | gitleaks.yml, trufflehog.yml |
| Dependency review | PR-time license + vulnerability gate | dependency-review.yml |
| License compliance | go-licenses allow-list (Apache-2.0, BSD, ISC, MIT, MPL-2.0, Unlicense) |
license-check.yml |
| Action SHA pinning | enforces every uses: is a 40-char SHA |
pin-check.yml |
| Coverage | Codecov + Codacy upload | ci.yml |
| Releases | release-please (Conventional Commits → CHANGELOG + tag) | release-please.yml |
| Dependencies | Renovate (primary), Dependabot (fallback) | renovate.json, dependabot.yml |
| Integration | live testnet smoke tests, manual dispatch only | integration.yml |
| OpenSSF Scorecard | weekly + on push, publishes public score | scorecard.yml |
| OSV-Scanner | weekly + on push/PR, transitive dep CVE scan | osv-scanner.yml |
| SLSA + SBOM | runs on every published release | release.yml |
| Post-release re-verify | cosign + slsa-verifier, weekly + on release | verify-release.yml |
All workflows additionally run step-security/harden-runner in audit
mode for egress monitoring.
| Secret | Used by | Required? |
|---|---|---|
CODECOV_TOKEN |
Codecov upload in ci.yml |
Yes for private repos; public repos can omit |
CODACY_PROJECT_TOKEN |
Codacy coverage upload in ci.yml |
Optional — coverage upload silently skipped if missing |
RELEASE_PLEASE_TOKEN |
release-please uses this PAT to publish releases that auto-trigger release.yml |
Recommended — if missing, falls back to GITHUB_TOKEN, but releases won't auto-fire release.yml (artefacts need manual gh workflow run release.yml -f tag=vX.Y.Z) |
GITHUB_TOKEN is provided by Actions automatically. RELEASE_PLEASE_TOKEN
should be a fine-grained PAT scoped to this repo with Contents: write
and Pull requests: write permissions — needed because GitHub's
anti-loop protection doesn't fire release.yml on releases published by
GITHUB_TOKEN.
This project follows the OpenSSF best practices and publishes a public Scorecard at scorecard.dev.
| What | Where |
|---|---|
| Vulnerability disclosure | SECURITY.md — uses GitHub private advisories |
| Code of conduct | CODE_OF_CONDUCT.md (Contributor Covenant 2.1) |
| Security metadata | SECURITY-INSIGHTS.yml (OpenSSF spec 1.0.0) |
| Required repo settings | docs/security/repo-policy.md |
| Static analysis (SAST) | CodeQL, gosec, Semgrep, staticcheck, Codacy |
| Filesystem / IaC scanning | Trivy (filesystem + secret + config modes) |
| Secret scanning | Gitleaks (history) + TruffleHog (verified-only) |
| Dependency scanning | govulncheck, OSV-Scanner, Trivy filesystem, dependency-review |
| Dependency updates | Renovate (primary) + Dependabot (fallback) |
| License compliance | go-licenses allow-list enforced in CI |
| Egress audit | step-security/harden-runner on every workflow (audit mode) |
| Action pinning enforcement | pin-check workflow rejects unpinned uses: lines |
| Release integrity | SLSA Level 3 provenance + CycloneDX & SPDX SBOMs + license inventory, all cosign-signed — release.yml |
| Post-release verification | cosign signatures + SLSA provenance re-checked weekly + on every release — verify-release.yml |
| Fuzzing | Go-native Fuzz* tests in pkg/types, pkg/auth, pkg/errors, internal/jsonrpc |
| Pinned actions | every action pinned by SHA with the version as a comment |
To report a vulnerability or code-of-conduct violation, use GitHub's private vulnerability reporting. The same channel handles both so reports go through one triage pipeline.
Live-network tests live under test/ and are gated by the
integration build tag, so the default go test ./... is unaffected.
# Public-only subset (no creds needed) against testnet.
make test-integration
# All tests except live order placement.
DERIVE_SESSION_KEY=0x... DERIVE_SUBACCOUNT=123 \
go test -tags=integration -count=1 ./test/...
# Add live order placement (testnet only — never against mainnet).
DERIVE_RUN_LIVE_ORDERS=1 DERIVE_BASE_ASSET=0x... \
DERIVE_SESSION_KEY=0x... DERIVE_SUBACCOUNT=123 \
go test -tags=integration -count=1 -run='^TestPrivate_PlaceAndCancel' ./test/...See test/README.md for the full env-var list and what each subset covers.
| File | Purpose |
|---|---|
| CONTRIBUTING.md | how to submit changes; Conventional Commits |
| CODE_OF_CONDUCT.md | Contributor Covenant 2.1 |
| SECURITY.md | vulnerability disclosure |
| SUPPORT.md | where to ask which kind of question |
| GOVERNANCE.md | how decisions get made |
| MAINTAINERS.md | who reviews and merges |
| CHANGELOG.md | every release, generated by release-please |
| MIGRATING.md | hand-written before/after for every 0.x breaking change |
| AUTHORS | contributors in chronological order |
| SECURITY-INSIGHTS.yml | OpenSSF security metadata |
| .github/settings.yml | declarative repo settings + label palette (Probot Settings) |
| .github/rulesets/ | branch + tag rulesets, importable via gh api |
| Configs | Makefile · lefthook.yml · renovate.json · .codacy.yml · .markdownlint.json · .remarkrc.yml · .typos.toml · .editorconfig |
Commits must follow Conventional Commits so release-please can derive the next version and update CHANGELOG.md. See CONTRIBUTING.md.
MIT.
This SDK exists thanks to:
- Derive (formerly Lyra) — the public REST + WebSocket reference underpins every method and sentinel in this module.
- Upstream Go libraries the SDK builds on:
go-ethereumfor crypto and EIP-712 hashing,gorilla/websocketfor the WS transport,shopspring/decimalfor fixed-point arithmetic,stretchr/testifyfor the test helpers. - OpenSSF — the Scorecard, SLSA, Security Insights, and best-practices projects shaped most of the security plumbing in this repo.
- Tools and standards — Sigstore for keyless artefact signing, SPDX and CycloneDX for SBOM formats, OWASP for the Semgrep security-audit rule pack, Mozilla for the CoC enforcement-ladder reference.
Use testnet first. Always validate any integration against the
Derive testnet (derive.WithTestnet()) before pointing at mainnet. Test
orders place real testnet positions but use no real funds; mainnet does
the opposite.
This software is provided "as is", without warranty of any kind, express or implied, including but not limited to the warranties of merchantability, fitness for a particular purpose, and non-infringement (see LICENSE for the full terms).
This is an independent, unofficial project. It is not affiliated with, endorsed by, or sponsored by Derive, Lyra Finance, the Lyra DAO, the Ethereum Foundation, or any other organisation or person. All product names, logos, and brands referenced are the property of their respective owners; their use here is for identification purposes only.
Trading derivatives carries financial risk. Nothing in this repository is financial advice. You are solely responsible for any orders submitted, keys generated or stored, and integrations built on top of this code. Use at your own risk.