Getting Started

Byoky lets users store their AI API keys in an encrypted wallet. Your app never sees the keys — it gets a proxied session that routes requests through the wallet.

Install the SDK

bash
npm install @byoky/sdk

Connect and make requests

typescript
import Anthropic from '@anthropic-ai/sdk';
import { Byoky } from '@byoky/sdk';

const byoky = new Byoky();
const session = await byoky.connect({
  providers: [{ id: 'anthropic', required: true }],
  modal: true,  // shows built-in connect UI with QR code
});

// Use the native Anthropic SDK — just swap in Byoky's fetch
const client = new Anthropic({
  apiKey: session.sessionKey,
  fetch: session.createFetch('anthropic'),
});

const message = await client.messages.create({
  model: 'claude-sonnet-4-20250514',
  max_tokens: 1024,
  messages: [{ role: 'user', content: 'Hello!' }],
});

Two lines changed. Full API compatibility. Streaming, file uploads, and vision all work. Sessions auto-reconnect if the extension restarts.

How it works

Your App → SDK (createFetch) → Content Script → Extension → LLM API
                                                    ↑
                                          Keys stay here. Always.

SDK Reference

Constructor

typescript
import { Byoky } from '@byoky/sdk';

const byoky = new Byoky({
  timeout: 60000,                      // connection timeout (ms)
  relayUrl: 'wss://relay.byoky.com',   // relay server for mobile pairing
});

byoky.connect(options)

Connect to a Byoky wallet. Returns a ByokySession.

typescript
const session = await byoky.connect({
  // Which providers your app needs
  providers: [
    { id: 'anthropic', required: true },
    { id: 'openai', required: false },
  ],

  // Show built-in modal with extension detection + QR code fallback
  modal: true,

  // Or handle pairing yourself
  onPairingReady: (code) => showQR(code),

  // Skip extension, go straight to relay (mobile)
  useRelay: true,
});
providersProviderRequirement[]
List of providers your app needs. required: true means connection fails if the user doesn't have that provider.
modalboolean | ModalOptions
Show the built-in connect modal. Handles extension detection, relay fallback, and QR code for mobile pairing automatically.
onPairingReady(code: string) => void
Called with a pairing code when no extension is detected. Display as QR or text for mobile wallet pairing.
useRelayboolean
Skip extension detection and go directly to relay pairing.

byoky.tryReconnect()

Silently reconnect to an existing session. Checks persisted vault sessions, extension live sessions, and stored extension sessions in order. Returns null if nothing is restorable.

typescript
const session = await byoky.tryReconnect();
if (session) {
  // Restored — ready to make requests
}

byoky.connectViaVault(options)

Connect via a Byoky Vault server. Works in both browser and Node.js environments.

typescript
const session = await byoky.connectViaVault({
  vaultUrl: 'https://vault.byoky.com',
  username: 'user@example.com',
  password: 'password',
  providers: [{ id: 'anthropic' }],
  appOrigin: 'https://myapp.com', // required in Node.js
});

Utilities

typescript
import { isExtensionInstalled, getStoreUrl } from '@byoky/sdk';

// Check if the Byoky extension is installed
if (isExtensionInstalled()) { ... }

// Get the store URL for the user's browser
const url = getStoreUrl(); // Chrome Web Store, Firefox Add-ons, etc.

Session API

A ByokySession is returned by connect(), tryReconnect(), or connectViaVault(). It provides everything you need to make API calls through the wallet.

session.createFetch(providerId)

Returns a fetch function that proxies requests through the wallet for the given provider. Use it as a drop-in replacement with any provider SDK.

typescript
// Anthropic
const client = new Anthropic({
  apiKey: session.sessionKey,
  fetch: session.createFetch('anthropic'),
});

// OpenAI
const client = new OpenAI({
  apiKey: session.sessionKey,
  fetch: session.createFetch('openai'),
});

// Or raw fetch
const fetch = session.createFetch('anthropic');
const res = await fetch('https://api.anthropic.com/v1/messages', {
  method: 'POST',
  headers: { 'content-type': 'application/json', 'anthropic-version': '2023-06-01' },
  body: JSON.stringify({ model: 'claude-sonnet-4-20250514', max_tokens: 1024, messages: [...] }),
});

session.createRelay(wsUrl)

Open a WebSocket relay channel so a backend server can make LLM calls through this session. See Backend Relay.

session.disconnect()

Disconnect the session. The wallet revokes all access.

session.isConnected()

Returns true if the session is still valid.

session.getUsage()

Get token usage stats for this session.

typescript
const usage = await session.getUsage();
// { requests: 42, inputTokens: 15000, outputTokens: 8000,
//   byProvider: { anthropic: { requests: 42, inputTokens: 15000, outputTokens: 8000 } } }

session.onDisconnect(callback)

Register a callback for when the user revokes this session from the wallet.

session.onProvidersUpdated(callback)

Register a callback for when provider availability changes (e.g. credential added/removed).

Session properties

typescript
session.sessionKey  // string — use as apiKey in provider SDKs
session.proxyUrl    // string — the proxy endpoint URL
session.providers   // Record<string, { available, authMethod, gift? }>

App Ecosystem

Build apps that users install directly into their Byoky wallet. Your app runs inside a sandboxed iframe (extension) or WebView (mobile) — full isolation from the wallet's keys and storage.

How marketplace apps work

  1. You build a web app that uses @byoky/sdk
  2. You host it on your own infrastructure (HTTPS required)
  3. You submit it to the marketplace for review
  4. Once approved, users can install it from the App Store inside their wallet
  5. Your app runs in a sandboxed environment — keys never touch your code

Scaffold a new app

bash
npx create-byoky-app my-app

# Choose a template:
#   1. AI Chat (Next.js)
#   2. Multi-Provider (Vite)
#   3. Backend Relay (Express)

Submit to the marketplace

bash
# Generate a byoky.app.json manifest
npx create-byoky-app init

# Submit for review
npx create-byoky-app submit

Or submit via the web form at byoky.com/apps/submit.

Security model

  • Apps run in sandboxed iframes (allow-scripts allow-forms) or native WebViews
  • Cross-origin isolation prevents access to wallet storage, DOM, or keys
  • All communication happens via the SDK's postMessage bridge
  • Installing an app auto-trusts its origin for the declared providers
  • Users can disable or uninstall apps at any time

App Manifest

Every marketplace app needs a byoky.app.json manifest in the project root. Run npx create-byoky-app init to generate one interactively.

json
{
  "name": "TradeBot Pro",
  "slug": "tradebot-pro",
  "url": "https://tradebot.acme-ai.com",
  "icon": "/icon.png",
  "description": "AI-powered trading signals using your own API keys",
  "category": "trading",
  "providers": ["anthropic", "openai"],
  "author": {
    "name": "Acme AI",
    "email": "dev@acme-ai.com",
    "website": "https://acme-ai.com"
  }
}

Fields

namestring
Display name shown in the App Store and icon grid.
slugstring
URL-safe identifier. Must be unique across the marketplace.
urlstring
HTTPS URL where your app is hosted. This is what loads in the sandboxed iframe.
iconstring
URL to your app icon. Displayed as a rounded square in the app grid.
descriptionstring
Short description shown in the store listing.
categorystring
One of: chat, coding, trading, productivity, research, creative, other.
providersstring[]
Provider IDs your app needs (e.g. ["anthropic", "openai"]). Users approve which providers to grant on install.
authorobject
Author info: name (required), email (required), website (optional).

Review criteria

  • App loads over HTTPS
  • Uses @byoky/sdk for all LLM access
  • Only requests providers it actually uses
  • No obfuscated JavaScript
  • Privacy policy exists

Token Gifts

Share token access without sharing your API key. The sender's wallet proxies all requests — the key never leaves the extension.

Sender's Extension ←WebSocket→ Relay Server ←WebSocket→ Recipient's Extension

Create a gift

  1. Open the wallet → select a credential → click "Gift"
  2. Set a token budget and expiry
  3. Share the generated gift link

Redeem a gift

  1. Open the wallet → click "Redeem Gift"
  2. Paste the gift link → accept

Self-host the relay

bash
npm install -g @byoky/relay
byoky-relay  # default port 8787

The recipient never receives your API key. Every request is relayed through the sender's running extension, which enforces the token budget and can revoke access at any time.

Token Marketplace

The Token Marketplace is a public board where users share free token gifts with the community.

How it works

  1. Create a gift in your wallet (extension or mobile)
  2. Check "List on Token Marketplace"
  3. Add a display name (or stay anonymous)
  4. Your gift appears on the marketplace for anyone to redeem

What users see

  • Online/offline status — green dot if the gifter's wallet is online (gift is usable), red if offline
  • Tokens remaining — progress bar showing how much budget is left
  • Expiry countdown — time until the gift expires
  • Provider — which LLM provider the tokens are for

API endpoints

The marketplace runs at marketplace.byoky.com with these endpoints:

GET    /gifts              — list active + expired gifts
GET    /gifts/:id/redeem   — get gift link for redemption
POST   /gifts              — list a gift publicly (called by wallet)
DELETE /gifts/:id          — unlist a gift
PATCH  /gifts/:id/usage    — update token usage
POST   /gifts/:id/heartbeat — online status ping

Wallet integration

When a user checks "List on Token Marketplace" during gift creation, the wallet automatically POSTs the gift metadata to the marketplace API. No extra steps needed — the gift is listed the moment it's created.

Backend Relay

Need LLM calls from your server? The user's browser relays requests through the extension — your backend never sees the API key.

Backend ←WebSocket→ User's Frontend ←Extension→ LLM API

Frontend

typescript
import { Byoky } from '@byoky/sdk';

const session = await new Byoky().connect({
  providers: [{ id: 'anthropic' }],
  modal: true,
});

// Open relay so your backend can make calls through this session
const relay = session.createRelay('wss://your-app.com/ws/relay');

Backend (Node.js)

typescript
import { ByokyServer } from '@byoky/sdk/server';

const byoky = new ByokyServer();

wss.on('connection', async (ws) => {
  const client = await byoky.handleConnection(ws);
  const fetch = client.createFetch('anthropic');

  const res = await fetch('https://api.anthropic.com/v1/messages', {
    method: 'POST',
    headers: {
      'content-type': 'application/json',
      'anthropic-version': '2023-06-01',
    },
    body: JSON.stringify({
      model: 'claude-sonnet-4-20250514',
      max_tokens: 1024,
      messages: [{ role: 'user', content: 'Hello!' }],
    }),
  });
});

Bridge (CLI / Desktop)

CLI tools and desktop apps route API calls through the bridge — a local HTTP proxy that relays requests to the extension via native messaging.

CLI App → HTTP → Bridge (localhost:19280) → Native Messaging → Extension → LLM API

Setup

bash
npm install -g @byoky/bridge
byoky-bridge install   # register native messaging host

Usage

Once installed, the bridge starts automatically when the extension needs it. CLI tools (like OpenClaw) make HTTP requests to http://127.0.0.1:19280/{provider}/, which the bridge forwards to the extension.

Supported Providers

All providers work with createFetch(providerId):

anthropicAnthropic (Claude)
openaiOpenAI (GPT)
geminiGoogle Gemini
mistralMistral
cohereCohere
xaixAI (Grok)
deepseekDeepSeek
perplexityPerplexity
groqGroq
togetherTogether AI
fireworksFireworks AI
openrouterOpenRouter
azure_openaiAzure OpenAI

Cross-provider routing

Users can route your app's requests through a different provider than what your code targets. For example, your app calls anthropic but the user routes it throughopenai — the wallet transparently translates request/response bodies and SSE streams. Your code doesn't need to change.