Skip to content

API Reference

Complete reference for the OxGasServerWallet class exported by @0xgasless/core.

import { OxGasServerWallet } from '@0xgasless/core';
new OxGasServerWallet(options: ServerWalletOptions)
OptionTypeDefaultDescription
apiKeystringRequired. Your project API key from the dashboard.
defaultChainIdnumber1Chain ID used when not specified per call.
timeoutnumber30000Request timeout in milliseconds. KMS signing can take a few seconds.
baseUrlstring(internal)Override the platform endpoint. Useful for staging or self-hosted deployments.
const wallet = new OxGasServerWallet({
apiKey: process.env.OXGAS_API_KEY!,
defaultChainId: 43113, // Avalanche Fuji
timeout: 30_000,
});

The apiKey is the only required field. The constructor throws synchronously if it’s missing or empty.

Idempotently fetches or creates a wallet for the given userId. The same userId always returns the same wallet.

const info = await wallet.getOrCreateWallet('telegram_123456789', {
label: 'Alice from Discord', // optional
chainId: 43113, // optional override
});
console.log(info.address); // 0x1a2b...
console.log(info.existing); // true on second+ call
console.log(info.createdAt); // ISO timestamp

Parameters:

  • userId (string) — any unique identifier you control (UUID, Telegram ID, email, etc.).
  • options.label (string, optional) — human-readable label shown in the dashboard.
  • options.chainId (number, optional) — overrides defaultChainId.

Returns: Promise<ServerWalletInfo>

interface ServerWalletInfo {
userId: string;
address: `0x${string}`;
projectId: string;
label?: string;
chainId: number;
existing?: boolean; // true if the wallet pre-existed
createdAt?: string;
}

Safe to call on every interaction — there’s no penalty for re-creating an existing wallet.


Convenience wrapper around getOrCreateWallet that returns just the address.

const address = await wallet.getAddress('telegram_123456789');
// → 0x1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b

Same parameters as getOrCreateWallet. Use this when you only need the address — for example, when displaying it to a user or constructing a deposit URL.


Returns every server wallet in your project.

const { projectId, totalWallets, wallets } = await wallet.listWallets();
for (const w of wallets) {
console.log(w.userId, w.address, w.chainId);
}

Returns: Promise<ListWalletsResponse>

interface ListWalletsResponse {
projectId: string;
totalWallets: number;
wallets: ServerWalletInfo[];
}

This endpoint is paginated server-side and may take a moment for large projects. For bots managing more than a few thousand wallets, keep your own DB index instead of relying on this for hot paths.


Sign a transaction with the wallet’s KMS-backed key. Returns the raw signed transaction — broadcasting is your responsibility.

const result = await wallet.signTransaction('telegram_123456789', {
to: '0x000000000000000000000000000000000000dEaD',
value: '1000000000000000', // 0.001 AVAX in wei
nonce: 7,
chainId: 43113,
gas: 21000, // optional
gasPrice: '30000000000', // optional (30 gwei)
data: '0x', // optional, for contract calls
});
console.log(result.rawTx); // 0xf86c... ready for eth_sendRawTransaction
console.log(result.txHash); // pre-computed hash
console.log(result.from); // the wallet address

Parameters:

interface SignTransactionParams {
to: `0x${string}`;
value: string; // wei as string — never use number for large values
nonce: number;
chainId: number;
gas?: number; // default 21000
gasPrice?: string | number; // default 30 gwei
data?: string; // calldata for contract calls
}

Returns:

interface SignTransactionResult {
rawTx: `0x${string}`;
txHash: `0x${string}`;
from: `0x${string}`;
}

Throws:

  • WalletNotFoundError — no wallet exists for this userId.
  • PolicyViolationError — the transaction was blocked by a policy rule (cap, allow-list, time window). The .reason field has the human-readable message.
  • ServerSigningError — signing failed for another reason (malformed tx, KMS error).
  • NetworkError — the API was unreachable or timed out.

See Errors for the full taxonomy.

  • value is a string. Always pass wei as a string. JS numbers lose precision above 2^53, so BigInt(amount).toString() is the safe pattern.
  • nonce is your responsibility. Fetch it from RPC (eth_getTransactionCount) or track it in your own DB. The platform does not manage nonces.
  • gas defaults to 21000. Override for contract calls — 80000 is a safe default for ERC-20 transfers, 150000+ for complex calls.
  • gasPrice defaults to 30 gwei. Override per call for chain-specific pricing.

Submit a signed transaction to any EVM RPC endpoint via eth_sendRawTransaction.

const { txHash } = await wallet.broadcastTransaction(
result.rawTx,
'https://api.avax-test.network/ext/bc/C/rpc',
);
console.log('Broadcast:', txHash);

Parameters:

  • rawTx (string) — the signed hex string returned by signTransaction.
  • rpcUrl (string) — any HTTP JSON-RPC URL for the target chain.

Returns:

interface BroadcastResult {
txHash: string;
}

Throws: NetworkError — the RPC was unreachable, returned HTTP ≥ 400, or returned an error object in the JSON-RPC response.

The returned txHash matches result.txHash from signTransaction — the RPC just confirms it accepted the transaction. Use this hash to poll for confirmation.

So you keep full control of:

  • Which RPC. Public, private, or a chain-specific gateway.
  • Confirmation strategy. Block-poll, websocket subscription, or fire-and-forget.
  • Replay handling. If the broadcast fails, you decide whether to retry with the same signature or bump the gas price and re-sign.
import type {
ServerWalletOptions,
ServerWalletInfo,
CreateWalletOptions,
SignTransactionParams,
SignTransactionResult,
ListWalletsResponse,
BroadcastResult,
} from '@0xgasless/core';

All types are exported from the package root. Use them to type your own helpers around the SDK.