Observed since 21 Oct, 08:55 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
All-in-one SDK for secure embedded wallets, ERC-4337 smart accounts, and server-side wallet management on EVM chains
The all-in-one SDK for secure embedded wallets, ERC-4337 smart accounts, and server-side wallet management on EVM chains.
@0xgasless/core provides two powerful wallet primitives in a single package:
User Wallets (OxGasClient) | Server Wallets (OxGasServerWallet) | |
|---|---|---|
| Environment | Browser | Node.js / Server |
| Auth | Email OTP, Google, MetaMask via widget | API key only — no login required |
| Signing | User approves in secure iframe | Instant — no human approval |
| Use case | dApps, web3 frontends | Telegram bots, trading bots, cron jobs |
| Key storage | AWS KMS (iframe-secured) | AWS KMS (API-secured + policy engine) |
Private keys never leave AWS KMS in either mode.
npm install @0xgasless/core
# or
yarn add @0xgasless/core
# or
pnpm add @0xgasless/core
Use OxGasClient for browser-based dApps where end users authenticate and approve transactions.
import { OxGasClient } from '@0xgasless/core';
const client = new OxGasClient({
apiKey: 'your-api-key',
chainId: 11155111,
bundlerUrl: 'https://bundler.0xgasless.com/11155111',
paymasterUrl: 'https://paymaster.0xgasless.com/v1/11155111/rpc/your-paymaster-key',
debug: true,
});
// 1. Authenticate — opens the secure widget
const wallet = await client.login();
console.log('Logged in as:', wallet.email);
// 2. Initialize Smart Account
const smartAccountAddress = await client.setupSmartAccount();
console.log('Smart Account:', smartAccountAddress);
// 3. Send a Gasless Transaction
const { wait } = await client.sendTransaction({
to: '0xTargetContract...',
value: 0n,
data: '0x...',
});
const receipt = await wait();
console.log('Confirmed:', receipt.receipt.transactionHash);
| Option | Type | Default | Description |
|---|---|---|---|
apiKey | string | (required) | Your 0xGas API key |
chainId | number | 1 | Target EVM chain ID |
bundlerUrl | string | (required) | ERC-4337 bundler RPC URL |
paymasterUrl | string | (required) | Paymaster RPC URL for gas sponsorship |
rpcUrl | string | — | Optional custom RPC URL |
accountIndex | number | 0 | Derive multiple smart accounts per user |
debug | boolean | false | Enable verbose console logging |
client.login()Opens the widget for email/password authentication. Returns WalletInfo with the KMS EOA address and email. Resolves immediately if already logged in.
client.setupSmartAccount()Derives the ERC-4337 smart account. Must be called after login(). Returns the deterministic smart account address.
client.sendTransaction(tx)Signs via KMS widget, sponsors gas via paymaster, submits to bundler. Returns UserOpResponse with wait() for confirmation.
client.sendBatchTransactions(txs)Execute multiple calls in a single UserOperation:
await client.sendBatchTransactions([
{ to: '0xToken...', data: '0xApprove...' },
{ to: '0xProtocol...', data: '0xDeposit...' },
]);
client.transferToken(params)Gasless ERC-20 transfer with automatic decimal handling:
await client.transferToken({
tokenAddress: '0xUSDC...',
to: '0xRecipient...',
amount: '10.5', // Human-readable, parsed automatically
});
client.getTokenBalance(tokenAddress)Returns { balance, symbol, name, decimals, rawBalance } for the smart account.
client.isLoggedIn // boolean
client.eoaAddress // KMS signer address
client.smartAccountAddress // Smart account address
client.chainId // Active chain ID
client.rpcUrl // Active RPC URL
await client.logout(); // Clear session & iframe
Use OxGasServerWallet for backend systems — Telegram bots, trading bots, cron jobs, AI agents — where wallets need to be managed programmatically without any user interaction.
import { OxGasServerWallet } from '@0xgasless/core';
const wallet = new OxGasServerWallet({
apiKey: 'your_project_api_key',
defaultChainId: 43113, // Avalanche Fuji
});
// Create or retrieve a wallet — safe to call every time
const address = await wallet.getAddress('telegram_123456789');
console.log('Wallet:', address);
// Sign a transaction
const result = await wallet.signTransaction('telegram_123456789', {
to: '0x1111111111111111111111111111111111111111',
value: '1000000000000000', // wei as string
nonce: 0,
chainId: 43113,
});
// Broadcast to the network
const { txHash } = await wallet.broadcastTransaction(
result.rawTx,
'https://api.avax-test.network/ext/bc/C/rpc'
);
console.log('Transaction:', txHash);
| Option | Type | Default | Description |
|---|---|---|---|
apiKey | string | (required) | Your 0xGas project API key |
baseUrl | string | https://pmwv2d8iwa... | Override the API base URL |
defaultChainId | number | 1 | Default chain ID when not specified per call |
timeout | number | 30000 (30s) | HTTP request timeout in ms |
wallet.getOrCreateWallet(userId, options?)Creates a new wallet or returns the existing one. Idempotent — safe to call on every user interaction.
const info = await wallet.getOrCreateWallet('telegram_123456789', {
label: "John's trading wallet", // Optional, shown in dashboard
chainId: 43113, // Optional, overrides defaultChainId
});
// info.address, info.userId, info.existing, info.projectId, ...
wallet.getAddress(userId, options?)Convenience method — calls getOrCreateWallet and returns just the address string.
const address = await wallet.getAddress('telegram_123456789');
wallet.signTransaction(userId, txParams)Signs a transaction instantly via KMS — no human approval required.
const result = await wallet.signTransaction('telegram_123456789', {
to: '0x1111111111111111111111111111111111111111',
value: '1000000000000000', // wei as string
nonce: 0,
chainId: 43113,
gas: 21000, // optional, default 21000
gasPrice: '30000000000', // optional, default 30 gwei
data: '0x', // optional, for contract calls
});
// result.rawTx — signed, RLP-encoded, ready to broadcast
// result.txHash — pre-computed hash
// result.from — the server wallet address
wallet.broadcastTransaction(rawTx, rpcUrl)Broadcasts a signed transaction to any EVM-compatible RPC endpoint.
const { txHash } = await wallet.broadcastTransaction(
result.rawTx,
'https://api.avax-test.network/ext/bc/C/rpc'
);
wallet.listWallets()List all server wallets in the project.
const { wallets, totalWallets } = await wallet.listWallets();
A complete example integrating OxGasServerWallet with a Telegram bot:
import { OxGasServerWallet, PolicyViolationError } from '@0xgasless/core';
const wallet = new OxGasServerWallet({
apiKey: 'your_project_api_key',
defaultChainId: 43113,
});
// Handle /wallet command
bot.command('wallet', async (ctx) => {
const userId = `telegram_${ctx.from.id}`;
const address = await wallet.getAddress(userId);
await ctx.reply(`Your wallet address:\n\`${address}\``, { parse_mode: 'Markdown' });
});
// Handle /send command
bot.command('send', async (ctx) => {
const userId = `telegram_${ctx.from.id}`;
const [toAddress, amountWei] = ctx.message.text.split(' ').slice(1);
try {
const result = await wallet.signTransaction(userId, {
to: toAddress as `0x${string}`,
value: amountWei,
nonce: 0, // Fetch from chain in production
chainId: 43113,
});
const { txHash } = await wallet.broadcastTransaction(
result.rawTx,
'https://api.avax-test.network/ext/bc/C/rpc'
);
await ctx.reply(`✅ Transaction sent!\nHash: ${txHash}`);
} catch (err) {
if (err instanceof PolicyViolationError) {
await ctx.reply(`❌ Blocked by policy: ${err.reason}`);
} else {
await ctx.reply(`❌ Transaction failed: ${(err as Error).message}`);
}
}
});
All errors extend OxGasError and include a programmatic code field:
import {
// User wallet errors
NotConnectedError, // code: 'NOT_CONNECTED'
SigningRejectedError, // code: 'SIGNING_REJECTED'
SigningTimeoutError, // code: 'TIMEOUT'
WidgetError, // code: 'WIDGET_ERROR'
// Server wallet errors
WalletNotFoundError, // code: 'WALLET_NOT_FOUND'
PolicyViolationError, // code: 'POLICY_VIOLATION' — includes .reason
ServerSigningError, // code: 'SERVER_SIGNING_ERROR'
NetworkError, // code: 'NETWORK_ERROR' — includes .statusCode
} from '@0xgasless/core';
Download counts and popularity will appear here as the collector receives them.
This describes our collected data; it is not a security assessment.
Observed since 21 Oct, 08:55 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
package:d952d7e500e19d9b1c5a170c9771a153df7fa19b75baef0e97a47049ff8b84da