Primeros pasos
Autenticación
Sign-In With Solana para la API de Seeryx: el mensaje, el token en X-Auth-Token o Bearer y la clave de la sesión de trading que firma tus órdenes.
Descripción general
| Llamadas | Requisitos |
|---|---|
| Datos de mercado: mercados, rondas, libros, operaciones, eventos, perfiles | Nada |
| Tu cuenta: efectivo, posiciones, órdenes, actividad | Un token de inicio de sesión en X-Auth-Token |
| Órdenes, cancelaciones, divisiones, combinaciones | El token y una Idempotency-Key; en seeryx.com cada orden, división y combinación lleva además signed, creado por tu clave de sesión de trading |
| Depósitos, retiros, la propia sesión | El token y la firma de tu billetera en la transacción que prepara el servidor |
Iniciar sesión con una billetera
Seeryx usa Sign-In With Solana: tu billetera firma un breve mensaje de texto, lo que no cuesta nada ni envía nada a la cadena de bloques.
POST /api/auth/noncecon{ "address": "<your wallet>" }devuelve el mensaje. Es válido durante 5 minutos y solo funciona una vez.- Comprueba que la línea 1 nombra este sitio y la línea 2 tu dirección; después, firma los bytes UTF-8 exactos del mensaje con la clave Ed25519 de la billetera y codifica la firma de 64 bytes en base58.
POST /api/auth/verifyconaddress,messageysignaturedevuelvetoken. El primer inicio de sesión crea la cuenta.
seeryx.com wants you to sign in with your Solana account:
4hfqTJ6sVSszXZGCYjXEr4YuAXz9nyLut8725NP9mVvm
Sign in to Seeryx. This does not send a transaction or cost a fee.
URI: https://seeryx.com
Version: 1
Chain ID: mainnet
Nonce: a4b5fb6f571c43b4b1c5057abaa8cea2
Issued At: 2026-10-13T18:29:28.000Z
Expiration Time: 2026-10-13T18:34:28.000Z// seeryx.ts: a small client for the Seeryx API. Node 22+, npm i @solana/kit
import { readFileSync } from 'node:fs';
import { createKeyPairFromBytes, getAddressFromPublicKey, getBase58Decoder, signBytes } from '@solana/kit';
import type { Address } from '@solana/kit';
import { apiUrl } from './api-url.mjs';
export const BASE = process.env.SEERYX_URL ?? 'https://seeryx.com';
export const ACCESS = process.env.SEERYX_ACCESS ?? ''; // only on a site with access codes
let token = '';
export interface Round {
slug: string; start: number; end: number; open: number | null; close: number | null;
outcome: 'up' | 'down' | null; status: 'upcoming' | 'live' | 'settled';
}
export interface Book { bids: [price: number, shares: number][]; asks: [price: number, shares: number][] }
export interface Account {
positions: { slug: string; side: 'up' | 'down'; shares: number; cost: number }[];
orders: {
id: number; slug: string; side: 'up' | 'down'; action: 'buy' | 'sell'; shares: number; limit: number;
}[];
balance: { available: number; total: number };
}
export class ApiError extends Error {
constructor(
message: string, readonly status: number, readonly code?: string, readonly retryAfter?: number,
) {
super(message);
}
}
// One request. Writes get a fresh Idempotency-Key unless you pass the key of the attempt you are retrying.
export async function api<T>(path: string, init: { method?: string; body?: unknown; key?: string } = {}) {
const method = init.method ?? 'GET';
const headers: Record<string, string> = { 'Content-Type': 'application/json' };
if (token) headers['X-Auth-Token'] = token;
if (ACCESS) headers['X-Access-Token'] = ACCESS;
if (method !== 'GET') headers['Idempotency-Key'] = init.key ?? crypto.randomUUID();
const body = init.body === undefined ? undefined : JSON.stringify(init.body);
const res = await fetch(apiUrl(BASE, path), { method, headers, body, redirect: 'error' });
const data = await res.json().catch(() => ({}));
if (!res.ok) {
const wait = Number(res.headers.get('Retry-After')) || undefined;
throw new ApiError(data.error ?? `HTTP ${res.status}`, res.status, data.code, wait);
}
return data as T;
}
export interface Wallet { pair: CryptoKeyPair; address: Address }
// A wallet file as solana-keygen writes it: a JSON array of 64 numbers.
export async function loadWallet(path = process.env.SEERYX_WALLET ?? 'wallet.json'): Promise<Wallet> {
const pair = await createKeyPairFromBytes(new Uint8Array(JSON.parse(readFileSync(path, 'utf8'))));
return { pair, address: await getAddressFromPublicKey(pair.publicKey) };
}
// Sign-In With Solana: ask for the message, check it, sign its exact bytes, trade the signature for a token.
export async function signIn(wallet: Wallet) {
const { address } = wallet;
const { message } = await api<{ message: string }>('/auth/nonce', { method: 'POST', body: { address } });
const [first, second] = message.split('\n');
const site = `${new URL(BASE).hostname} wants you to sign in with your Solana account:`;
if (first !== site || second !== address) {
throw new Error('Unexpected sign-in message: not this site or not this wallet');
}
const bytes = await signBytes(wallet.pair.privateKey, new TextEncoder().encode(message));
const signature = getBase58Decoder().decode(bytes);
const body = { address, message, signature };
({ token } = await api<{ token: string }>('/auth/verify', { method: 'POST', body }));
return token; // valid for 7 days
}Tokens de inicio de sesión
- Cabecera
- Envía el token como
X-Auth-Token: <token>oAuthorization: Bearer <token>en cada solicitud con sesión iniciada, y comotokenen la suscripción de cuenta del WebSocket. - Vigencia
- 7 días. Vuelve a iniciar sesión antes de que venza, o cuando una llamada responda 403 (seeryx.com) o 401 con "Invalid or expired token".
- Cookies
- El propio sitio web inicia sesión con una cookie HttpOnly y un token CSRF, que solo pueden usar las páginas del sitio. Los clientes de la API usan la cabecera del token y no necesitan ninguno de los dos.
- Límites
- 30 solicitudes por minuto y por dirección IP para cada uno de
/auth/noncey/auth/verify.
La clave de la sesión de trading
En seeryx.com cada operación se liquida en Solana a través del programa de Seeryx, y el programa solo acepta órdenes firmadas para tu cuenta. En lugar de pedir a la billetera que firme cada orden, la billetera aprueba una vez una clave de sesión:
| Campo | Tipo | Descripción |
|---|---|---|
key | clave pública | Una clave Ed25519 nueva creada por tu bot. Firma órdenes, divisiones y combinaciones. |
expiresAt | segundos Unix | Cuándo deja de funcionar la clave: como máximo maxSessionTtl de GET /api/funds a partir de ahora (24 horas). |
limit | USDC | Lo máximo que la clave puede gastar en compras y divisiones en total. |
maxTrade | USDC | Lo máximo que puede gastar una orden; como máximo, limit. |
- Puede operar, nunca retirar. La clave solo puede firmar órdenes, divisiones y combinaciones para tu cuenta dentro de sus límites. Los retiros siempre necesitan la propia billetera.
- Una sola a la vez. Una sesión nueva reemplaza la clave anterior; las órdenes en el libro firmadas por la clave anterior se cancelan en cuanto se empieza a usar la nueva.
- Las órdenes límite no deben sobrevivir a la sesión. Se rechaza una orden que quedaría en el libro más allá del final de la sesión: abre una sesión nueva antes de cotizar una ronda que cierra más tarde (las rondas de 1 día, por ejemplo).
- Gratis. Seeryx paga la comisión de red y la renta de la cuenta de la transacción de sesión. Antes, tu primer depósito debe haber abierto tu cuenta (hasta entonces: 409 "Deposit first").
- Ciérrala antes de tiempo con
POST /api/relay{ "action": "close_session" }: tus órdenes en el libro se cancelan y la clave deja de funcionar al instante.
Cómo abrir la sesión y firmar con ella, byte a byte: Firma de órdenes.
Cerrar sesión
POST /api/auth/logoutinvalida el token que envías;POST /api/auth/logout-allinvalida todos los tokens de la cuenta.- Ninguno de los dos cierra la clave de la sesión de trading: ciérrala con
close_sessiono deja que venza.
curl -s -X POST https://seeryx.com/api/auth/logout-all -H "X-Auth-Token: $TOKEN"
# {"success":true}Endpoints de inicio de sesión
Inicia sesión con una billetera de Solana: pide un mensaje, firma sus bytes exactos con la clave de la billetera e intercambia la firma por un token. No se envía nada a la cadena de bloques ni se paga ninguna comisión.
/api/auth/nonceObtener el mensaje que hay que firmar
| Campo | Tipo | Descripción |
|---|---|---|
address | string | Dirección de billetera de Solana (base58) |
curl -X POST "https://seeryx.com/api/auth/nonce" \
-H "Content-Type: application/json" \
-d '{"address":"4hfqTJ6sVSszXZGCYjXEr4YuAXz9nyLut8725NP9mVvm"}'{
"message": "seeryx.com wants you to sign in with your Solana account:\n4hfqTJ6sVSszXZGCYjXEr4YuAXz9nyLut8725NP9mVvm\n\nSign in to Seeryx. This does not send a transaction or cost a fee.\n\nURI: https://seeryx.com\nVersion: 1\nChain ID: mainnet\nNonce: a4b5fb6f571c43b4b1c5057abaa8cea2\nIssued At: 2026-10-13T18:29:28.000Z\nExpiration Time: 2026-10-13T18:34:28.000Z",
"nonce": "a4b5fb6f571c43b4b1c5057abaa8cea2"
}- El mensaje es válido durante 5 minutos y solo puede usarse una vez. Chain ID indica el clúster de Solana del servidor.
| Estado | Cuándo |
|---|---|
| 400 | No es una dirección de Solana |
| 429 | Más de 30 solicitudes por minuto desde tu dirección IP |
/api/auth/verifyIntercambiar el mensaje firmado por un token
| Campo | Tipo | Descripción |
|---|---|---|
address | string | La misma dirección de billetera |
message | string | El mensaje exactamente como se recibió |
signature | string | Firma Ed25519 de los bytes del mensaje (UTF-8), en base58 |
curl -X POST "https://seeryx.com/api/auth/verify" \
-H "Content-Type: application/json" \
-d '{"address":"4hfqTJ6sVSszXZGCYjXEr4YuAXz9nyLut8725NP9mVvm","message":"...","signature":"5Kq3..."}'{ "token": "eyJ0eXAiOiJKV1Qi...", "user": { "id": 3, "address": "4hfqTJ6sVSszXZGCYjXEr4YuAXz9nyLut8725NP9mVvm", "createdAt": "2026-10-13 18:29:28" } }- El token es válido durante 7 días. Envíalo como X-Auth-Token (o Authorization: Bearer) en cada solicitud con sesión iniciada. El primer inicio de sesión crea la cuenta.
| Estado | Cuándo |
|---|---|
| 401 | "Signature verification failed" o "Invalid or expired login message" |
| 403 | Esta cuenta está bloqueada |
| 429 | Más de 30 solicitudes por minuto desde tu dirección IP |
/api/auth/meLa cuenta con sesión iniciada y su efectivo
curl "https://seeryx.com/api/auth/me" \
-H "X-Auth-Token: $TOKEN"{ "user": { "id": 3, "address": "4hfqTJ6sVSszXZGCYjXEr4YuAXz9nyLut8725NP9mVvm", "username": null, "avatar": null },
"balance": { "total": 474.097965, "available": 474.097965, "locked": 0, "currency": "USDC" } }/api/auth/logoutInvalidar este token de inicio de sesión
curl -X POST "https://seeryx.com/api/auth/logout" \
-H "X-Auth-Token: $TOKEN"{ "success": true }- Los demás tokens de la cuenta siguen funcionando. No cierra la clave de la sesión de trading: ciérrala con POST /api/relay close_session.
/api/auth/logout-allInvalidar todos los tokens de inicio de sesión de la cuenta
curl -X POST "https://seeryx.com/api/auth/logout-all" \
-H "X-Auth-Token: $TOKEN"{ "success": true }- Todos los tokens creados hasta ahora dejan de funcionar, también este; vuelve a iniciar sesión para obtener uno nuevo.
/api/auth/usernameFijar o cambiar el nombre de usuario público
| Campo | Tipo | Descripción |
|---|---|---|
username | string | De 2 a 20 letras, dígitos o _; único sin distinguir mayúsculas y minúsculas |
curl -X POST "https://seeryx.com/api/auth/username" \
-H "X-Auth-Token: $TOKEN" \
-H "Content-Type: application/json" \
-d '{"username":"satoshi_bot"}'{ "success": true, "username": "satoshi_bot" }- El nombre aparece en la clasificación y en tu perfil público; sin él, se muestra tu billetera abreviada.