@rozoai/intent-common 0.1.2 → 0.1.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.
- package/package.json +5 -1
- package/src/api/base.ts +0 -261
- package/src/api/fee.ts +0 -95
- package/src/api/payment.ts +0 -483
- package/src/assert.ts +0 -29
- package/src/bridge-utils.ts +0 -382
- package/src/chain.ts +0 -257
- package/src/debug.ts +0 -14
- package/src/format.ts +0 -65
- package/src/index.ts +0 -14
- package/src/primitiveTypes.ts +0 -29
- package/src/retryBackoff.ts +0 -30
- package/src/rozoPay.ts +0 -638
- package/src/token.ts +0 -1226
- package/src/try.ts +0 -25
- package/src/validation.ts +0 -54
- package/test/bridge.test.ts +0 -396
- package/tsconfig.json +0 -12
package/src/bridge-utils.ts
DELETED
|
@@ -1,382 +0,0 @@
|
|
|
1
|
-
import { parseUnits } from "viem";
|
|
2
|
-
import {
|
|
3
|
-
baseUSDC,
|
|
4
|
-
getChainById,
|
|
5
|
-
getKnownToken,
|
|
6
|
-
isChainSupported,
|
|
7
|
-
isTokenSupported,
|
|
8
|
-
PaymentResponse,
|
|
9
|
-
RozoPayHydratedOrderWithOrg,
|
|
10
|
-
RozoPayIntentStatus,
|
|
11
|
-
RozoPayOrderMode,
|
|
12
|
-
RozoPayOrderStatusDest,
|
|
13
|
-
RozoPayOrderStatusSource,
|
|
14
|
-
RozoPayUserMetadata,
|
|
15
|
-
rozoSolana,
|
|
16
|
-
rozoSolanaUSDC,
|
|
17
|
-
rozoStellarUSDC,
|
|
18
|
-
solana,
|
|
19
|
-
validateAddressForChain,
|
|
20
|
-
} from ".";
|
|
21
|
-
|
|
22
|
-
export interface PaymentBridgeConfig {
|
|
23
|
-
toChain: number;
|
|
24
|
-
toToken: string;
|
|
25
|
-
toAddress: string;
|
|
26
|
-
toUnits: string;
|
|
27
|
-
preferredChain: number;
|
|
28
|
-
preferredTokenAddress: string;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export interface PreferredPaymentConfig {
|
|
32
|
-
preferredChain: string;
|
|
33
|
-
preferredToken: string;
|
|
34
|
-
preferredTokenAddress: string;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
export interface DestinationConfig {
|
|
38
|
-
destinationAddress?: string;
|
|
39
|
-
chainId: string;
|
|
40
|
-
amountUnits: string;
|
|
41
|
-
tokenSymbol: string;
|
|
42
|
-
tokenAddress: string;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
interface PaymentBridge {
|
|
46
|
-
preferred: PreferredPaymentConfig;
|
|
47
|
-
destination: DestinationConfig;
|
|
48
|
-
isIntentPayment: boolean;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* Creates payment bridge configuration for cross-chain payment routing
|
|
53
|
-
*
|
|
54
|
-
* Determines the optimal payment routing based on the destination chain/token
|
|
55
|
-
* and the preferred payment method selected by the user. This function handles
|
|
56
|
-
* the complexity of multi-chain payments by:
|
|
57
|
-
*
|
|
58
|
-
* 1. **Preferred Payment Method**: Identifies which chain/token the user will pay from
|
|
59
|
-
* - Supports Base USDC, Polygon USDC, Ethereum USDC, Solana USDC, Stellar USDC, Worldchain USDC, and BSC USDT
|
|
60
|
-
* - Sets appropriate chain ID and token address for the source transaction
|
|
61
|
-
*
|
|
62
|
-
* 2. **Destination Configuration**: Determines where funds will be received
|
|
63
|
-
* - Supports Base, Solana, Stellar, and Worldchain as destination chains
|
|
64
|
-
* - Automatically handles special address formats for Solana and Stellar addresses
|
|
65
|
-
* - Configures destination token based on chain type (e.g., Stellar/Solana USDC)
|
|
66
|
-
*
|
|
67
|
-
* 3. **Intent Payment Detection**: Determines if this is a cross-chain intent payment
|
|
68
|
-
* - Returns `isIntentPayment: true` when preferred chain/token differs from destination
|
|
69
|
-
* - Returns `isIntentPayment: false` for same-chain, same-token payments
|
|
70
|
-
*
|
|
71
|
-
* @param config - Payment bridge configuration parameters
|
|
72
|
-
* @param config.toChain - Destination chain ID (e.g., 8453 for Base, 900 for Solana, 10001 for Stellar)
|
|
73
|
-
* @param config.toToken - Destination token address (must be a supported token on the destination chain)
|
|
74
|
-
* @param config.toAddress - Destination address (format validated based on chain type: EVM 0x..., Solana Base58, Stellar G...)
|
|
75
|
-
* @param config.toUnits - Amount in human-readable units (e.g., "1" for 1 USDC, "0.5" for half a USDC)
|
|
76
|
-
* @param config.preferredChain - Chain ID where the user will pay from (e.g., 137 for Polygon, 8453 for Base)
|
|
77
|
-
* @param config.preferredTokenAddress - Token address the user selected to pay with (must be a supported token on preferredChain)
|
|
78
|
-
*
|
|
79
|
-
* @returns Payment routing configuration object
|
|
80
|
-
* @returns preferred - Source payment configuration (chain, token user will pay from)
|
|
81
|
-
* @returns preferred.preferredChain - Chain ID as string where payment originates
|
|
82
|
-
* @returns preferred.preferredToken - Token symbol (e.g., "USDC", "USDT")
|
|
83
|
-
* @returns preferred.preferredTokenAddress - Token contract address
|
|
84
|
-
* @returns destination - Destination payment configuration (chain, token user will receive)
|
|
85
|
-
* @returns destination.destinationAddress - Address where funds will be received
|
|
86
|
-
* @returns destination.chainId - Destination chain ID as string
|
|
87
|
-
* @returns destination.amountUnits - Payment amount in token units
|
|
88
|
-
* @returns destination.tokenSymbol - Destination token symbol
|
|
89
|
-
* @returns destination.tokenAddress - Destination token contract address
|
|
90
|
-
* @returns isIntentPayment - Boolean indicating if this is a cross-chain intent payment
|
|
91
|
-
*
|
|
92
|
-
* @throws {Error} If the destination token is not supported for the destination chain
|
|
93
|
-
* @throws {Error} If the destination address format is invalid for the destination chain
|
|
94
|
-
* @throws {Error} If the preferred token is not supported for the preferred chain
|
|
95
|
-
* @throws {Error} If the destination chain or token is not supported
|
|
96
|
-
*
|
|
97
|
-
* @example
|
|
98
|
-
* ```typescript
|
|
99
|
-
* // User wants to pay with Polygon USDC to receive on Base
|
|
100
|
-
* import { baseUSDC, polygonUSDCe } from '@rozoai/intent-common';
|
|
101
|
-
* import { base, polygon } from '@rozoai/intent-common';
|
|
102
|
-
*
|
|
103
|
-
* const { preferred, destination, isIntentPayment } = createPaymentBridgeConfig({
|
|
104
|
-
* toChain: base.chainId, // 8453
|
|
105
|
-
* toToken: baseUSDC.token,
|
|
106
|
-
* toAddress: '0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb',
|
|
107
|
-
* toUnits: '1000000', // 1 USDC (6 decimals)
|
|
108
|
-
* preferredChain: polygon.chainId, // 137
|
|
109
|
-
* preferredToken: polygonUSDCe.token,
|
|
110
|
-
* });
|
|
111
|
-
*
|
|
112
|
-
* // preferred = { preferredChain: '137', preferredToken: 'USDCe', preferredTokenAddress: '0x2791...' }
|
|
113
|
-
* // destination = { destinationAddress: '0x742d...', chainId: '8453', amountUnits: '1000000', tokenSymbol: 'USDC', tokenAddress: '0x8335...' }
|
|
114
|
-
* // isIntentPayment = true (different chains)
|
|
115
|
-
* ```
|
|
116
|
-
*
|
|
117
|
-
* @example
|
|
118
|
-
* ```typescript
|
|
119
|
-
* // User wants to pay to a Stellar address using Base USDC
|
|
120
|
-
* import { baseUSDC, rozoStellarUSDC } from '@rozoai/intent-common';
|
|
121
|
-
* import { base, rozoStellar } from '@rozoai/intent-common';
|
|
122
|
-
*
|
|
123
|
-
* const { preferred, destination, isIntentPayment } = createPaymentBridgeConfig({
|
|
124
|
-
* toChain: rozoStellar.chainId, // 10001
|
|
125
|
-
* toToken: rozoStellarUSDC.token,
|
|
126
|
-
* toAddress: 'GA5ZSEJYB37JRC5AVCIA5MOP4RHTM335X2KGX3IHOJAPP5RE34K4KZVN',
|
|
127
|
-
* toUnits: '10000000', // 1 USDC (7 decimals for Stellar)
|
|
128
|
-
* preferredChain: base.chainId, // 8453
|
|
129
|
-
* preferredToken: baseUSDC.token,
|
|
130
|
-
* });
|
|
131
|
-
*
|
|
132
|
-
* // preferred = { preferredChain: '8453', preferredToken: 'USDC', preferredTokenAddress: '0x8335...' }
|
|
133
|
-
* // destination = { destinationAddress: 'GA5Z...', chainId: '10001', amountUnits: '10000000', tokenSymbol: 'USDC', tokenAddress: 'USDC:GA5Z...' }
|
|
134
|
-
* // isIntentPayment = true (Base to Stellar)
|
|
135
|
-
* ```
|
|
136
|
-
*
|
|
137
|
-
* @example
|
|
138
|
-
* ```typescript
|
|
139
|
-
* // Same-chain payment (not an intent payment)
|
|
140
|
-
* const { preferred, destination, isIntentPayment } = createPaymentBridgeConfig({
|
|
141
|
-
* toChain: base.chainId, // 8453
|
|
142
|
-
* toToken: baseUSDC.token,
|
|
143
|
-
* toAddress: '0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb',
|
|
144
|
-
* toUnits: '1000000',
|
|
145
|
-
* preferredChain: base.chainId, // 8453
|
|
146
|
-
* preferredToken: baseUSDC.token,
|
|
147
|
-
* });
|
|
148
|
-
*
|
|
149
|
-
* // isIntentPayment = false (same chain and token)
|
|
150
|
-
* ```
|
|
151
|
-
*
|
|
152
|
-
* @see PreferredPaymentConfig
|
|
153
|
-
* @see DestinationConfig
|
|
154
|
-
* @see PaymentBridgeConfig
|
|
155
|
-
*/
|
|
156
|
-
export function createPaymentBridgeConfig({
|
|
157
|
-
toChain,
|
|
158
|
-
toToken,
|
|
159
|
-
toAddress,
|
|
160
|
-
toUnits,
|
|
161
|
-
preferredChain,
|
|
162
|
-
preferredTokenAddress,
|
|
163
|
-
}: PaymentBridgeConfig): PaymentBridge {
|
|
164
|
-
const chain = getChainById(toChain);
|
|
165
|
-
const token = getKnownToken(toChain, toToken);
|
|
166
|
-
|
|
167
|
-
if (!token) {
|
|
168
|
-
throw new Error(
|
|
169
|
-
`Unsupported token ${toToken} for chain ${chain.name} (${toChain})`
|
|
170
|
-
);
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
const addressValid = validateAddressForChain(toChain, toAddress);
|
|
174
|
-
if (!addressValid) {
|
|
175
|
-
throw new Error(
|
|
176
|
-
`Invalid address ${toAddress} for chain ${chain.name} (${toChain})`
|
|
177
|
-
);
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
const preferredChainData = getChainById(preferredChain);
|
|
181
|
-
const tokenConfig = getKnownToken(preferredChain, preferredTokenAddress);
|
|
182
|
-
if (!tokenConfig) {
|
|
183
|
-
throw new Error(
|
|
184
|
-
`Unknown token ${preferredTokenAddress} for chain ${preferredChainData.name} (${preferredChain})`
|
|
185
|
-
);
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
let preferred: PreferredPaymentConfig = {
|
|
189
|
-
preferredChain: String(preferredChain),
|
|
190
|
-
preferredToken: tokenConfig.symbol,
|
|
191
|
-
preferredTokenAddress: preferredTokenAddress,
|
|
192
|
-
};
|
|
193
|
-
|
|
194
|
-
let destination: DestinationConfig = {
|
|
195
|
-
destinationAddress: toAddress,
|
|
196
|
-
chainId: String(toChain),
|
|
197
|
-
amountUnits: toUnits,
|
|
198
|
-
tokenSymbol: token.symbol,
|
|
199
|
-
tokenAddress: toToken,
|
|
200
|
-
};
|
|
201
|
-
|
|
202
|
-
if (isChainSupported(toChain) && isTokenSupported(toChain, toToken)) {
|
|
203
|
-
preferred = {
|
|
204
|
-
preferredChain: String(
|
|
205
|
-
tokenConfig.chainId === solana.chainId
|
|
206
|
-
? rozoSolana.chainId
|
|
207
|
-
: tokenConfig.chainId
|
|
208
|
-
),
|
|
209
|
-
preferredToken: tokenConfig.symbol,
|
|
210
|
-
preferredTokenAddress: tokenConfig.token,
|
|
211
|
-
};
|
|
212
|
-
|
|
213
|
-
// Determine destination based on special address types
|
|
214
|
-
if (isChainSupported(toChain, "stellar")) {
|
|
215
|
-
destination = {
|
|
216
|
-
...destination,
|
|
217
|
-
tokenSymbol: rozoStellarUSDC.symbol,
|
|
218
|
-
chainId: String(rozoStellarUSDC.chainId),
|
|
219
|
-
tokenAddress: rozoStellarUSDC.token,
|
|
220
|
-
};
|
|
221
|
-
} else if (isChainSupported(toChain, "solana")) {
|
|
222
|
-
destination = {
|
|
223
|
-
...destination,
|
|
224
|
-
tokenSymbol: rozoSolanaUSDC.symbol,
|
|
225
|
-
chainId: String(rozoSolanaUSDC.chainId),
|
|
226
|
-
tokenAddress: rozoSolanaUSDC.token,
|
|
227
|
-
};
|
|
228
|
-
}
|
|
229
|
-
} else {
|
|
230
|
-
throw new Error(
|
|
231
|
-
`Unsupported chain ${chain.name} (${toChain}) or token ${token.symbol} (${toToken})`
|
|
232
|
-
);
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
// If the preferred chain and token are not the same as the toChain and toToken, then it is an intent payment
|
|
236
|
-
const isIntentPayment =
|
|
237
|
-
preferred.preferredChain !== String(toChain) &&
|
|
238
|
-
preferred.preferredTokenAddress !== toToken;
|
|
239
|
-
|
|
240
|
-
return { preferred, destination, isIntentPayment };
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
/**
|
|
244
|
-
* Converts a RozoAI payment API response to a fully hydrated RozoPay order.
|
|
245
|
-
*
|
|
246
|
-
* This utility transforms the low-level {@link PaymentResponse} object returned by the RozoAI Intent Pay API
|
|
247
|
-
* into a {@link RozoPayHydratedOrderWithOrg}, containing all values needed for UI display, order tracking,
|
|
248
|
-
* and multi-chain cross-payment logic. Fields are normalized and token metadata is resolved in order to
|
|
249
|
-
* standardize data from different chains and token types.
|
|
250
|
-
*
|
|
251
|
-
* Key steps performed:
|
|
252
|
-
*
|
|
253
|
-
* 1. **Token Metadata Lookup**: Uses {@link getKnownToken} to identify the correct token
|
|
254
|
-
* for the payment, including decimals, symbol, logo, and chain details.
|
|
255
|
-
* Special handling is applied for Stellar and Solana tokens based on how they're encoded in the backend.
|
|
256
|
-
*
|
|
257
|
-
* 2. **Order Hydration**: Generates a unique (random BigInt) internal order ID for frontend usage, sets the
|
|
258
|
-
* payment mode as HYDRATED, and resolves all destination call and amount fields from the payment response.
|
|
259
|
-
*
|
|
260
|
-
* 3. **Status Initialization**: Initializes the payment, source, and destination status fields
|
|
261
|
-
* with their correct values based on the payment's progress in the state machine. The returned object is
|
|
262
|
-
* ready for status tracking and user notification.
|
|
263
|
-
*
|
|
264
|
-
* 4. **Metadata Consolidation**: Merges core order metadata, user metadata (if provided by the payer),
|
|
265
|
-
* and any external references such as org info. Ensures all details needed for order display and analytics are available.
|
|
266
|
-
*
|
|
267
|
-
* @param order - Low-level API payment response (from RozoAI Intent Pay backend)
|
|
268
|
-
* @param feeType - Optional: Fee deduction mode (ExactIn/ExactOut); determines which side's amount is shown as source. Defaults to ExactIn.
|
|
269
|
-
*
|
|
270
|
-
* @returns {RozoPayHydratedOrderWithOrg} A normalized, display-ready order representation containing all tracking, status,
|
|
271
|
-
* token, org, and routing information for frontend use.
|
|
272
|
-
*
|
|
273
|
-
* @example
|
|
274
|
-
* ```typescript
|
|
275
|
-
* const paymentResponse = await getPayment(paymentId);
|
|
276
|
-
* const hydratedOrder = formatPaymentResponseToHydratedOrder(paymentResponse.data);
|
|
277
|
-
* console.log(hydratedOrder.sourceStatus); // 'WAITING_PAYMENT'
|
|
278
|
-
* console.log(hydratedOrder.destFinalCallTokenAmount.token.symbol); // 'USDC'
|
|
279
|
-
* console.log(hydratedOrder.usdValue); // 10.00
|
|
280
|
-
* ```
|
|
281
|
-
*
|
|
282
|
-
* @remarks
|
|
283
|
-
* - The returned `id` (BigInt) is generated randomly and is client-side only; always use
|
|
284
|
-
* `order.orderId` or the API reference for backend/server reconciliation.
|
|
285
|
-
* - The expiration timestamp and org info are carried over if present on the API response.
|
|
286
|
-
* - Decimals, token symbol, and display metadata for the amount and destination chain
|
|
287
|
-
* are resolved so the result is immediately usable for UI.
|
|
288
|
-
*
|
|
289
|
-
* @see PaymentResponse
|
|
290
|
-
* @see RozoPayHydratedOrderWithOrg
|
|
291
|
-
* @see getKnownToken
|
|
292
|
-
*/
|
|
293
|
-
export function formatPaymentResponseToHydratedOrder(
|
|
294
|
-
order: PaymentResponse
|
|
295
|
-
): RozoPayHydratedOrderWithOrg {
|
|
296
|
-
// Source amount is in the same units as the destination amount without fee
|
|
297
|
-
const sourceAmountUnits =
|
|
298
|
-
order.source?.amount ?? order.destination?.amountUnits ?? "0";
|
|
299
|
-
|
|
300
|
-
// Destination Intent Address
|
|
301
|
-
const intentAddress =
|
|
302
|
-
order.metadata?.receivingAddress ?? order.source?.receiverAddress;
|
|
303
|
-
|
|
304
|
-
// Destination Intent Memo
|
|
305
|
-
const intentMemo = order.metadata?.memo ?? order.source?.receiverMemo;
|
|
306
|
-
|
|
307
|
-
// Destination address is where the payment will be received
|
|
308
|
-
const destAddress = order.source?.receiverAddress;
|
|
309
|
-
|
|
310
|
-
// Determine the chain from metadata or default to the source chain
|
|
311
|
-
const requiredChain = order.source?.chainId || baseUSDC.chainId;
|
|
312
|
-
|
|
313
|
-
const token = getKnownToken(
|
|
314
|
-
Number(requiredChain),
|
|
315
|
-
Number(requiredChain) === rozoStellarUSDC.chainId
|
|
316
|
-
? rozoStellarUSDC.token
|
|
317
|
-
: order.source?.tokenAddress || ""
|
|
318
|
-
);
|
|
319
|
-
|
|
320
|
-
return {
|
|
321
|
-
id: BigInt(Math.floor(Math.random() * Number.MAX_SAFE_INTEGER)),
|
|
322
|
-
mode: RozoPayOrderMode.HYDRATED,
|
|
323
|
-
intentAddr: intentAddress ?? "",
|
|
324
|
-
memo: intentMemo ?? null,
|
|
325
|
-
preferredChainId: order.source?.chainId ?? null,
|
|
326
|
-
preferredTokenAddress: order.source?.tokenAddress ?? null,
|
|
327
|
-
destFinalCallTokenAmount: {
|
|
328
|
-
token: {
|
|
329
|
-
chainId: token ? token.chainId : baseUSDC.chainId,
|
|
330
|
-
token: token ? token.token : baseUSDC.token,
|
|
331
|
-
symbol: token ? token.symbol : baseUSDC.symbol,
|
|
332
|
-
usd: Number(sourceAmountUnits),
|
|
333
|
-
priceFromUsd: 1,
|
|
334
|
-
decimals: token ? token.decimals : baseUSDC.decimals,
|
|
335
|
-
displayDecimals: 2,
|
|
336
|
-
logoSourceURI: token ? token.logoSourceURI : baseUSDC.logoSourceURI,
|
|
337
|
-
logoURI: token ? token.logoURI : baseUSDC.logoURI,
|
|
338
|
-
maxAcceptUsd: 100000,
|
|
339
|
-
maxSendUsd: 0,
|
|
340
|
-
},
|
|
341
|
-
amount: parseUnits(
|
|
342
|
-
sourceAmountUnits,
|
|
343
|
-
token ? token.decimals : baseUSDC.decimals
|
|
344
|
-
).toString() as `${bigint}`,
|
|
345
|
-
usd: Number(sourceAmountUnits),
|
|
346
|
-
},
|
|
347
|
-
usdValue: Number(sourceAmountUnits),
|
|
348
|
-
destFinalCall: {
|
|
349
|
-
to: destAddress ?? "",
|
|
350
|
-
value: BigInt("0"),
|
|
351
|
-
data: "0x",
|
|
352
|
-
},
|
|
353
|
-
refundAddr: (order.source?.senderAddress as any) || null,
|
|
354
|
-
nonce: BigInt(order.nonce ?? 0),
|
|
355
|
-
sourceFulfillerAddr: null,
|
|
356
|
-
sourceTokenAmount: null,
|
|
357
|
-
sourceInitiateTxHash: null,
|
|
358
|
-
sourceStatus: RozoPayOrderStatusSource.WAITING_PAYMENT,
|
|
359
|
-
destStatus: RozoPayOrderStatusDest.PENDING,
|
|
360
|
-
intentStatus: RozoPayIntentStatus.UNPAID,
|
|
361
|
-
destFastFinishTxHash: null,
|
|
362
|
-
destClaimTxHash: null,
|
|
363
|
-
redirectUri: null,
|
|
364
|
-
createdAt: Math.floor(new Date(order.createdAt).getTime() / 1000),
|
|
365
|
-
lastUpdatedAt: Math.floor(new Date(order.updatedAt).getTime() / 1000),
|
|
366
|
-
orgId: order.orgId ?? "",
|
|
367
|
-
metadata: {
|
|
368
|
-
...(order?.metadata ?? {}),
|
|
369
|
-
receivingAddress: intentAddress ?? "",
|
|
370
|
-
memo: intentMemo ?? null,
|
|
371
|
-
} as any,
|
|
372
|
-
externalId: order.externalId ?? null,
|
|
373
|
-
userMetadata: order.userMetadata as RozoPayUserMetadata | null,
|
|
374
|
-
expirationTs: BigInt(
|
|
375
|
-
Math.floor(new Date(order.expiresAt).getTime() / 1000).toString()
|
|
376
|
-
),
|
|
377
|
-
org: {
|
|
378
|
-
orgId: order.orgId ?? "",
|
|
379
|
-
name: "",
|
|
380
|
-
},
|
|
381
|
-
};
|
|
382
|
-
}
|
package/src/chain.ts
DELETED
|
@@ -1,257 +0,0 @@
|
|
|
1
|
-
export type Chain = {
|
|
2
|
-
type: "evm" | "solana" | "stellar";
|
|
3
|
-
chainId: number;
|
|
4
|
-
name: string;
|
|
5
|
-
cctpDomain: number | null;
|
|
6
|
-
};
|
|
7
|
-
|
|
8
|
-
export const arbitrum: Chain = {
|
|
9
|
-
type: "evm",
|
|
10
|
-
chainId: 42161,
|
|
11
|
-
name: "Arbitrum",
|
|
12
|
-
cctpDomain: 3,
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
export const base: Chain = {
|
|
16
|
-
type: "evm",
|
|
17
|
-
chainId: 8453,
|
|
18
|
-
name: "Base",
|
|
19
|
-
cctpDomain: 6,
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
export const bsc: Chain = {
|
|
23
|
-
type: "evm",
|
|
24
|
-
chainId: 56,
|
|
25
|
-
name: "BNB",
|
|
26
|
-
cctpDomain: null,
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
export const celo: Chain = {
|
|
30
|
-
type: "evm",
|
|
31
|
-
chainId: 42220,
|
|
32
|
-
name: "Celo",
|
|
33
|
-
cctpDomain: null,
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
export const ethereum: Chain = {
|
|
37
|
-
type: "evm",
|
|
38
|
-
chainId: 1,
|
|
39
|
-
name: "Ethereum",
|
|
40
|
-
cctpDomain: 0,
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
export const linea: Chain = {
|
|
44
|
-
type: "evm",
|
|
45
|
-
chainId: 59144,
|
|
46
|
-
name: "Linea",
|
|
47
|
-
cctpDomain: 11,
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
export const mantle: Chain = {
|
|
51
|
-
type: "evm",
|
|
52
|
-
chainId: 5000,
|
|
53
|
-
name: "Mantle",
|
|
54
|
-
cctpDomain: null,
|
|
55
|
-
};
|
|
56
|
-
|
|
57
|
-
export const optimism: Chain = {
|
|
58
|
-
type: "evm",
|
|
59
|
-
chainId: 10,
|
|
60
|
-
name: "Optimism",
|
|
61
|
-
cctpDomain: 2,
|
|
62
|
-
};
|
|
63
|
-
|
|
64
|
-
export const polygon: Chain = {
|
|
65
|
-
type: "evm",
|
|
66
|
-
chainId: 137,
|
|
67
|
-
name: "Polygon",
|
|
68
|
-
cctpDomain: 7,
|
|
69
|
-
};
|
|
70
|
-
|
|
71
|
-
export const solana: Chain = {
|
|
72
|
-
type: "solana",
|
|
73
|
-
chainId: 501,
|
|
74
|
-
name: "Solana",
|
|
75
|
-
cctpDomain: 5,
|
|
76
|
-
};
|
|
77
|
-
|
|
78
|
-
export const stellar: Chain = {
|
|
79
|
-
type: "stellar",
|
|
80
|
-
chainId: 10001,
|
|
81
|
-
name: "Stellar",
|
|
82
|
-
cctpDomain: null,
|
|
83
|
-
};
|
|
84
|
-
|
|
85
|
-
export const worldchain: Chain = {
|
|
86
|
-
type: "evm",
|
|
87
|
-
chainId: 480,
|
|
88
|
-
name: "Worldchain",
|
|
89
|
-
cctpDomain: 14,
|
|
90
|
-
};
|
|
91
|
-
|
|
92
|
-
/**
|
|
93
|
-
* Rozo Solana
|
|
94
|
-
* @link https://github.com/RozoAI/rozo-payment-manager/tree/staging?tab=readme-ov-file#supported-chains-and-tokens
|
|
95
|
-
*/
|
|
96
|
-
export const rozoSolana: Chain = {
|
|
97
|
-
type: "solana",
|
|
98
|
-
chainId: 900,
|
|
99
|
-
name: "Solana",
|
|
100
|
-
cctpDomain: 5,
|
|
101
|
-
};
|
|
102
|
-
|
|
103
|
-
export const rozoStellar: Chain = {
|
|
104
|
-
type: "stellar",
|
|
105
|
-
chainId: 1500,
|
|
106
|
-
name: "Stellar",
|
|
107
|
-
cctpDomain: null,
|
|
108
|
-
};
|
|
109
|
-
|
|
110
|
-
export const gnosis: Chain = {
|
|
111
|
-
type: "evm",
|
|
112
|
-
chainId: 100,
|
|
113
|
-
name: "Gnosis",
|
|
114
|
-
cctpDomain: null,
|
|
115
|
-
};
|
|
116
|
-
|
|
117
|
-
export const avalanche: Chain = {
|
|
118
|
-
type: "evm",
|
|
119
|
-
chainId: 43114,
|
|
120
|
-
name: "Avalanche",
|
|
121
|
-
cctpDomain: null,
|
|
122
|
-
};
|
|
123
|
-
|
|
124
|
-
/**
|
|
125
|
-
* Supported chains for Near Intents cross-chain swaps
|
|
126
|
-
* Based on USDC/USDT support documentation
|
|
127
|
-
*/
|
|
128
|
-
export const supportedChains: Chain[] = [
|
|
129
|
-
// Supported for Near Intents (USDC/USDT)
|
|
130
|
-
arbitrum, // USDC & USDT
|
|
131
|
-
avalanche, // USDC & USDT
|
|
132
|
-
base, // USDC only (no USDT)
|
|
133
|
-
bsc, // USDC & USDT
|
|
134
|
-
ethereum, // USDC & USDT
|
|
135
|
-
gnosis, // USDC & USDT
|
|
136
|
-
optimism, // USDC & USDT
|
|
137
|
-
polygon, // USDC & USDT
|
|
138
|
-
worldchain,
|
|
139
|
-
solana,
|
|
140
|
-
rozoSolana, // USDC & USDT (chainId: 900)
|
|
141
|
-
rozoStellar, // USDC only (chainId: 1500, no USDT)
|
|
142
|
-
|
|
143
|
-
// Not supported for Near Intents - kept for other features
|
|
144
|
-
// celo, // Not in Near Intents docs
|
|
145
|
-
// linea, // Not in Near Intents docs
|
|
146
|
-
// mantle, // Not in Near Intents docs
|
|
147
|
-
// solana, // Use rozoSolana (900) instead of solana (501)
|
|
148
|
-
// stellar, // Use rozoStellar (1500) instead of stellar (10001)
|
|
149
|
-
];
|
|
150
|
-
|
|
151
|
-
// https://developers.circle.com/stablecoins/supported-domains
|
|
152
|
-
const cctpV1Chains = [
|
|
153
|
-
arbitrum,
|
|
154
|
-
base,
|
|
155
|
-
ethereum,
|
|
156
|
-
optimism,
|
|
157
|
-
polygon,
|
|
158
|
-
solana,
|
|
159
|
-
rozoSolana,
|
|
160
|
-
stellar,
|
|
161
|
-
rozoStellar,
|
|
162
|
-
];
|
|
163
|
-
const cctpV2Chains = [arbitrum, base, ethereum, linea, worldchain];
|
|
164
|
-
|
|
165
|
-
/** Given a chainId, return the chain. */
|
|
166
|
-
export function getChainById(chainId: number): Chain {
|
|
167
|
-
const ret = supportedChains.find((c) => c.chainId === chainId);
|
|
168
|
-
if (ret == null) throw new Error(`Unknown chainId ${chainId}`);
|
|
169
|
-
return ret;
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
/** Returns the chain name for the given chainId. */
|
|
173
|
-
export function getChainName(chainId: number): string {
|
|
174
|
-
return getChainById(chainId).name;
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
/** Returns the CCTP domain for the given chainId. */
|
|
178
|
-
export function getCCTPDomain(chainId: number): number | null {
|
|
179
|
-
return getChainById(chainId).cctpDomain;
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
/** Returns true if the chain is a CCTP v1 chain. */
|
|
183
|
-
export function isCCTPV1Chain(chainId: number): boolean {
|
|
184
|
-
return cctpV1Chains.some((c) => c.chainId === chainId);
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
/** Returns true if the chain is a CCTP v2 chain. */
|
|
188
|
-
export function isCCTPV2Chain(chainId: number): boolean {
|
|
189
|
-
return cctpV2Chains.some((c) => c.chainId === chainId);
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
/**
|
|
193
|
-
* Get block explorer URL for chain ID
|
|
194
|
-
*/
|
|
195
|
-
export function getChainExplorerByChainId(chainId: number): string | undefined {
|
|
196
|
-
switch (chainId) {
|
|
197
|
-
case arbitrum.chainId:
|
|
198
|
-
return "https://arbiscan.io";
|
|
199
|
-
case base.chainId:
|
|
200
|
-
return "https://basescan.org";
|
|
201
|
-
case bsc.chainId:
|
|
202
|
-
return "https://bscscan.com";
|
|
203
|
-
case celo.chainId:
|
|
204
|
-
return "https://celoscan.io";
|
|
205
|
-
case ethereum.chainId:
|
|
206
|
-
return "https://etherscan.io";
|
|
207
|
-
case linea.chainId:
|
|
208
|
-
return "https://lineascan.build";
|
|
209
|
-
case mantle.chainId:
|
|
210
|
-
return "https://mantlescan.xyz";
|
|
211
|
-
case optimism.chainId:
|
|
212
|
-
return "https://optimistic.etherscan.io";
|
|
213
|
-
case polygon.chainId:
|
|
214
|
-
return "https://polygonscan.com";
|
|
215
|
-
case gnosis.chainId:
|
|
216
|
-
return "https://gnosisscan.io";
|
|
217
|
-
case avalanche.chainId:
|
|
218
|
-
return "https://snowtrace.io";
|
|
219
|
-
case solana.chainId:
|
|
220
|
-
case rozoSolana.chainId:
|
|
221
|
-
return "https://solscan.io";
|
|
222
|
-
case stellar.chainId:
|
|
223
|
-
case rozoStellar.chainId:
|
|
224
|
-
return "https://stellar.expert/explorer/public/search?term=";
|
|
225
|
-
case worldchain.chainId:
|
|
226
|
-
return "https://worldscan.org";
|
|
227
|
-
default:
|
|
228
|
-
return undefined;
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
/**
|
|
233
|
-
* Get block explorer address URL for chain ID and address.
|
|
234
|
-
*/
|
|
235
|
-
export function getChainExplorerAddressUrl(chainId: number, address: string) {
|
|
236
|
-
const explorer = getChainExplorerByChainId(chainId);
|
|
237
|
-
if (!explorer) {
|
|
238
|
-
return undefined;
|
|
239
|
-
}
|
|
240
|
-
return `${explorer}/address/${address}`;
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
/**
|
|
244
|
-
* Get block explorer transaction URL for chain ID and transaction hash.
|
|
245
|
-
*/
|
|
246
|
-
export function getChainExplorerTxUrl(chainId: number, txHash: string) {
|
|
247
|
-
const explorer = getChainExplorerByChainId(chainId);
|
|
248
|
-
if (!explorer) {
|
|
249
|
-
return undefined;
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
if ([stellar.chainId, rozoStellar.chainId].includes(chainId)) {
|
|
253
|
-
return `${explorer}${txHash}`;
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
return `${explorer}/tx/${txHash}`;
|
|
257
|
-
}
|
package/src/debug.ts
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
/** Return compact JSON, 10000 chars max. Never throws. */
|
|
2
|
-
export function debugJson(obj: any) {
|
|
3
|
-
try {
|
|
4
|
-
let serialized = JSON.stringify(obj, (_, value) =>
|
|
5
|
-
typeof value === "bigint" ? value.toString() : value,
|
|
6
|
-
);
|
|
7
|
-
if (typeof serialized !== "string") {
|
|
8
|
-
serialized = "" + obj;
|
|
9
|
-
}
|
|
10
|
-
return serialized.slice(0, 10000);
|
|
11
|
-
} catch (e: any) {
|
|
12
|
-
return `<JSON error: ${e.message}>`;
|
|
13
|
-
}
|
|
14
|
-
}
|