npm package: @pooflabs/server
Description: Server SDK for Poof API - Node.js/Backend implementation
Author: Poof.new
Latest version: 0.0.31

# @tarobase/server

Server SDK for Tarobase API - Node.js/Backend implementation. This package provides functionality for server-side applications to interact with the Tarobase API using Solana keypairs for authentication.

## Installation

```bash
npm install @tarobase/server
```

Or using yarn:

```bash
yarn add @tarobase/server
```

## Features

- Server-side authentication using Solana keypairs
- In-memory session management (no cookies or local storage required)
- Support for all Tarobase data operations (get, getMany, set, query)
- Real-time subscriptions
- Transaction signing and execution
- TypeScript support

## Basic Usage

```typescript
import { init, login, getCurrentUser, set, get } from '@tarobase/server';
import { Keypair } from '@solana/web3.js';

async function main() {
  // Initialize the SDK
  await init({
    apiKey: 'your-api-key',
    appId: 'your-app-id',
    authMethod: 'solana-keypair'
  });

  // Create or load a Solana keypair
  const keypair = Keypair.generate(); // or load from a file/secret
  // Alternative: const keypair = "your-base58-encoded-private-key"

  // Log in with the keypair
  const user = await login(keypair);
  if (!user) {
    console.error('Login failed');
    return;
  }

  console.log(`Logged in as: ${user.address}`);

  // Set data
  await set('todos/123', { 
    text: 'Buy milk', 
    completed: false, 
    created: new Date().toISOString() 
  });

  // Get data
  const todo = await get('todos/123');
  console.log('Retrieved todo:', todo);
}

main().catch(console.error);
```

## Advanced Usage

### Loading a Keypair from a Secret Key File

```typescript
import { init, login, getCurrentUser } from '@tarobase/server';
import { Keypair } from '@solana/web3.js';
import * as fs from 'fs';

// Load keypair from file
const secretKeyString = fs.readFileSync('/path/to/keypair.json', 'utf8');
const secretKey = Uint8Array.from(JSON.parse(secretKeyString));
const keypair = Keypair.fromSecretKey(secretKey);

// Initialize and login
await init({ apiKey: 'your-api-key', appId: 'your-app-id' });
await login(keypair);
```

### Using the SolanaKeypairProvider Directly

```typescript
import { init, SolanaKeypairProvider, getAuthProvider } from '@tarobase/server';
import { Keypair } from '@solana/web3.js';

// Initialize the SDK
await init({
  apiKey: 'your-api-key',
  appId: 'your-app-id',
  rpcUrl: 'https://api.mainnet-beta.solana.com'
});

// Get the auth provider (automatically created during init)
const provider = await getAuthProvider() as SolanaKeypairProvider;

// Or create a provider instance directly
// const provider = new SolanaKeypairProvider("https://api.mainnet-beta.solana.com");

// Set the keypair
provider.setKeypair(Keypair.generate());

// Login
const user = await provider.login();

// Sign a message
const signature = await provider.signMessage("Hello, world!");

// Run a transaction (example)
const txResult = await provider.runTransaction(undefined, {
  appId: 'your-app-id',
  txArgs: [{
    setDocumentData: [{ path: 'todos/123', data: { text: 'New todo' } }],
    deletePaths: [],
    remainingAccounts: [],
    idl: {}
  }]
});
```

### Subscriptions

```typescript
import { init, login, subscribe, unsubscribe } from '@tarobase/server';
import { Keypair } from '@solana/web3.js';

// Initialize and login
await init({ apiKey: 'your-api-key', appId: 'your-app-id' });
await login(Keypair.generate());

// Subscribe to changes
const unsubscribeFunc = await subscribe('todos', (data) => {
  console.log('Todos updated:', data);
});

// Later, unsubscribe when done
unsubscribeFunc();
// Or use the unsubscribe function
await unsubscribe('todos');
```

## API Reference

### Configuration and Initialization

```typescript
function init(config: Partial<ClientConfig>): Promise<void>;
function getConfig(): Promise<ClientConfig>;
function getSessionOptions(): SessionOptions;
function isInitialized(): boolean;
function waitForInitialization(): Promise<void>;
```

### Authentication

```typescript
function login(keypair?: Keypair | string | Uint8Array): Promise<User | null>;
function logout(): Promise<void>;
function getCurrentUser(): User | null;
function getAuthProvider(): Promise<AuthProvider>;
function getIdToken(): Promise<string | null>;
```

### Data Operations

```typescript
function get(path: string): Promise<any>;
function getMany(paths: string[], options?: { bypassCache?: boolean }): Promise<GetManyResult[]>;
function set(path: string, data: any, options?: SetOptions): Promise<any>;
function setMany(paths: { [key: string]: any }, options?: SetOptions): Promise<any>;
function setFile(path: string, file: File, metadata?: any): Promise<any>;
function getFiles(path: string): Promise<any>;
function runQuery(queryString: string, variables?: any): Promise<any>;
function runQueryMany(queryString: string, variables?: any): Promise<any>;
```

### Subscriptions

```typescript
function subscribe(path: string, callback: (data: any) => void): Promise<() => void>;
function unsubscribe(path: string): Promise<void>;
```

### Solana Keypair Provider

```typescript
class SolanaKeypairProvider implements AuthProvider {
  constructor(networkUrl?: string);
  
  setKeypair(keypair: Keypair | string | Uint8Array): void;
  login(): Promise<User | null>;
  logout(): Promise<void>;
  signMessage(message: string): Promise<string>;
  runTransaction(evmTransactionData?: EVMTransaction, solTransactionData?: SolTransaction, options?: SetOptions): Promise<TransactionResult>;
  restoreSession(): Promise<User | null>;
  getNativeMethods(): Promise<any>;
}
```

## Types

```typescript
interface ClientConfig {
  apiKey: string;
  authMethod: 'solana-keypair' | string;
  wsApiUrl: string;
  apiUrl: string;
  appId: string;
  authApiUrl: string;
  chain: string;
  rpcUrl: string;
  skipBackendInit: boolean;
  useSessionStorage: boolean;
}

interface User {
  address: string;
  provider: AuthProvider;
}

interface SetOptions {
  shouldSubmitTx?: boolean;
}

interface GetManyResult {
  path: string;
  data: any | null;
  error?: {
    code: 'NOT_FOUND' | 'UNAUTHORIZED' | 'INVALID_PATH';
    message: string;
  };
}

interface TransactionResult {
  transactionSignature?: string;
  signedTransaction?: any;
  blockNumber: number;
  gasUsed: string;
  data: any;
}
```

## Contributing

Please see the main repository for contribution guidelines.

## Key Differences from the Web SDK

This server-side SDK differs from the web SDK in several important ways:

1. **Authentication Method**: Uses Solana keypairs instead of browser wallets
2. **Storage Strategy**: Uses in-memory storage instead of localStorage/sessionStorage 
3. **Environment**: Optimized for Node.js/backend environments rather than browsers
4. **Session Management**: Does not rely on browser-specific APIs
5. **Dependencies**: Excludes browser-specific libraries

## Part of the Tarobase SDK Family

This package is part of a family of modular SDKs:

- **@pooflabs/core**: Core functionality shared between all SDKs
- **@pooflabs/web**: Browser-focused SDK (identical to original js-sdk)
- **@pooflabs/server**: Server-side SDK for backend applications