مواد پر جائیں
AtheronDEVELOPERS
← SDKs and libraries

Go SDK

Install and use github.com/Atheron-ATON-Network/atheron-sdk-go.

مثالوں میں اپنی ٹیسٹ کلائنٹ آئی ڈی دیکھنے کے لیے سائن اِن کریں۔

Coming soon. github.com/Atheron-ATON-Network/atheron-sdk-go is not published on Go modules yet, so the install line on this page does not work until it is. Until then, everything works over plain HTTP: pick cURL in any code block, or start from Endpoints.

atheron-sdk-go is Sign in with Atheron for Go: PKCE, the authorize address, the code swap, userinfo, webhook signatures, the events stream and the developer API client, on the standard library alone. Gin and Echo integrations are modules of their own, so the core pulls in nothing. It ships on 30 October 2026.

Install

Go 1.22 and later (Echo needs 1.23).

bash
go get github.com/Atheron-ATON-Network/atheron-sdk-go       # the core, with net/http
go get github.com/Atheron-ATON-Network/atheron-sdk-go/gin   # or /echo

Sign somebody in

Build the address on your server and keep started.Kept() (the verifier, state and nonce) in their session. In a web app, the net/http, Gin or Echo integration does this for you.

# The authorize request is a page the person opens, not an API call. Build the address on your
# server: a fresh PKCE pair, state and nonce for this browser, then redirect them to it.
VERIFIER=$(openssl rand -base64 32 | tr '+/' '-_' | tr -d '=\n')
CHALLENGE=$(printf '%s' "$VERIFIER" | openssl dgst -sha256 -binary | openssl base64 | tr '+/' '-_' | tr -d '=\n')
STATE=$(openssl rand -hex 16)
echo "https://accounts.aton-network.org/oauth/authorize?response_type=code&client_id=$ATHERON_CLIENT_ID&redirect_uri=https%3A%2F%2Fapp.example.com%2Fcallback&scope=openid%20profile%20email&state=$STATE&code_challenge=$CHALLENGE&code_challenge_method=S256"
مثالی جواب302
(no body: the browser follows the redirect)

Handle the callback

FinishSignIn checks state in constant time, then swaps the code. Send the secret from a server app; leave it out in a public app.

# Swap the code from the redirect for tokens, on your server. HTTP Basic carries your client ID and
# secret; the verifier proves this is the browser that started the sign-in.
curl https://accounts.aton-network.org/oauth/token \
  -u "$ATHERON_CLIENT_ID:$ATHERON_CLIENT_SECRET" \
  -d grant_type=authorization_code \
  -d code="$CODE" \
  -d redirect_uri=https://app.example.com/callback \
  -d code_verifier="$VERIFIER"
مثالی جواب200
{
  "access_token": "eyJhbGciOiJFUzI1NiIsInR5cCI6ImF0K2p3dCJ9...",
  "token_type": "Bearer",
  "expires_in": 900,
  "scope": "openid profile email offline_access",
  "id_token": "eyJhbGciOiJFUzI1NiIsImtpZCI6IjIwMjYtMTAtMDEiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL2FjY291bnRzLmF0b24tbmV0d29yay5vcmciLCJzdWIiOiI5YTZk...",
  "refresh_token": "ath_rt_6Qm9..."
}

Read who it is now

# Who the person is as of now, with an access token issued to your client.
curl https://accounts.aton-network.org/oauth/userinfo \
  -H "Authorization: Bearer $ACCESS_TOKEN"
مثالی جواب200
{
  "sub": "9a6d4c1e-1f0b-4a51-8a8e-3b2f6c0d7e11",
  "name": "Ada Lovelace",
  "email": "ada@example.com",
  "email_verified": true,
  "age": { "verified": true, "adult": true, "sixteen_or_over": true }
}

Keep them signed in

# A new access token and a new refresh token for the newest refresh token you hold. The old one stops working.
curl https://accounts.aton-network.org/oauth/token \
  -u "$ATHERON_CLIENT_ID:$ATHERON_CLIENT_SECRET" \
  -d grant_type=refresh_token \
  -d refresh_token="$REFRESH_TOKEN"
مثالی جواب200
{
  "access_token": "eyJhbGciOiJFUzI1NiIsInR5cCI6ImF0K2p3dCJ9...",
  "token_type": "Bearer",
  "expires_in": 900,
  "scope": "openid profile email offline_access",
  "refresh_token": "ath_rt_k2Lp..."
}

Check a webhook

atheron.WebhookHandler reads the raw body (up to 1 MiB), checks the signature against every secret you hold (two while you rotate), and answers 400 for a forgery, 500 when your function fails (so we deliver it again) and 204 otherwise.

یہ مثال ابھی ⁨cURL⁩ میں نہیں لکھی گئی۔ ⁨TypeScript⁩ میں دکھائی گئی ہے۔

// Check that a webhook came from Atheron before you act on it. Pass the raw body, exactly as received.
import { verifyWebhook, type WebhookEvent } from "@aton-network/sdk";

export async function handleWebhook(request: Request): Promise<Response> {
  const raw = await request.text();
  const ok = await verifyWebhook(request.headers.get("atheron-signature"), raw, process.env.ATHERON_WEBHOOK_SECRET!);
  if (!ok) return new Response("bad signature", { status: 400 });
  const event = JSON.parse(raw) as WebhookEvent;
  if (event.type === "consent.revoked") {
    // Delete the refresh token you hold for event.data.sub, and stop using what you read.
  }
  return new Response(null, { status: 204 });
}

Follow the events stream

FollowEvents reconnects when the connection drops and resumes after the last event it handed you; it stops only on a refusal that waiting cannot fix, such as a key without events:read, or when your context ends. See the events stream.

# Follow the events stream. -N keeps curl from buffering; pass the last id you handled to resume.
curl -N https://developers.aton-network.org/api/v1/events \
  -H "Authorization: Bearer $ATHERON_API_KEY" \
  -H "Accept: text/event-stream" \
  -H "Last-Event-ID: $LAST_EVENT_ID"
مثالی جواب200
retry: 3000

event: ready
data: {"types":null}

id: 5b1c2a8e-0000-4000-8000-000000000001
event: user.signed_in
data: {"id":"5b1c2a8e-0000-4000-8000-000000000001","type":"user.signed_in","created":"2026-10-15T17:02:11.000Z","client_id":"live-1a2b3c4d5e6f7a8b","data":{"sub":"9a6d4c1e-1f0b-4a51-8a8e-3b2f6c0d7e11","scopes":["openid","email"],"at":"2026-10-15T17:02:11.000Z"}}

: beat

GraphQL

NewGraphQL and Query[T] run typed queries: atheron.Query[atheron.UsageQueryData](ctx, gql, atheron.UsageQuery, vars). The documents the SDK ships (the App, Usage, Overview and Events documents the GraphQL reference publishes) go as their SHA-256 alone, so the server knows them from the first request; your own go in full unless you turn persisted queries on. Query answers a *GraphQLError when any field failed, with the data that could be read on it; Request answers the data and the field errors side by side. Go has no WebSocket in its standard library, so use FollowEvents for events as they happen, or your own WebSocket client with WSCloseAction, WSErrorAction and ResumeVariables.

یہ مثال ابھی ⁨cURL⁩ میں نہیں لکھی گئی۔ ⁨TypeScript⁩ میں دکھائی گئی ہے۔

// Your app and its usage in one GraphQL request, then its events as they happen over the subscription.
// Node 22 has a global WebSocket; on Node 20, pass { WebSocket } from the ws package.
import { AtheronGraphQL, UsageQuery } from "@aton-network/sdk";

export async function usageThisMonth(apiKey: string): Promise<number> {
  const { usage } = await new AtheronGraphQL({ apiKey }).query(UsageQuery, { days: 30 });
  return usage ? usage.usage.reduce((sum, day) => sum + day.calls, 0) : 0;
}

export async function watchConsent(apiKey: string, lastId: string | null, forget: (sub: string | undefined) => void, signal?: AbortSignal): Promise<string | null> {
  for await (const event of new AtheronGraphQL({ apiKey }).events({ types: ["consent.revoked"], lastEventId: lastId, ...(signal ? { signal } : {}) })) {
    forget(event.data.sub);
    lastId = event.id; // keep it somewhere durable, to pass back after a restart
  }
  return lastId;
}

The developer API

# Your app as registered, for the environment this API key belongs to. Needs app:read.
curl https://developers.aton-network.org/api/v1/app \
  -H "Authorization: Bearer $ATHERON_API_KEY"
مثالی جواب200
{
  "name": "Price Check",
  "state": "live",
  "kind": "confidential",
  "quota": "free",
  "env": "live",
  "client_id": "live-1a2b3c4d5e6f7a8b",
  "redirect_uris": ["https://app.example.com/callback"],
  "scopes": ["openid", "profile", "email"],
  "approved_scopes": ["openid", "profile", "email"],
  "privacy_url": "https://app.example.com/privacy",
  "homepage_url": "https://app.example.com",
  "credentials": 2,
  "testers": 0,
  "webhooks": 1
}

Errors

Every failure is an *atheron.Error with Code (for example invalid_grant), Description, the HTTP Status and, on a 429, RetryAfter. Find it in a chain with atheron.AsError(err). See Errors for every code.

Reference

ItemWhat it does
FromEnv(Config) (*Auth, error)Sign-in for a web app, from the ATHERON_* settings
(*Auth).Handler() http.HandlerThe four routes under /auth
(*Auth).RequireUser(http.Handler) http.HandlerSomebody signed in, or off to sign in and back (401 for JSON)
UserFrom(ctx) UserThe person RequireUser let through
NewCookieStore, NewMemoryStoreWhere the session lives; any Store of your own works
StartSignIn(SignInOptions) (Started, error)The authorize address and the verifier, state and nonce to keep
ParseCallback(url, state, issuer) (string, error)The code, after the state, issuer and error checks
(*Client).FinishSignIn, ExchangeCode, RefreshTokens, RevokeToken, UserinfoThe token endpoint and userinfo
IDTokenClaims(token, clientID, nonce, IDTokenOptions)An ID token's claims, checked for issuer, audience, expiry and nonce
VerifyWebhook, ConstructEvent, WebhookHandlerWebhook signatures
FollowEvents(ctx, key, FollowOptions, func(Event) error) errorThe events stream, with resume
NewAPI(key) (*API, error)The developer API, generated from the OpenAPI description

Sample apps

One per framework, each go run .: samples/net-http, samples/gin and samples/echo in the SDK's repository. Their Atheron files are the examples on these pages.

Frameworks

net/http, Gin and Echo.

⁨Atlas⁩ سے پوچھیں

AI اسسٹنٹ

Atheron کے ساتھ سائن ان، API یا پورٹل کے بارے میں کچھ بھی پوچھیں۔ جواب ہماری دستاویزات سے آتا ہے، استعمال شدہ صفحات کے لنک کے ساتھ۔