@rozoai/intent-common 0.0.28-beta.1 → 0.0.28-beta.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,275 @@
1
+ # API Client Utility
2
+
3
+ A clean, flexible TypeScript utility for handling API requests to the RozoAI API service.
4
+
5
+ ## Overview
6
+
7
+ This utility provides a modular approach to API requests with:
8
+
9
+ - A base client for core HTTP operations
10
+ - Endpoint-specific modules for domain operations
11
+ - TypeScript interfaces for type safety
12
+ - Configuration management for API URLs and tokens
13
+ - Pre-configured defaults for RozoAI API
14
+
15
+ ## Default Configuration
16
+
17
+ The API client comes pre-configured with RozoAI production settings:
18
+
19
+ ```typescript
20
+ import { ROZO_API_URL, ROZO_API_TOKEN } from "@rozoai/intent-common";
21
+
22
+ console.log(ROZO_API_URL); // "https://intentapiv2.rozo.ai/functions/v1"
23
+ console.log(ROZO_API_TOKEN); // Pre-configured production token
24
+ ```
25
+
26
+ These defaults are automatically used by the API client, so you can start making requests immediately without any configuration.
27
+
28
+ ## Structure
29
+
30
+ ```bash
31
+ api/
32
+ ├── base.ts # Core API client functionality
33
+ ├── index.ts # Re-exports all API modules
34
+ ├── payment.ts # Payment-specific endpoints
35
+ └── README.md # Documentation
36
+ ```
37
+
38
+ ## Base API Client
39
+
40
+ The base client (`base.ts`) provides the foundation for all API requests:
41
+
42
+ ```typescript
43
+ import { apiClient, setApiConfig } from "@rozoai/intent-common";
44
+
45
+ // Configure the API client (optional, uses defaults if not set)
46
+ setApiConfig({
47
+ baseUrl: "https://intentapiv2.rozo.ai/functions/v1",
48
+ apiToken: "your-api-token",
49
+ });
50
+
51
+ // Make a GET request
52
+ const response = await apiClient.get("/some-endpoint");
53
+
54
+ // Make a POST request with data
55
+ const response = await apiClient.post("/some-endpoint", { data: "value" });
56
+
57
+ // Make a request with custom headers
58
+ const response = await apiClient.get("/some-endpoint", {
59
+ headers: { "Custom-Header": "value" },
60
+ });
61
+
62
+ // Make a request with query parameters
63
+ const response = await apiClient.get("/some-endpoint", {
64
+ params: { filter: "active", sort: "desc" },
65
+ });
66
+ ```
67
+
68
+ ## Using Payment API
69
+
70
+ The payment module provides typed functions for payment operations:
71
+
72
+ ```typescript
73
+ import {
74
+ createRozoPayment,
75
+ getRozoPayment,
76
+ createRozoPaymentRequest,
77
+ } from "@rozoai/intent-common";
78
+
79
+ // Create a payment
80
+ const handleSubmitPayment = async () => {
81
+ const paymentData = createRozoPaymentRequest({
82
+ appId: "your-app-id",
83
+ display: {
84
+ intent: "Pay for product",
85
+ paymentValue: "100.00",
86
+ currency: "USD",
87
+ },
88
+ destination: {
89
+ chainId: "8453",
90
+ amountUnits: "100000000",
91
+ tokenSymbol: "USDC",
92
+ tokenAddress: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
93
+ },
94
+ });
95
+
96
+ const response = await createRozoPayment(paymentData);
97
+
98
+ if (response.data) {
99
+ console.log("Payment created:", response.data.id);
100
+ } else if (response.error) {
101
+ console.error("Error creating payment:", response.error.message);
102
+ }
103
+ };
104
+
105
+ // Get payment details
106
+ const fetchPaymentDetails = async (paymentId: string) => {
107
+ const response = await getRozoPayment(paymentId);
108
+
109
+ if (response.data) {
110
+ console.log("Payment status:", response.data.status);
111
+ }
112
+ };
113
+ ```
114
+
115
+ ## React Hooks
116
+
117
+ React hooks for these APIs are available in the `@rozoai/intent-pay` package:
118
+
119
+ ```typescript
120
+ // In @rozoai/intent-pay
121
+ import {
122
+ useCreateRozoPayment,
123
+ useRozoPayment,
124
+ useRozoPayments
125
+ } from '@rozoai/intent-pay';
126
+
127
+ // Use in React components
128
+ const PaymentForm = () => {
129
+ const [paymentState, submitPayment] = useCreateRozoPayment();
130
+
131
+ const handleSubmit = (formData) => {
132
+ submitPayment({
133
+ appId: 'your-app-id',
134
+ display: { ... },
135
+ destination: { ... }
136
+ });
137
+ };
138
+
139
+ if (paymentState.isLoading) return <div>Processing...</div>;
140
+ if (paymentState.isError) return <div>Error: {paymentState.error?.message}</div>;
141
+ if (paymentState.isSuccess) return <div>Success! ID: {paymentState.data?.id}</div>;
142
+
143
+ return <FormComponent onSubmit={handleSubmit} />;
144
+ };
145
+ ```
146
+
147
+ ## Error Handling
148
+
149
+ All API responses include standardized error handling:
150
+
151
+ ```typescript
152
+ const response = await createRozoPayment(data);
153
+
154
+ if (response.error) {
155
+ // Handle error
156
+ console.error("API Error:", response.error.message);
157
+ return;
158
+ }
159
+
160
+ // Process successful response
161
+ const paymentData = response.data;
162
+ ```
163
+
164
+ ## TypeScript Integration
165
+
166
+ All functions are fully typed:
167
+
168
+ ```typescript
169
+ import { PaymentResponseData, ApiResponse } from "@rozoai/intent-common";
170
+
171
+ const response: ApiResponse<PaymentResponseData> = await getRozoPayment(
172
+ paymentId
173
+ );
174
+ // response.data will be typed as PaymentResponseData | null
175
+ ```
176
+
177
+ ## Configuration
178
+
179
+ ### Using Default Configuration
180
+
181
+ The API client is pre-configured with production RozoAI settings, so you can use it immediately:
182
+
183
+ ```typescript
184
+ import { createRozoPayment } from "@rozoai/intent-common";
185
+
186
+ // Works out of the box with default configuration
187
+ const response = await createRozoPayment({
188
+ appId: "your-app-id",
189
+ display: { intent: "Payment", paymentValue: "10.00", currency: "USD" },
190
+ destination: {
191
+ chainId: "8453",
192
+ amountUnits: "10000000",
193
+ tokenSymbol: "USDC",
194
+ },
195
+ });
196
+ ```
197
+
198
+ ### Customizing Configuration
199
+
200
+ For testing, staging, or custom environments, you can override the defaults:
201
+
202
+ ```typescript
203
+ import {
204
+ setApiConfig,
205
+ getApiConfig,
206
+ ROZO_API_URL,
207
+ ROZO_API_TOKEN,
208
+ } from "@rozoai/intent-common";
209
+
210
+ // Override for staging environment
211
+ setApiConfig({
212
+ baseUrl: "https://staging-api.rozo.ai/v1",
213
+ apiToken: "your-staging-token",
214
+ });
215
+
216
+ // Or reset to production defaults
217
+ setApiConfig({
218
+ baseUrl: ROZO_API_URL,
219
+ apiToken: ROZO_API_TOKEN,
220
+ });
221
+
222
+ // Get current configuration
223
+ const config = getApiConfig();
224
+ console.log(config.baseUrl, config.apiToken);
225
+ ```
226
+
227
+ ### Configuration in Different Environments
228
+
229
+ **Production (Default):**
230
+
231
+ ```typescript
232
+ // No configuration needed - uses ROZO_API_URL and ROZO_API_TOKEN automatically
233
+ import { createRozoPayment } from "@rozoai/intent-common";
234
+ const response = await createRozoPayment(data);
235
+ ```
236
+
237
+ **Staging:**
238
+
239
+ ```typescript
240
+ import { setApiConfig } from "@rozoai/intent-common";
241
+
242
+ setApiConfig({
243
+ baseUrl: "https://staging.intentapi.rozo.ai/v1",
244
+ apiToken: process.env.STAGING_API_TOKEN,
245
+ });
246
+ ```
247
+
248
+ **Development/Testing:**
249
+
250
+ ```typescript
251
+ import { setApiConfig } from "@rozoai/intent-common";
252
+
253
+ setApiConfig({
254
+ baseUrl: "http://localhost:3000/api",
255
+ apiToken: "dev_token",
256
+ });
257
+ ```
258
+
259
+ ## Available Payment Functions
260
+
261
+ - `createRozoPayment(paymentData)` - Create a new payment
262
+ - `getRozoPayment(paymentId)` - Get payment by ID
263
+ - `getRozoPaymentByExternalId(externalId)` - Get payment by external ID
264
+ - `updateRozoPayment(paymentId, paymentData)` - Update a payment
265
+ - `cancelRozoPayment(paymentId)` - Cancel a payment
266
+ - `listRozoPayments(params?)` - List all payments with optional filters
267
+ - `createRozoPaymentRequest(options)` - Create a payment request payload
268
+
269
+ ## Best Practices
270
+
271
+ - Configure the API client once at app initialization
272
+ - Leverage TypeScript interfaces for type safety
273
+ - Handle loading, error, and success states properly
274
+ - Use the React hooks (from @rozoai/intent-pay) when working in React components
275
+ - Implement proper error handling for all API calls
@@ -0,0 +1,215 @@
1
+ /**
2
+ * RozoAI API Configuration Constants
3
+ */
4
+ export const ROZO_API_URL = "https://intentapiv2.rozo.ai/functions/v1";
5
+ export const ROZO_API_TOKEN =
6
+ "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImZ4Y3Zmb2xobmNtdXZmYXp1cXViIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NTI4Mzg2NjYsImV4cCI6MjA2ODQxNDY2Nn0.B4dV5y_-zCMKSNm3_qyCbAvCPJmoOGv_xB783LfAVUA";
7
+
8
+ // HTTP methods type
9
+ export type HttpMethod = "GET" | "POST" | "PUT" | "DELETE" | "PATCH";
10
+
11
+ // Request options type
12
+ export interface RequestOptions {
13
+ method?: HttpMethod;
14
+ headers?: Record<string, string>;
15
+ body?: any;
16
+ params?: Record<string, string>;
17
+ signal?: AbortSignal;
18
+ }
19
+
20
+ // Response type with generic data
21
+ export interface ApiResponse<T = any> {
22
+ data: T | null;
23
+ error: Error | null;
24
+ status: number | null;
25
+ }
26
+
27
+ // Request state for hooks (used in connectkit)
28
+ export interface RequestState<T = any> extends ApiResponse<T> {
29
+ isLoading: boolean;
30
+ isError: boolean;
31
+ isSuccess: boolean;
32
+ }
33
+
34
+ /**
35
+ * API Configuration
36
+ */
37
+ export interface ApiConfig {
38
+ baseUrl: string;
39
+ apiToken: string;
40
+ }
41
+
42
+ // Default configuration (can be overridden via setApiConfig)
43
+ let apiConfig: ApiConfig = {
44
+ baseUrl: ROZO_API_URL,
45
+ apiToken: ROZO_API_TOKEN,
46
+ };
47
+
48
+ /**
49
+ * Set API configuration
50
+ * @param config - API configuration
51
+ */
52
+ export const setApiConfig = (config: Partial<ApiConfig>) => {
53
+ apiConfig = { ...apiConfig, ...config };
54
+ };
55
+
56
+ /**
57
+ * Get current API configuration
58
+ * @returns Current API configuration
59
+ */
60
+ export const getApiConfig = (): ApiConfig => {
61
+ return apiConfig;
62
+ };
63
+
64
+ /**
65
+ * Creates a URL with query parameters
66
+ * @param url - Base URL
67
+ * @param params - Query parameters
68
+ * @returns Full URL with query parameters
69
+ */
70
+ const createUrl = (url: string, params?: Record<string, string>): string => {
71
+ const fullUrl = url.startsWith("/")
72
+ ? `${apiConfig.baseUrl}${url}`
73
+ : `${apiConfig.baseUrl}/${url}`;
74
+
75
+ if (!params) return fullUrl;
76
+
77
+ const queryParams = new URLSearchParams();
78
+ Object.entries(params).forEach(([key, value]) => {
79
+ if (value !== undefined && value !== null) {
80
+ queryParams.append(key, value);
81
+ }
82
+ });
83
+
84
+ const queryString = queryParams.toString();
85
+ return queryString ? `${fullUrl}?${queryString}` : fullUrl;
86
+ };
87
+
88
+ /**
89
+ * Core fetch function for making API requests
90
+ * @param url - API endpoint path
91
+ * @param options - Request options
92
+ * @returns Promise with response data
93
+ */
94
+ export const fetchApi = async <T = any>(
95
+ url: string,
96
+ options: RequestOptions = {}
97
+ ): Promise<ApiResponse<T>> => {
98
+ const { method = "GET", headers = {}, body, params, signal } = options;
99
+
100
+ try {
101
+ const fullUrl = createUrl(url, params);
102
+
103
+ const requestHeaders: Record<string, string> = {
104
+ "Content-Type": "application/json",
105
+ ...headers,
106
+ Authorization: `Bearer ${apiConfig.apiToken}`,
107
+ };
108
+
109
+ const requestOptions: {
110
+ method: string;
111
+ headers: Record<string, string>;
112
+ signal?: AbortSignal;
113
+ body?: string;
114
+ } = {
115
+ method,
116
+ headers: requestHeaders,
117
+ signal,
118
+ };
119
+
120
+ if (body && method !== "GET") {
121
+ requestOptions.body = JSON.stringify(body);
122
+ }
123
+
124
+ const response = await fetch(fullUrl, requestOptions);
125
+ const status = response.status;
126
+
127
+ // Handle non-JSON responses
128
+ const contentType = response.headers.get("content-type");
129
+ let data: T | null = null;
130
+
131
+ if (contentType && contentType.includes("application/json")) {
132
+ data = (await response.json()) as T;
133
+ } else if (contentType && contentType.includes("text/")) {
134
+ data = (await response.text()) as unknown as T;
135
+ }
136
+
137
+ if (!response.ok) {
138
+ throw new Error(data ? JSON.stringify(data) : response.statusText);
139
+ }
140
+
141
+ return { data, error: null, status };
142
+ } catch (error) {
143
+ return {
144
+ data: null,
145
+ error: error instanceof Error ? error : new Error(String(error)),
146
+ status: null,
147
+ };
148
+ }
149
+ };
150
+
151
+ /**
152
+ * API client with methods for different HTTP verbs
153
+ */
154
+ export const apiClient = {
155
+ /**
156
+ * GET request
157
+ * @param url - API endpoint path
158
+ * @param options - Request options
159
+ * @returns Promise with response data
160
+ */
161
+ get: <T = any>(
162
+ url: string,
163
+ options: Omit<RequestOptions, "method" | "body"> = {}
164
+ ) => fetchApi<T>(url, { ...options, method: "GET" }),
165
+
166
+ /**
167
+ * POST request
168
+ * @param url - API endpoint path
169
+ * @param body - Request body
170
+ * @param options - Additional request options
171
+ * @returns Promise with response data
172
+ */
173
+ post: <T = any>(
174
+ url: string,
175
+ body: any,
176
+ options: Omit<RequestOptions, "method" | "body"> = {}
177
+ ) => fetchApi<T>(url, { ...options, method: "POST", body }),
178
+
179
+ /**
180
+ * PUT request
181
+ * @param url - API endpoint path
182
+ * @param body - Request body
183
+ * @param options - Additional request options
184
+ * @returns Promise with response data
185
+ */
186
+ put: <T = any>(
187
+ url: string,
188
+ body: any,
189
+ options: Omit<RequestOptions, "method" | "body"> = {}
190
+ ) => fetchApi<T>(url, { ...options, method: "PUT", body }),
191
+
192
+ /**
193
+ * PATCH request
194
+ * @param url - API endpoint path
195
+ * @param body - Request body
196
+ * @param options - Additional request options
197
+ * @returns Promise with response data
198
+ */
199
+ patch: <T = any>(
200
+ url: string,
201
+ body: any,
202
+ options: Omit<RequestOptions, "method" | "body"> = {}
203
+ ) => fetchApi<T>(url, { ...options, method: "PATCH", body }),
204
+
205
+ /**
206
+ * DELETE request
207
+ * @param url - API endpoint path
208
+ * @param options - Request options
209
+ * @returns Promise with response data
210
+ */
211
+ delete: <T = any>(
212
+ url: string,
213
+ options: Omit<RequestOptions, "method"> = {}
214
+ ) => fetchApi<T>(url, { ...options, method: "DELETE" }),
215
+ };
@@ -0,0 +1,14 @@
1
+ /**
2
+ * API client utilities for RozoAI Intent Pay
3
+ *
4
+ * This module provides core API client functionality for making HTTP requests
5
+ * to the RozoAI payment API. It includes:
6
+ * - Base API client with support for GET, POST, PUT, PATCH, DELETE
7
+ * - Payment API functions and types
8
+ * - Type-safe interfaces for requests and responses
9
+ *
10
+ * Note: React hooks for these APIs are available in the @rozoai/intent-pay package.
11
+ */
12
+
13
+ export * from "./base";
14
+ export * from "./payment";
@@ -0,0 +1,112 @@
1
+ import { apiClient, ApiResponse } from "./base";
2
+
3
+ /**
4
+ * Payment display information
5
+ */
6
+ export interface PaymentDisplay {
7
+ intent: string;
8
+ paymentValue: string;
9
+ currency: string;
10
+ }
11
+
12
+ /**
13
+ * Payment destination information
14
+ */
15
+ export interface PaymentDestination {
16
+ destinationAddress?: string;
17
+ chainId: string;
18
+ amountUnits: string;
19
+ tokenSymbol: string;
20
+ tokenAddress?: string;
21
+ txHash?: string | null;
22
+ }
23
+
24
+ /**
25
+ * Payment source information
26
+ */
27
+ export interface PaymentSource {
28
+ sourceAddress?: string;
29
+ [key: string]: unknown;
30
+ }
31
+
32
+ /**
33
+ * Payment request data type
34
+ */
35
+ export interface PaymentRequestData {
36
+ appId: string;
37
+ display: PaymentDisplay;
38
+ destination: PaymentDestination;
39
+ externalId?: string;
40
+ metadata?: Record<string, unknown>;
41
+ [key: string]: unknown;
42
+ }
43
+
44
+ /**
45
+ * Payment response data type
46
+ */
47
+ export interface PaymentResponseData {
48
+ id: string;
49
+ status: "payment_unpaid" | string;
50
+ createdAt: string;
51
+ display: {
52
+ intent: string;
53
+ currency: string;
54
+ paymentValue?: string;
55
+ };
56
+ source: PaymentSource | null;
57
+ destination: {
58
+ destinationAddress: string;
59
+ txHash: string | null;
60
+ chainId: string;
61
+ amountUnits: string;
62
+ tokenSymbol: string;
63
+ tokenAddress: string;
64
+ };
65
+ metadata: {
66
+ daimoOrderId?: string;
67
+ intent: string;
68
+ items: unknown[];
69
+ payer: Record<string, unknown>;
70
+ appId: string;
71
+ orderDate: string;
72
+ webhookUrl: string;
73
+ provider: string;
74
+ receivingAddress: string;
75
+ memo: string | null;
76
+ payinchainid: string;
77
+ payintokenaddress: string;
78
+ preferredChain: string;
79
+ preferredToken: string;
80
+ preferredTokenAddress: string;
81
+ source_tx_hash?: string;
82
+ [key: string]: unknown;
83
+ };
84
+ url: string;
85
+ [key: string]: unknown;
86
+ }
87
+
88
+ /**
89
+ * Creates a new payment
90
+ * @param paymentData - Payment data to send
91
+ * @returns Promise with payment response
92
+ */
93
+ export const createRozoPayment = (
94
+ paymentData: PaymentRequestData
95
+ ): Promise<ApiResponse<PaymentResponseData>> => {
96
+ return apiClient.post<PaymentResponseData>("/payment-api", paymentData);
97
+ };
98
+
99
+ /**
100
+ * Gets payment details by ID
101
+ * @param paymentId - Payment ID
102
+ * @returns Promise with payment response
103
+ */
104
+ export const getRozoPayment = (
105
+ paymentId: string
106
+ ): Promise<ApiResponse<PaymentResponseData>> => {
107
+ const isMugglePay = paymentId.includes("mugglepay_order");
108
+ const endpoint = isMugglePay
109
+ ? `payment-api/${paymentId}`
110
+ : `payment/id/${paymentId}`;
111
+ return apiClient.get<PaymentResponseData>(endpoint);
112
+ };