@rozoai/intent-common 0.1.0-beta.2 → 0.1.0-beta.4

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.
@@ -1,104 +1,273 @@
1
- import { createPaymentBridgeConfig } from "../bridge";
1
+ import { createPaymentBridgeConfig } from "../bridge-utils";
2
+ import { getChainById } from "../chain";
3
+ import { getKnownToken } from "../token";
2
4
  import { apiClient, ApiResponse } from "./base";
3
- import { DisplayInfo } from "./new-payment";
4
5
 
5
6
  /**
6
- * Payment display information
7
+ * FeeType, Fee calculation type:
8
+ * - exactIn (default): Fee deducted from input, recipient receives amount - fee
9
+ * - exactOut: Fee added to input, recipient receives exact amount
7
10
  */
8
- export interface PaymentDisplay {
9
- intent: string;
10
- paymentValue: string;
11
- currency: string;
11
+ export enum FeeType {
12
+ ExactIn = "exactIn",
13
+ ExactOut = "exactOut",
12
14
  }
13
15
 
14
16
  /**
15
- * Payment destination information
17
+ * PaymentStatus, Payment status
16
18
  */
17
- export interface PaymentDestination {
18
- destinationAddress?: string;
19
- chainId: string;
20
- amountUnits: string;
21
- tokenSymbol: string;
19
+ export enum PaymentStatus {
20
+ PaymentBounced = "payment_bounced",
21
+ PaymentCompleted = "payment_completed",
22
+ PaymentExpired = "payment_expired",
23
+ PaymentPayinCompleted = "payment_payin_completed",
24
+ PaymentPayoutCompleted = "payment_payout_completed",
25
+ PaymentRefunded = "payment_refunded",
26
+ PaymentStarted = "payment_started",
27
+ PaymentUnpaid = "payment_unpaid",
28
+ }
29
+
30
+ /**
31
+ * PaymentErrorCode, Error code (only present when status is payment_bounced)
32
+ */
33
+ export enum PaymentErrorCode {
34
+ AmountTooHigh = "amountTooHigh",
35
+ AmountTooLow = "amountTooLow",
36
+ ChainUnavailable = "chainUnavailable",
37
+ InsufficientLiquidity = "insufficientLiquidity",
38
+ InvalidRecipient = "invalidRecipient",
39
+ MissingTrustline = "missingTrustline",
40
+ NetworkError = "networkError",
41
+ ProviderError = "providerError",
42
+ ServiceMaintenance = "serviceMaintenance",
43
+ }
44
+
45
+ /**
46
+ * DestinationRequest
47
+ */
48
+ export interface DestinationRequest {
49
+ /**
50
+ * Receive amount (required for type=exactOut).
51
+ * For exactIn, this field is omitted in request and calculated in response.
52
+ */
53
+ amount?: string;
54
+ chainId: number;
55
+ /**
56
+ * Final recipient's wallet address
57
+ */
58
+ receiverAddress: string;
59
+ /**
60
+ * Memo for Stellar/Solana destinations
61
+ */
62
+ receiverMemo?: string;
63
+ /**
64
+ * Override default token address
65
+ */
22
66
  tokenAddress?: string;
23
- txHash?: string | null;
67
+ tokenSymbol: string;
68
+ [property: string]: any;
24
69
  }
25
70
 
26
71
  /**
27
- * Payment source information
72
+ * DisplayInfo
28
73
  */
29
- export interface PaymentSource {
30
- sourceAddress?: string;
31
- [key: string]: unknown;
74
+ export interface DisplayInfo {
75
+ /**
76
+ * Display currency
77
+ */
78
+ currency: string;
79
+ /**
80
+ * Detailed description
81
+ */
82
+ description?: string;
83
+ /**
84
+ * Short title
85
+ */
86
+ title: string;
87
+ [property: string]: any;
32
88
  }
33
89
 
34
90
  /**
35
- * Payment request data type
91
+ * SourceRequest
36
92
  */
37
- export interface PaymentRequestData {
93
+ export interface SourceRequest {
94
+ /**
95
+ * Pay-in amount (required for type=exactIn).
96
+ * For exactOut, this field is omitted in request and calculated in response.
97
+ */
98
+ amount?: string;
99
+ chainId: number;
100
+ /**
101
+ * Override default token address
102
+ */
103
+ tokenAddress?: string;
104
+ tokenSymbol: string;
105
+ [property: string]: any;
106
+ }
107
+
108
+ /**
109
+ * PaymentRequest
110
+ */
111
+ export interface CreatePaymentRequest {
112
+ /**
113
+ * Your application ID
114
+ */
38
115
  appId: string;
39
- display: PaymentDisplay;
40
- destination: PaymentDestination;
41
- externalId?: string;
42
- metadata?: Record<string, unknown>;
43
- [key: string]: unknown;
116
+ destination: DestinationRequest;
117
+ display: DisplayInfo;
118
+ /**
119
+ * Custom metadata (max 4 KB recommended)
120
+ */
121
+ metadata?: { [key: string]: any };
122
+ /**
123
+ * Your order reference ID (for idempotency)
124
+ */
125
+ orderId?: string;
126
+ source: SourceRequest;
127
+ type?: FeeType;
128
+ /**
129
+ * Secret for HMAC-SHA256 signature verification.
130
+ * If not provided, a unique secret is auto-generated.
131
+ * The secret is returned in the response for you to store and use for verification.
132
+ */
133
+ webhookSecret?: string;
134
+ /**
135
+ * URL to receive payment status updates
136
+ */
137
+ webhookUrl?: string;
138
+ [property: string]: any;
44
139
  }
45
140
 
46
141
  /**
47
- * Payment response data type
142
+ * DestinationResponse
48
143
  */
49
- export interface PaymentResponseData {
144
+ export interface DestinationResponse {
145
+ /**
146
+ * Amount to be sent to recipient
147
+ */
148
+ amount?: string;
149
+ chainId?: number;
150
+ /**
151
+ * Withdrawal confirmation time
152
+ */
153
+ confirmedAt?: Date;
154
+ /**
155
+ * Final recipient's wallet
156
+ */
157
+ receiverAddress?: string;
158
+ /**
159
+ * Memo for Stellar/Solana
160
+ */
161
+ receiverMemo?: string;
162
+ /**
163
+ * Token contract address
164
+ */
165
+ tokenAddress?: string;
166
+ tokenSymbol?: string;
167
+ /**
168
+ * Withdrawal transaction hash
169
+ */
170
+ txHash?: string;
171
+ [property: string]: any;
172
+ }
173
+
174
+ /**
175
+ * SourceResponse
176
+ */
177
+ export interface SourceResponse {
178
+ /**
179
+ * Amount payer must send
180
+ */
181
+ amount?: string;
182
+ /**
183
+ * Actual amount received
184
+ */
185
+ amountReceived?: string;
186
+ chainId?: number;
187
+ /**
188
+ * Deposit confirmation time
189
+ */
190
+ confirmedAt?: Date;
191
+ /**
192
+ * Fee amount
193
+ */
194
+ fee?: string;
195
+ /**
196
+ * Deposit address (where payer sends funds)
197
+ */
198
+ receiverAddress?: string;
199
+ /**
200
+ * Memo for Stellar/Solana deposits
201
+ */
202
+ receiverMemo?: string;
203
+ /**
204
+ * Payer's wallet address (populated after deposit)
205
+ */
206
+ senderAddress?: string;
207
+ /**
208
+ * Token contract address
209
+ */
210
+ tokenAddress?: string;
211
+ tokenSymbol?: string;
212
+ /**
213
+ * Deposit transaction hash
214
+ */
215
+ txHash?: string;
216
+ [property: string]: any;
217
+ }
218
+
219
+ /**
220
+ * PaymentResponse
221
+ */
222
+ export interface PaymentResponse {
223
+ /**
224
+ * Your application ID
225
+ */
226
+ appId: string;
227
+ /**
228
+ * ISO 8601 timestamp
229
+ */
230
+ createdAt: Date;
231
+ destination: DestinationResponse;
232
+ display: DisplayInfo;
233
+ errorCode: PaymentErrorCode | null;
234
+ /**
235
+ * ISO 8601 timestamp (when payment expires)
236
+ */
237
+ expiresAt: Date;
238
+ /**
239
+ * Payment ID
240
+ */
50
241
  id: string;
51
- status: "payment_unpaid" | string;
52
- createdAt: string;
53
- updatedAt: string;
54
- expiresAt: string;
55
- display:
56
- | {
57
- intent: string;
58
- currency: string;
59
- paymentValue?: string;
60
- }
61
- | DisplayInfo;
62
- source: PaymentSource | null;
63
- destination: {
64
- destinationAddress: string;
65
- txHash: string | null;
66
- chainId: string;
67
- amountUnits: string;
68
- tokenSymbol: string;
69
- tokenAddress: string;
70
- };
71
- metadata: {
72
- daimoOrderId?: string;
73
- intent: string;
74
- items: unknown[];
75
- payer: Record<string, unknown>;
76
- appId: string;
77
- orderDate: string;
78
- webhookUrl: string;
79
- provider: string;
80
- receivingAddress: string;
81
- memo: string | null;
82
- payinchainid: string;
83
- payintokenaddress: string;
84
- preferredChain: string;
85
- preferredToken: string;
86
- preferredTokenAddress: string;
87
- source_tx_hash?: string;
88
- [key: string]: unknown;
89
- };
90
- url: string;
91
- [key: string]: unknown;
242
+ metadata: { [key: string]: any } | null;
243
+ /**
244
+ * Your order reference ID
245
+ */
246
+ orderId: string | null;
247
+ source: SourceResponse;
248
+ status: PaymentStatus;
249
+ type: FeeType;
250
+ /**
251
+ * ISO 8601 timestamp
252
+ */
253
+ updatedAt: Date;
254
+ /**
255
+ * Secret for webhook signature verification.
256
+ * Only present when webhookUrl was provided in the request.
257
+ * Store this securely to verify incoming webhook signatures.
258
+ */
259
+ webhookSecret: string | null;
260
+ [property: string]: any;
92
261
  }
93
262
 
94
263
  /**
95
- * Simplified interface for creating a payment bridge
264
+ * Parameters for creating a new payment using the new backend interface
96
265
  */
97
- export interface CreatePaymentBridgeParams {
266
+ export interface CreateNewPaymentParams {
98
267
  /** App ID for authentication */
99
268
  appId: string;
100
269
  // Destination (where funds will be received)
101
- /** Destination chain ID (e.g., 8453 for Base, 900 for Solana, 10001 for Stellar) */
270
+ /** Destination chain ID (e.g., 8453 for Base, 900 for Solana, 1500 for Stellar) */
102
271
  toChain: number;
103
272
  /** Destination token address */
104
273
  toToken: string;
@@ -115,111 +284,53 @@ export interface CreatePaymentBridgeParams {
115
284
  /** Amount in human-readable units (e.g., "1" for 1 USDC, "0.5" for half a USDC) */
116
285
  toUnits?: string;
117
286
 
118
- // Optional metadata
287
+ // Optional fields
119
288
  /** Additional metadata to include */
120
289
  metadata?: Record<string, unknown>;
290
+ /** Display title for the payment */
291
+ title?: string;
292
+ /** Display description for the payment */
293
+ description?: string;
294
+ /** Order reference ID (for idempotency) */
295
+ orderId?: string;
296
+ /** Fee calculation type (exactIn or exactOut) */
297
+ type?: FeeType;
298
+ /** Webhook URL to receive payment status updates */
299
+ webhookUrl?: string;
300
+ /** Secret for HMAC-SHA256 signature verification */
301
+ webhookSecret?: string;
302
+ /** Memo for Stellar/Solana destinations */
303
+ receiverMemo?: string;
121
304
  }
122
305
 
123
306
  /**
124
- * Gets payment details by ID
125
- * @param paymentId - Payment ID
126
- * @returns Promise with payment response
127
- */
128
- export const getRozoPayment = (
129
- paymentId: string
130
- ): Promise<ApiResponse<PaymentResponseData>> => {
131
- const isMugglePay = paymentId.includes("mugglepay_order");
132
- const endpoint = isMugglePay
133
- ? `payment-api/${paymentId}`
134
- : `payment/id/${paymentId}`;
135
- return apiClient.get<PaymentResponseData>(endpoint);
136
- };
137
-
138
- /**
139
- * Creates a payment bridge configuration and initiates a Rozo payment
307
+ * Creates a payment using the new backend interface
140
308
  *
141
- * This function combines the payment bridge configuration logic with payment creation,
142
- * handling cross-chain payment routing and metadata merging. It provides a simplified
143
- * API that doesn't require understanding internal types like WalletPaymentOption.
309
+ * This function creates a payment using the new backend API structure with
310
+ * separate source and destination objects, enum-based chain IDs and token symbols.
144
311
  *
145
- * @param params - Payment bridge creation parameters
312
+ * @param params - Payment creation parameters
146
313
  * @returns Promise resolving to the payment response data
147
314
  * @throws Error if payment creation fails or required parameters are missing
148
315
  *
149
316
  * @example
150
317
  * ```typescript
151
318
  * // Simple same-chain payment
152
- * const payment = await createPaymentBridge({
319
+ * const payment = await createPayment({
153
320
  * toChain: 8453, // Base
154
321
  * toToken: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", // Base USDC
155
322
  * toAddress: "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",
156
- * preferredChainId: 8453, // User pays from Base
157
- * preferredToken: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", // Base USDC
323
+ * preferredChain: 8453, // User pays from Base
324
+ * preferredTokenAddress: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", // Base USDC
158
325
  * toUnits: "1", // 1 USDC
159
326
  * appId: "my-app-id",
160
- * intent: "Pay",
161
- * });
162
- * ```
163
- *
164
- * @example
165
- * ```typescript
166
- * // Cross-chain payment: Polygon to Base
167
- * const payment = await createPaymentBridge({
168
- * toChain: 8453, // Base (destination)
169
- * toToken: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", // Base USDC
170
- * toAddress: "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",
171
- * preferredChainId: 137, // Polygon (user pays from)
172
- * preferredToken: "0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174", // Polygon USDC
173
- * toUnits: "1",
174
- * appId: "my-app-id",
175
- * });
176
- * ```
177
- *
178
- * @example
179
- * ```typescript
180
- * // Payment to Solana address (payout → Solana)
181
- * const payment = await createPaymentBridge({
182
- * toChain: 900, // Solana
183
- * toToken: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", // Solana USDC
184
- * toAddress: "7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgAsU", // Solana address
185
- * preferredChainId: 8453, // User pays from Base
186
- * preferredToken: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", // Base USDC
187
- * toUnits: "1",
188
- * appId: "my-app-id",
189
- * });
190
- * ```
191
- *
192
- * @example
193
- * ```typescript
194
- * // Payment paid in from Stellar account
195
- * const payment = await createPaymentBridge({
196
- * toChain: 8453, // Payout on Base
197
- * toToken: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", // Base USDC
198
- * toAddress: "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb", // EVM address
199
- * preferredChainId: 1500, // Pay in from Stellar
200
- * preferredToken: "USDC:GA5ZSEJYB37JRC5AVCIA5MOP4RHTM335X2KGX3IHOJAPP5RE34K4KZVN", // Stellar USDC (token format: code:issuer)
201
- * toUnits: "10",
202
- * appId: "my-app-id",
203
- * });
204
- * ```
205
- *
206
- * @example
207
- * ```typescript
208
- * // Payment paying out to Stellar address (payout → Stellar)
209
- * const payment = await createPaymentBridge({
210
- * toChain: 1500, // Stellar
211
- * toToken: "USDC:GA5ZSEJYB37JRC5AVCIA5MOP4RHTM335X2KGX3IHOJAPP5RE34K4KZVN", // Stellar USDC (token format: code:issuer)
212
- * toAddress: "GA5ZSEPRY3STUGUUXZGHV5CDEQ2AJGEAAUUMSZK2QIPICFL2JVP4X6T4", // Stellar address
213
- * preferredChainId: 8453, // User pays from Base
214
- * preferredToken: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", // Base USDC
215
- * toUnits: "1",
216
- * appId: "my-app-id",
327
+ * title: "Payment",
217
328
  * });
218
329
  * ```
219
330
  */
220
- export async function createRozoPayment(
221
- params: CreatePaymentBridgeParams
222
- ): Promise<PaymentResponseData> {
331
+ export async function createPayment(
332
+ params: CreateNewPaymentParams
333
+ ): Promise<PaymentResponse> {
223
334
  const {
224
335
  toChain,
225
336
  toToken,
@@ -229,36 +340,76 @@ export async function createRozoPayment(
229
340
  toUnits,
230
341
  appId,
231
342
  metadata,
343
+ title,
344
+ description,
345
+ orderId,
346
+ type,
347
+ webhookUrl,
348
+ webhookSecret,
349
+ receiverMemo,
232
350
  } = params;
351
+
233
352
  // Create payment bridge configuration
234
- const { preferred, destination, isIntentPayment } = createPaymentBridgeConfig(
235
- {
236
- toChain,
237
- toToken,
238
- toAddress,
239
- toUnits: toUnits ?? "0",
240
- // Preferred payment method (what user will pay with)
241
- preferredChain,
242
- preferredTokenAddress,
243
- }
353
+ const { preferred, destination } = createPaymentBridgeConfig({
354
+ toChain,
355
+ toToken,
356
+ toAddress,
357
+ toUnits: toUnits ?? "0",
358
+ // Preferred payment method (what user will pay with)
359
+ preferredChain,
360
+ preferredTokenAddress,
361
+ });
362
+
363
+ const sourceChain = getChainById(Number(preferred.preferredChain));
364
+ const sourceToken = getKnownToken(
365
+ Number(preferred.preferredChain),
366
+ preferred.preferredTokenAddress
367
+ );
368
+ const destinationChain = getChainById(Number(destination.chainId));
369
+ const destinationToken = getKnownToken(
370
+ Number(destination.chainId),
371
+ destination.tokenAddress
244
372
  );
245
373
 
246
- // Build payment request data
247
- const paymentData: PaymentRequestData = {
374
+ if (!sourceToken || !destinationToken) {
375
+ throw new Error("Source or destination token not found");
376
+ }
377
+
378
+ // Build payment request data matching new backend interface
379
+ const paymentData: CreatePaymentRequest = {
248
380
  appId,
381
+ type: type ?? FeeType.ExactIn,
382
+ ...(orderId ? { orderId } : {}),
383
+ source: {
384
+ chainId: sourceChain.chainId,
385
+ tokenSymbol: sourceToken.symbol,
386
+ amount: destination.amountUnits, // Use same amount for source
387
+ ...(preferred.preferredTokenAddress
388
+ ? { tokenAddress: preferred.preferredTokenAddress }
389
+ : {}),
390
+ },
391
+ destination: {
392
+ chainId: destinationChain.chainId,
393
+ receiverAddress: destination.destinationAddress ?? toAddress,
394
+ tokenSymbol: destinationToken.symbol,
395
+ amount: destination.amountUnits,
396
+ ...(destination.tokenAddress
397
+ ? { tokenAddress: destination.tokenAddress }
398
+ : {}),
399
+ ...(receiverMemo ? { receiverMemo } : {}),
400
+ },
249
401
  display: {
250
- intent: "",
251
- paymentValue: String(toUnits ?? ""),
252
402
  currency: "USD",
403
+ title: title ?? "Pay",
404
+ ...(description ? { description } : {}),
253
405
  },
254
- destination,
255
- ...preferred,
256
- ...(metadata ?? {}),
257
- ...(isIntentPayment ? { intents: true } : {}),
406
+ ...(metadata ? { metadata } : {}),
407
+ ...(webhookUrl ? { webhookUrl } : {}),
408
+ ...(webhookSecret ? { webhookSecret } : {}),
258
409
  };
259
410
 
260
411
  // Create payment via API
261
- const response = await apiClient.post<PaymentResponseData>(
412
+ const response = await apiClient.post<PaymentResponse>(
262
413
  "/payment-api",
263
414
  paymentData
264
415
  );
@@ -269,3 +420,14 @@ export async function createRozoPayment(
269
420
 
270
421
  return response.data;
271
422
  }
423
+
424
+ /**
425
+ * Gets payment details by ID using the new backend API
426
+ * @param paymentId - Payment ID
427
+ * @returns Promise with payment response
428
+ */
429
+ export const getPayment = (
430
+ paymentId: string
431
+ ): Promise<ApiResponse<PaymentResponse>> => {
432
+ return apiClient.get<PaymentResponse>(`/payment-api/payments/${paymentId}`);
433
+ };