npm package: @openpets/wise
Description: Wise API client for fetching transactions and account data
Latest version: 1.0.2

# Wise Pet Plugin

A self-contained OpenPets plugin for integrating with the Wise API to fetch transactions, account balances, exchange rates, and manage international money transfers.

## Features

- Fetch profiles and account information
- Retrieve transaction history with advanced filtering
- Get account balances across multiple currencies
- Search and filter transactions
- Create currency conversion quotes
- Get real-time exchange rates
- Retrieve account statements
- Generate spending summaries and analytics
- Manage recipients for transfers
- Support for both sandbox and production environments
- Type-safe TypeScript interface

## Installation

```bash
cd pets/wise
npm install
```

## Configuration

### Environment Variables

Create a `.env` file in the plugin directory or set these environment variables:

```bash
WISE_API_TOKEN=your_api_token_here
WISE_SANDBOX=false  # Set to 'true' for sandbox testing
WISE_PROFILE_ID=12345678  # Optional: Set default profile ID
```

See `.env.example` for a complete configuration template.

## Usage

### Basic Example

```typescript
import { WiseAPI } from './index'

const client = new WiseAPI({
  apiToken: process.env.WISE_API_TOKEN,
  sandbox: false
})

const profiles = await client.getProfiles()
console.log(`Found ${profiles.length} profiles`)

const transactions = await client.getTransactions({
  profileId: profiles[0].id,
  limit: 100
})

console.log(`Found ${transactions.length} transactions`)
```

### Get Account Balances

```typescript
const balances = await client.getBalances()
balances.forEach(balance => {
  console.log(`${balance.currency}: ${balance.balance}`)
})
```

### Fetch Transactions

```typescript
const transactions = await client.getTransactions({
  profileId: 12345678,
  intervalStart: new Date('2024-01-01'),
  intervalEnd: new Date(),
  limit: 1000
})

transactions.forEach(tx => {
  console.log(`${tx.date}: ${tx.description} - ${tx.amount} ${tx.currency}`)
})
```

### Search Transactions

```typescript
const results = await client.searchTransactions({
  query: 'Amazon',
  minAmount: 10,
  maxAmount: 500,
  currency: 'USD',
  intervalStart: new Date('2024-01-01'),
  limit: 50
})
```

### Get Exchange Rates

```typescript
const rate = await client.getExchangeRates('USD', 'EUR')
console.log(`1 ${rate.source} = ${rate.rate} ${rate.target}`)
```

### Create Currency Quote

```typescript
const quote = await client.createQuote({
  sourceCurrency: 'USD',
  targetCurrency: 'EUR',
  sourceAmount: 1000
})

console.log(`Converting ${quote.sourceAmount} ${quote.sourceCurrency}`)
console.log(`You will receive ${quote.targetAmount} ${quote.targetCurrency}`)
console.log(`Rate: ${quote.rate}, Fee: ${quote.fee}`)
```

### Get Spending Summary

```typescript
const summary = await client.getSpendingSummary({
  intervalStart: new Date('2024-01-01'),
  intervalEnd: new Date(),
  groupBy: 'category'
})

console.log(`Total spent: ${summary.totalSpent}`)
console.log(`Total received: ${summary.totalReceived}`)
console.log('Breakdown by category:', summary.breakdown)
```

## API Reference

### WiseAPI

#### Constructor

```typescript
new WiseAPI(config?: WiseConfig)
```

**Parameters:**
- `config.apiToken?` - Wise API token (falls back to `WISE_API_TOKEN` env var)
- `config.sandbox?` - Use sandbox environment (falls back to `WISE_SANDBOX` env var)

#### Methods

##### `testConnection(): Promise<boolean>`

Test the API connection and credentials.

##### `getProfiles(): Promise<WiseProfile[]>`

Fetch all profiles associated with your account (personal and business).

##### `getAccounts(profileId?: number): Promise<WiseAccount[]>`

Get multi-currency account details for a profile.

**Parameters:**
- `profileId?` - Optional profile ID (uses `WISE_PROFILE_ID` env var if not provided)

##### `getBalances(profileId?: number): Promise<WiseBalance[]>`

Get current balances for all currencies in your account.

##### `getTransactions(options?): Promise<WiseTransaction[]>`

Fetch transaction history with optional filters.

**Options:**
- `profileId?` - Profile ID (uses default from env if not provided)
- `accountId?` - Specific account ID
- `currency?` - Filter by currency code
- `intervalStart?` - Start date
- `intervalEnd?` - End date
- `limit?` - Maximum number of transactions (default: 100)
- `status?` - Transaction status filter
- `type?` - Transaction type filter

##### `getActivities(profileId?, limit?, intervalStart?, intervalEnd?): Promise<WiseTransaction[]>`

Fetch card payment activities (business account feature).

##### `searchTransactions(options): Promise<WiseTransaction[]>`

Search transactions with advanced filtering.

**Options:**
- `query?` - Text search in description/reference
- `minAmount?` - Minimum transaction amount
- `maxAmount?` - Maximum transaction amount
- `currency?` - Filter by currency
- `category?` - Filter by category
- `intervalStart?` - Start date
- `intervalEnd?` - End date
- `limit?` - Maximum results

##### `getRecipients(profileId?: number): Promise<WiseRecipient[]>`

Get list of saved transfer recipients.

##### `createQuote(options): Promise<WiseQuote>`

Create a currency conversion quote.

**Options:**
- `sourceCurrency` - Source currency code
- `targetCurrency` - Target currency code
- `sourceAmount?` - Amount to convert (either this or targetAmount required)
- `targetAmount?` - Amount to receive (either this or sourceAmount required)

##### `getExchangeRates(source: string, target: string): Promise<{...}>`

Get current exchange rate between two currencies.

##### `getStatements(profileId?, accountId?, options?): Promise<WiseStatement[]>`

Get account statements for download.

##### `getTransactionById(transferId: string): Promise<WiseTransaction>`

Fetch detailed information for a specific transaction.

##### `getSpendingSummary(options): Promise<{...}>`

Generate spending analytics and summaries.

**Options:**
- `intervalStart` - Start date (required)
- `intervalEnd` - End date (required)
- `currency?` - Filter by currency
- `groupBy?` - Group by 'category', 'month', or 'counterparty'

##### `getAccountDetails(): Promise<WiseAccountDetails>`

Get detailed account information for the authenticated user.

## Architecture

### Self-Contained Plugin Design

This plugin follows the OpenPets factory-based architecture pattern where all logic is contained within the plugin itself:

```
pets/wise/
├── index.ts              # Wise API client implementation
├── index.js              # Compiled JavaScript
├── package.json          # Plugin dependencies
├── tsconfig.json         # TypeScript configuration
├── .env.example          # Configuration template
├── commands.json         # Tool definitions
├── opencode.json         # OpenCode configuration
└── README.md            # This file
```

### Key Design Principles

1. **Self-Sufficient**: No dependencies on `src/utils/` - everything needed is in the plugin
2. **Type-Safe**: Full TypeScript interfaces for all API responses
3. **Environment-Aware**: Supports both sandbox and production environments
4. **Error Handling**: Graceful error handling with detailed error messages
5. **Flexible Querying**: Support for date ranges, filtering, searching, and analytics
6. **Default Profile**: Can set `WISE_PROFILE_ID` to avoid passing profileId to every call

### Migration from Utils

This plugin was previously located in `src/utils/wise/`. It has been migrated to be fully self-contained following the OpenPets architecture pattern:

- ✅ Core logic moved from `src/utils/wise/index.ts` to `pets/wise/index.ts`
- ✅ Dependencies added to plugin's `package.json`
- ✅ Plugin is now independent and can be used without external utilities

## Dependencies

- `dotenv` - Environment variable management

## Getting Started with Wise

1. **Sign up for Wise**: Visit [wise.com](https://wise.com) and create an account
2. **Get API credentials**: Navigate to your account settings → Integrations and tools → API tokens
   - Direct link: https://wise.com/your-account/integrations-and-tools/api-tokens
3. **Create an API token**: Follow the instructions to generate a new API token
4. **Get your profile ID**: Use `getProfiles()` to find your profile ID, then set it as `WISE_PROFILE_ID`
5. **Use this plugin**: Once configured, use this plugin to fetch transaction data and manage transfers

## Sandbox vs Production

The plugin automatically switches between sandbox and production based on the `WISE_SANDBOX` environment variable:

- **Sandbox**: `https://api.sandbox.transferwise.tech`
- **Production**: `https://api.wise.com` (default)

## Transaction Format

Transactions are normalized to a consistent format:

```typescript
{
  id: string              // Unique transaction ID
  date: Date             // Transaction date
  description: string    // Transaction description
  amount: number         // Transaction amount (positive or negative)
  currency: string       // Currency code (e.g., 'USD', 'EUR', 'GBP')
  accountType: 'wise' | 'wise-business'  // Account type
  category: string       // Transaction category
  reference?: string     // Payment reference
  counterparty?: string  // Recipient or sender name
  fees?: number         // Transaction fees (if applicable)
  status?: string       // Transaction status
  type?: string         // Transaction type
  sourceCurrency?: string  // Source currency for conversions
  targetCurrency?: string  // Target currency for conversions
  rate?: number         // Exchange rate for conversions
}
```

## Error Handling

The plugin includes robust error handling:

- Connection errors are caught and logged
- Invalid profiles or accounts throw descriptive errors
- Missing API tokens provide setup instructions
- All errors include helpful error messages

## Rate Limits

Wise API has rate limits that vary by endpoint. The plugin handles pagination automatically but you should be aware of:

- Personal accounts: Generally more lenient rate limits
- Business accounts: Higher limits, especially for transactions API
- Consider caching results when appropriate

## Security Notes

1. **Never commit your API token**: Always use environment variables
2. **Use sandbox for testing**: Test with sandbox tokens before using production
3. **Rotate tokens regularly**: Generate new API tokens periodically
4. **Restrict token permissions**: Use minimal required permissions when creating tokens

## License

MIT

## Author

OpenPets