npm package: @pays-solutions/sdk
Description: Official TypeScript SDK for the Pays API - cryptocurrency and fiat conversions
Author: Pays
Latest version: 0.2.1

# @pays-solutions/sdk

Official TypeScript SDK for the Pays API - cryptocurrency and fiat conversions.

## Installation

```bash
npm install @pays-solutions/sdk
```

## Requirements

- Node.js 18.0.0 or higher (uses native `fetch`)
- TypeScript 4.7+ (optional, for type support)

## Quick Start

```typescript
import { PaysClient } from '@pays-solutions/sdk';

const pays = new PaysClient({
  apiKey: process.env.PAYS_API_KEY!,
});

// Get a quote for swapping USDC to ETH
const quote = await pays.convert.quote({
  from: { asset: 'USDC', amount: '100', chain: 'ethereum' },
  to: { asset: 'ETH', chain: 'ethereum' },
  recipient: '0x742d35Cc6634C0532925a3b844Bc454e4438f44e',
});

console.log(`Rate: ${quote.rate}`);
console.log(`You'll receive: ${quote.to.amount} ETH`);
```

## Configuration

```typescript
const pays = new PaysClient({
  // Required: Your sandbox API key
  apiKey: 'sk_sandbox_...',

  // Optional: Request timeout in milliseconds (default: 30000)
  timeout: 60000,

  // Optional: Custom fetch implementation
  fetch: customFetch,
});
```

> **Note:** This SDK currently supports sandbox mode only. Production mode will be available in a future release.

## Conversions

The SDK supports three types of conversions:

- **Swap**: Crypto to crypto (e.g., USDC to ETH)
- **On-ramp**: Fiat to crypto (e.g., USD to ETH)
- **Off-ramp**: Crypto to fiat (e.g., ETH to USD)

### Get a Quote

```typescript
// Swap: Crypto to Crypto
const swapQuote = await pays.convert.quote({
  from: { asset: 'USDC', amount: '100', chain: 'ethereum' },
  to: { asset: 'ETH', chain: 'ethereum' },
  recipient: '0x742d35Cc...',
  slippage: 0.5, // 0.5% max slippage
});

// On-ramp: Fiat to Crypto
const onrampQuote = await pays.convert.quote({
  from: { asset: 'USD', amount: '100' },
  to: { asset: 'ETH', chain: 'ethereum' },
  recipient: '0x742d35Cc...',
  paymentMethod: 'card',
});

// Off-ramp: Crypto to Fiat
const offrampQuote = await pays.convert.quote({
  from: { asset: 'ETH', amount: '0.5', chain: 'ethereum' },
  to: { asset: 'USD' },
  paymentMethod: 'bank_transfer',
});
```

### Execute a Conversion

```typescript
const result = await pays.convert.execute({
  quoteId: quote.quoteId,
  walletAddress: '0x742d35Cc...',
});

// For swaps: Sign and submit the transaction
if (result.transaction) {
  const tx = await wallet.sendTransaction(result.transaction);
  await tx.wait();
}

// For ramps: Redirect user to payment page
if (result.redirect) {
  window.location.href = result.redirect.url;
}
```

### Idempotency

Use idempotency keys to safely retry requests:

```typescript
const result = await pays.convert.execute(
  { quoteId: 'qt_abc123', walletAddress: '0x742d35Cc...' },
  'order-12345' // Idempotency key
);
```

### Check Conversion Status

```typescript
const conversion = await pays.convert.get('cv_abc123');
console.log(`Status: ${conversion.status}`);
```

### Wait for Completion

```typescript
const conversion = await pays.convert.waitForCompletion('cv_abc123', {
  pollInterval: 3000,    // Check every 3 seconds
  timeout: 300000,       // 5 minute timeout
  onStatusChange: (status, conversion) => {
    console.log(`Status changed to: ${status}`);
  },
});
```

## Account

### Get Account Info

```typescript
const account = await pays.account.get();

console.log(`Environment: ${account.environment}`);
console.log(`KYC Status: ${account.kyc.status}`);
console.log(`Daily Limit: $${account.limits.daily.remaining} remaining`);
```

### Submit KYC

```typescript
const result = await pays.account.submitKyc({
  method: 'sumsub_share',
  shareToken: 'sst_abc123...',
});
```

## Assets

### List Supported Assets

```typescript
// All assets
const { assets } = await pays.assets.list();

// Crypto assets only
const { assets: crypto } = await pays.assets.list({ type: 'crypto' });

// Assets on a specific chain
const { assets: eth } = await pays.assets.list({ chain: 'ethereum' });
```

### Get Asset Details

```typescript
const eth = await pays.assets.get('ETH');

console.log(`Chains: ${eth.chains?.map(c => c.name).join(', ')}`);
console.log(`Swap limits: ${eth.limits.swap?.min} - ${eth.limits.swap?.max}`);
```

## Error Handling

The SDK provides typed errors for different failure scenarios:

```typescript
import {
  PaysError,
  PaysApiError,
  PaysTimeoutError,
  PaysNetworkError,
  PaysConfigError,
  isRetryableError,
} from '@pays-solutions/sdk';

try {
  await pays.convert.quote({ ... });
} catch (error) {
  if (error instanceof PaysApiError) {
    console.log(`API Error: ${error.code} - ${error.message}`);
    console.log(`Status: ${error.status}`);
    console.log(`Request ID: ${error.requestId}`);

    if (error.retryable) {
      // Wait and retry
      await sleep(error.retryAfter ?? 1000);
    }
  } else if (error instanceof PaysTimeoutError) {
    console.log(`Request timed out after ${error.timeout}ms`);
  } else if (error instanceof PaysNetworkError) {
    console.log(`Network error: ${error.message}`);
  }

  // Check if any error is retryable
  if (isRetryableError(error)) {
    // Implement retry logic
  }
}
```

### Error Types

| Error Class | Description |
|-------------|-------------|
| `PaysError` | Base class for all SDK errors |
| `PaysApiError` | API returned an error response |
| `PaysTimeoutError` | Request timed out |
| `PaysNetworkError` | Network connectivity issue |
| `PaysConfigError` | Invalid configuration |

## TypeScript Support

The SDK is fully typed. All request and response types are exported:

```typescript
import type {
  PaysClientConfig,
  Quote,
  QuoteRequest,
  Conversion,
  ConversionStatus,
  Account,
  Asset,
  AssetDetails,
} from '@pays-solutions/sdk';
```

## Supported Chains

- `ethereum` - Ethereum Mainnet
- `polygon` - Polygon PoS
- `arbitrum` - Arbitrum One
- `optimism` - Optimism
- `base` - Base

## Payment Methods

For fiat on/off-ramp:

- `card` - Credit/Debit Card
- `bank_transfer` - Bank Transfer
- `apple_pay` - Apple Pay
- `google_pay` - Google Pay

## License

MIT