@paymanai/payman-ts v1.0.12
Payman SDK TypeScript
This SDK provides a simple way to interact with the Payman AI Platform's API using client credentials authentication. The SDK automatically handles token management, including fetching and refreshing access tokens.
Installation
npm install @paymanai/payman-tsEnvironment Setup
Before running the SDK or tests, you need to set up your environment variables. Create a .env file in the root directory with the following variables:
PAYMAN_CLIENT_ID=your-client-id
PAYMAN_CLIENT_SECRET=your-client-secretThese credentials are required for both running the SDK and executing tests.
Testing
The SDK uses Jest for testing. To run the tests:
- Make sure you have set up your
.envfile with the required credentials - Install dependencies:
npm install- Run the tests:
npm testThe test suite will verify the SDK's functionality, including authentication, API interactions, and response handling.
Usage
Initialization
The SDK provides three ways to initialize the client:
- Using client credentials (recommended for server-side applications):
import { PaymanClient } from '@paymanai/payman-ts';
const payman = PaymanClient.withCredentials({
clientId: "your-client-id",
clientSecret: "your-client-secret",
});- Using an authorization code (for OAuth flow):
const payman = PaymanClient.withAuthCode({
clientId: "your-client-id",
environment: "TEST"
}, "your-auth-code");- Using an access token (when you already have a token):
const payman = PaymanClient.withToken(
"your-client-id",
{
accessToken: "your-access-token",
expiresIn: 3600 // token expiry in seconds
},
);Making Requests
- Get a formatted response (recommended for most use cases):
const response = await payman.ask("What's the weather?");
console.log(response);- Get a raw response (when you need the full JSON-RPC response):
const rawResponse = await payman.ask("What's the weather?", {
outputFormat: 'json'
});
console.log(rawResponse);- Streaming request with formatted responses:
await payman.ask("What's the weather?", {
onMessage: (response) => {
console.log("Formatted response:", response);
},
outputFormat: 'markdown'
});- Streaming request with raw responses:
await payman.ask("What's the weather?", {
onMessage: (response) => {
console.log("Raw response:", response);
},
outputFormat: 'json'
});- Start a new session with metadata:
const response = await payman.ask("Hello!", {
newSession: true,
metadata: { source: "web-app" }
});Session Management
The SDK automatically manages sessions for you. Each client instance maintains a session ID that persists across requests. You can start a new session at any time by setting newSession: true in the options.
The SDK also handles OAuth token management automatically:
- Fetches an access token during initialization
- Refreshes the token before it expires (within 60 seconds of expiry)
- Handles token management transparently
Streaming Responses
When using streaming responses with the onMessage callback, you'll receive updates in real-time as they become available. This is useful for:
- Long-running tasks
- Real-time updates
- Progress monitoring
- Handling artifacts as they become available
The streaming response can include different types of events:
- Status Updates:
await client.ask("List all payees", {
onMessage: (response) => {
if ('status' in response) {
console.log(`Task status: ${response.status}`);
console.log(`Is final: ${response.isFinal}`);
}
}
});- Artifact Updates:
await client.ask("List all payees", {
onMessage: (response) => {
if ('artifacts' in response) {
console.log(`New artifact: ${response.artifacts[response.artifacts.length - 1]}`);
}
}
});Using Metadata
The SDK supports various types of metadata that can be attached to requests:
- Request-level metadata:
await client.ask("Pay Tyllen 50$?", {
metadata: {
source: "mobile-app",
userId: "user123",
requestId: "req456"
}
});- Message-level metadata:
await client.ask("Create a new payee with the email tyllen@paymanai.com", {
messageMetadata: {
priority: "high",
category: "payee creation"
}
});- Part-level metadata:
await client.ask("List all wallets", {
partMetadata: {
currency: "USD",
format: "text"
}
});API Reference
PaymanClient
Static Methods
withCredentials(config: PaymanConfig): PaymanClient- Creates a client using client credentials
config: Configuration object containing clientId, clientSecret, and optional environment
withAuthCode(config: PaymanConfig, authCode: string): PaymanClient- Creates a client using an authorization code
config: Configuration object containing clientId, clientSecret, and optional environmentauthCode: Authorization code obtained via OAuth
withToken(clientId: string, tokenInfo: { accessToken: string; expiresIn: number }, environment?: 'TEST' | 'LIVE' | 'INTERNAL'): PaymanClient- Creates a client using an existing access token
clientId: Your Payman client IDtokenInfo: Object containing access token and its expiration timeenvironment: Optional environment to use (defaults to "LIVE")
Instance Methods
ask(text: string, options?: AskOptions, raw?: boolean): Promise<FormattedTaskResponse | TaskResponse>- Sends a message to the Payman AI Agent
text: The message or question to sendoptions: Optional parameters for the request
getAccessToken(): { accessToken: string; expiresIn: number } | undefined- Gets the current access token and its expiration information
- Returns undefined if no token is set
isAccessTokenExpired(): boolean- Checks if the current access token has expired
- Returns true if the token has expired or is about to expire within 60 seconds
Types
PaymanConfig{ clientId: string; clientSecret: string; environment?: 'TEST' | 'LIVE' | 'INTERNAL'; }AskOptions{ onMessage?: (response: FormattedTaskResponse | TaskResponse) => void; newSession?: boolean; outputFormat?: 'markdown' | 'json'; metadata?: Record<string, unknown>; partMetadata?: Record<string, unknown>; messageMetadata?: Record<string, unknown>; }
Response Types
FormattedTaskResponse{ status: 'completed' | 'failed' | 'in_progress'; isFinal: boolean; artifacts?: Array<{ type: string; content: unknown; metadata?: Record<string, unknown>; }>; error?: { code: number; message: string; }; }TaskResponse{ jsonrpc: '2.0'; id: string; result?: { status: 'completed' | 'failed' | 'in_progress'; isFinal: boolean; artifacts?: Array<{ type: string; content: unknown; metadata?: Record<string, unknown>; }>; }; error?: { code: number; message: string; data?: unknown; }; }
Events
TaskStatusUpdateEvent{ type: 'status_update'; status: 'completed' | 'failed' | 'in_progress'; isFinal: boolean; }TaskArtifactUpdateEvent{ type: 'artifact_update'; artifacts: Array<{ type: string; content: unknown; metadata?: Record<string, unknown>; }>; }
Error Handling
The SDK uses Axios for HTTP requests. All API calls will throw an error if the request fails. You can catch these errors and handle them appropriately:
try {
const response = await client.ask("What's the weather?");
} catch (error) {
if (error.response) {
// The request was made and the server responded with a status code
// that falls out of the range of 2xx
console.error(error.response.data);
console.error(error.response.status);
} else if (error.request) {
// The request was made but no response was received
console.error(error.request);
} else {
// Something happened in setting up the request that triggered an Error
console.error('Error', error.message);
}
}