@rhea-finance/cross-chain-aggregation-dex 2.0.0 → 2.0.2
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/README.md +536 -205
- package/dist/executors/aptos.d.mts +2 -2
- package/dist/executors/aptos.d.ts +2 -2
- package/dist/executors/aptos.js.map +1 -1
- package/dist/executors/aptos.mjs.map +1 -1
- package/dist/executors/bitcoin.d.mts +2 -2
- package/dist/executors/bitcoin.d.ts +2 -2
- package/dist/executors/bitcoin.js.map +1 -1
- package/dist/executors/bitcoin.mjs.map +1 -1
- package/dist/executors/evm.d.mts +2 -2
- package/dist/executors/evm.d.ts +2 -2
- package/dist/executors/evm.js.map +1 -1
- package/dist/executors/evm.mjs.map +1 -1
- package/dist/executors/near.d.mts +2 -2
- package/dist/executors/near.d.ts +2 -2
- package/dist/executors/near.js.map +1 -1
- package/dist/executors/near.mjs.map +1 -1
- package/dist/executors/solana.d.mts +2 -2
- package/dist/executors/solana.d.ts +2 -2
- package/dist/executors/solana.js.map +1 -1
- package/dist/executors/solana.mjs.map +1 -1
- package/dist/executors/sui.d.mts +2 -2
- package/dist/executors/sui.d.ts +2 -2
- package/dist/executors/sui.js.map +1 -1
- package/dist/executors/sui.mjs.map +1 -1
- package/dist/executors/tron.d.mts +2 -2
- package/dist/executors/tron.d.ts +2 -2
- package/dist/executors/tron.js.map +1 -1
- package/dist/executors/tron.mjs.map +1 -1
- package/dist/executors/zcash.d.mts +3 -3
- package/dist/executors/zcash.d.ts +3 -3
- package/dist/executors/zcash.js +2 -8
- package/dist/executors/zcash.js.map +1 -1
- package/dist/executors/zcash.mjs +2 -8
- package/dist/executors/zcash.mjs.map +1 -1
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +8 -15
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +8 -15
- package/dist/index.mjs.map +1 -1
- package/dist/{registry-DRYUqs7T.d.mts → registry-DjohbPPm.d.mts} +2 -5
- package/dist/{registry-DRYUqs7T.d.ts → registry-DjohbPPm.d.ts} +2 -5
- package/dist/{shared-BdH3hWuP.d.ts → shared-BbfGrWrJ.d.ts} +2 -7
- package/dist/{shared-BqpFeosz.d.mts → shared-BxJ0H20s.d.mts} +2 -7
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,88 +1,159 @@
|
|
|
1
1
|
# @rhea-finance/cross-chain-aggregation-dex
|
|
2
2
|
|
|
3
|
-
TypeScript SDK for the unified multi-chain Swap API.
|
|
3
|
+
A TypeScript SDK for the RHEA unified multi-chain Swap API. The SDK handles quote normalization, swap building, wallet execution, EVM approvals, order submission, status polling, reporting, and history. Applications do not need to branch on routers, cross-chain status, or transaction types.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
This package is a client SDK for the RHEA Cross-Chain Swap API. For endpoint contracts, request/response fields, and protocol details, see the [Cross-Chain Swap API documentation](https://github.com/rhea-finance/rhea-sdk-docs/blob/main/CrossChainDexAPI.md).
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Supported chain families: EVM, Solana, Aptos, NEAR, Tron, Bitcoin, Zcash, and Sui. How to load the product token list and chain coverage is described in [Supported chains and tokens](#supported-chains-and-tokens).
|
|
8
|
+
|
|
9
|
+
## Supported chains and tokens
|
|
10
|
+
|
|
11
|
+
The product support list matches `multi-chain-lending` Trade: **18 mainnets**. Use the HTTP API chain ID for `fromChain` / `toChain` in Swap calls, and the token-query alias when fetching token metadata.
|
|
12
|
+
|
|
13
|
+
| Chain | Type | HTTP / SDK chain ID | Token query alias |
|
|
14
|
+
| --- | --- | --- | --- |
|
|
15
|
+
| Ethereum | EVM | `1` | `eth` |
|
|
16
|
+
| BNB Smart Chain | EVM | `56` | `bsc` |
|
|
17
|
+
| Arbitrum One | EVM | `42161` | `arb` |
|
|
18
|
+
| Base | EVM | `8453` | `base` |
|
|
19
|
+
| Optimism | EVM | `10` | `op` |
|
|
20
|
+
| Berachain | EVM | `1385` | `bera` |
|
|
21
|
+
| Monad | EVM | `143` | `monad` |
|
|
22
|
+
| X Layer | EVM | `196` | `xlayer` |
|
|
23
|
+
| Polygon PoS | EVM | `137` | `pol` |
|
|
24
|
+
| Gnosis Chain | EVM | `100` | `gnosis` |
|
|
25
|
+
| Plasma | EVM | `9745` | `plasma` |
|
|
26
|
+
| Solana | Non-EVM | `solana` | `sol` |
|
|
27
|
+
| Bitcoin | Non-EVM | `btc` | `btc` |
|
|
28
|
+
| NEAR | Non-EVM | `near` | `near` |
|
|
29
|
+
| Zcash | Non-EVM | `zcash` | `zcash` (also accepts `zec`) |
|
|
30
|
+
| Aptos | Non-EVM | `aptos` | `aptos` |
|
|
31
|
+
| Tron | Non-EVM | `tron` | `tron` |
|
|
32
|
+
| Sui | Non-EVM | `sui` | `sui` |
|
|
33
|
+
|
|
34
|
+
"Supported" means the product can load tokens for that chain and send them into the unified quote flow. It does **not** guarantee a route for every pair. Live liquidity, routers, amount, and service status still decide whether a quote succeeds.
|
|
35
|
+
|
|
36
|
+
### Token coverage (Unified Swap)
|
|
37
|
+
|
|
38
|
+
Across the 18 product chains above, Unified Swap currently covers **4,000+** tokens (same-chain DEX metadata plus cross-chain Intents tokens, deduplicated per direction). Snapshot: 2026-07-24. Counts change as liquidity providers and Intents listings update; always fetch the live token APIs below for the current list.
|
|
39
|
+
|
|
40
|
+
### How to fetch supported tokens
|
|
41
|
+
|
|
42
|
+
Token discovery uses HTTP endpoints **outside** `/api/swap/*`. The SDK does not wrap these calls; applications should `fetch` them directly and map results into `AssetRef` when calling `client.quote()`.
|
|
43
|
+
|
|
44
|
+
#### 1. Product token list (recommended for Trade UI)
|
|
45
|
+
|
|
46
|
+
```http
|
|
47
|
+
GET https://api.rhea.finance/get_multichain_lending_tokens_data?chains=<COMMA_SEPARATED_ALIASES>
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Query all currently supported product chains:
|
|
8
51
|
|
|
9
52
|
```bash
|
|
10
|
-
|
|
53
|
+
curl "https://api.rhea.finance/get_multichain_lending_tokens_data?chains=bsc,eth,arb,base,op,bera,monad,xlayer,pol,gnosis,plasma,sol,btc,near,zcash,zec,aptos,tron,sui"
|
|
11
54
|
```
|
|
12
55
|
|
|
13
|
-
|
|
56
|
+
A successful response is a **JSON array** of token objects (not the `/api/swap` `{ code, data, msg }` envelope). Typical fields:
|
|
14
57
|
|
|
15
|
-
|
|
58
|
+
| Field | Description |
|
|
59
|
+
| --- | --- |
|
|
60
|
+
| `assetId` | Multichain / Intents asset ID |
|
|
61
|
+
| `blockchain` | Token query alias (`eth`, `near`, …) |
|
|
62
|
+
| `symbol` | Display symbol |
|
|
63
|
+
| `decimals` | Token decimals |
|
|
64
|
+
| `contractAddress` | On-chain address; may be empty for natives |
|
|
65
|
+
| `price` / `priceUpdatedAt` | Display price only; not a swap quote |
|
|
66
|
+
| `icon` | Optional icon URL |
|
|
16
67
|
|
|
17
|
-
|
|
18
|
-
import { SwapClient, type QuoteRequest } from "@rhea-finance/cross-chain-aggregation-dex";
|
|
68
|
+
Integration tips:
|
|
19
69
|
|
|
20
|
-
|
|
70
|
+
- Group by `blockchain`; do not merge tokens by `symbol` alone.
|
|
71
|
+
- For `quote()`, pass the chain-specific token address/ID as `AssetRef.address`, and use the HTTP/SDK chain ID in `fromChain` / `toChain` / `AssetRef.chain` (for example Base `"8453"`, Solana `"solana"`).
|
|
72
|
+
- Presence in this list means the token is discoverable. Confirm a route with `client.quote()` (or `POST /api/swap/quote`) before trading.
|
|
73
|
+
- Prefer short-lived cache; refresh periodically instead of hard-coding the list.
|
|
21
74
|
|
|
22
|
-
|
|
23
|
-
baseUrl: "https://api.rhea.finance",
|
|
24
|
-
getAccessToken,
|
|
25
|
-
});
|
|
75
|
+
#### 2. Per-chain token price metadata
|
|
26
76
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
tokenIn: {
|
|
31
|
-
chain: "btc",
|
|
32
|
-
address: "btc",
|
|
33
|
-
symbol: "BTC",
|
|
34
|
-
decimals: 8,
|
|
35
|
-
isNative: true,
|
|
36
|
-
},
|
|
37
|
-
tokenOut: {
|
|
38
|
-
chain: "near",
|
|
39
|
-
address: "wrap.near",
|
|
40
|
-
symbol: "wNEAR",
|
|
41
|
-
decimals: 24,
|
|
42
|
-
},
|
|
43
|
-
amountIn: "100000",
|
|
44
|
-
slippageBps: 50,
|
|
45
|
-
sender: "bc1...",
|
|
46
|
-
recipient: "alice.near",
|
|
47
|
-
};
|
|
77
|
+
```http
|
|
78
|
+
GET https://api.rhea.finance/get_chain_prices?chain=<TOKEN_QUERY_ALIAS>
|
|
79
|
+
```
|
|
48
80
|
|
|
49
|
-
|
|
50
|
-
const build = await client.buildSwap({ quote });
|
|
81
|
+
Example:
|
|
51
82
|
|
|
52
|
-
|
|
53
|
-
|
|
83
|
+
```bash
|
|
84
|
+
curl "https://api.rhea.finance/get_chain_prices?chain=eth"
|
|
85
|
+
curl "https://api.rhea.finance/get_chain_prices?chain=bsc"
|
|
86
|
+
curl "https://api.rhea.finance/get_chain_prices?chain=base"
|
|
54
87
|
```
|
|
55
88
|
|
|
56
|
-
`
|
|
89
|
+
`chain` is required and must be a **token query alias** (`eth`, `bsc`, `base`, …). A successful response uses `{ code, data, msg }`:
|
|
57
90
|
|
|
58
91
|
```ts
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
92
|
+
// code === 0 && msg === "success"
|
|
93
|
+
type ChainPricesResponse = {
|
|
94
|
+
code: number;
|
|
95
|
+
msg: string;
|
|
96
|
+
data: Record<
|
|
97
|
+
string,
|
|
98
|
+
{
|
|
99
|
+
address: string;
|
|
100
|
+
chainId: number;
|
|
101
|
+
decimals: number;
|
|
102
|
+
symbol: string;
|
|
103
|
+
name?: string;
|
|
104
|
+
price: string;
|
|
105
|
+
logoURI?: string;
|
|
106
|
+
updated_at?: number;
|
|
107
|
+
}
|
|
108
|
+
>;
|
|
109
|
+
};
|
|
110
|
+
```
|
|
64
111
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
112
|
+
Use this endpoint for same-chain token metadata and display prices. It is keyed by token address. It does not replace `get_multichain_lending_tokens_data` for the full multi-chain Trade selector, and some non-EVM aliases may return an empty `data` object.
|
|
113
|
+
|
|
114
|
+
## 1. What the SDK does
|
|
115
|
+
|
|
116
|
+
The recommended flow has only two steps:
|
|
117
|
+
|
|
118
|
+
```ts
|
|
119
|
+
const quote = await client.quote(quoteRequest);
|
|
120
|
+
const result = await client.swap({ quote });
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
The normalized object returned by `quote()` can be passed directly to `swap()`. Internally, `swap()` continues with `buildSwap()` and `executeSwap()`, then selects the registered executor that matches the execution type returned by the API. Applications do not need to determine:
|
|
124
|
+
|
|
125
|
+
- whether the swap is same-chain or cross-chain;
|
|
126
|
+
- which router is used;
|
|
127
|
+
- whether execution requires a transaction, a signed order, or a deposit transfer;
|
|
128
|
+
- whether an EVM approval is required;
|
|
129
|
+
- whether the flow is an MCA deposit, NEAR withdrawal, or relayer withdrawal.
|
|
130
|
+
|
|
131
|
+
The application only provides the request fields and the relevant wallet adapters. Do not modify `quote.buildContext` or rebuild a swap request from `quote.raw`.
|
|
132
|
+
|
|
133
|
+
## 2. Installation
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
pnpm add @rhea-finance/cross-chain-aggregation-dex
|
|
69
137
|
```
|
|
70
138
|
|
|
71
|
-
|
|
139
|
+
Node.js 16 or later is required. When running on Node.js 16 without a global `fetch`, inject a compatible implementation through `SwapClientConfig.fetch`.
|
|
140
|
+
|
|
141
|
+
## 3. Recommended: simple quote → swap flow
|
|
142
|
+
|
|
143
|
+
The example below swaps USDC on Base for USDC on Solana. All token amounts use base-unit decimal strings. For example, USDC has 6 decimals, so `"1000000"` represents 1 USDC.
|
|
144
|
+
|
|
145
|
+
### 3.1 Minimal EVM adapter
|
|
72
146
|
|
|
73
|
-
|
|
147
|
+
The SDK does not receive private keys and is not coupled to a specific wallet library. Wrap your wallet implementation in an adapter:
|
|
74
148
|
|
|
75
149
|
```ts
|
|
76
|
-
import { SwapClient } from "@rhea-finance/cross-chain-aggregation-dex";
|
|
77
150
|
import {
|
|
78
151
|
createEvmExecutor,
|
|
79
152
|
type EvmWalletAdapter,
|
|
80
153
|
} from "@rhea-finance/cross-chain-aggregation-dex/executors/evm";
|
|
81
154
|
|
|
82
|
-
const
|
|
83
|
-
|
|
84
|
-
signMessage: (message) => wallet.signMessage(message),
|
|
85
|
-
sendTransaction: async (tx) => {
|
|
155
|
+
const evmAdapter: EvmWalletAdapter = {
|
|
156
|
+
async sendTransaction(tx) {
|
|
86
157
|
const response = await wallet.sendTransaction({
|
|
87
158
|
to: tx.to,
|
|
88
159
|
data: tx.data,
|
|
@@ -91,25 +162,271 @@ const evmWallet: EvmWalletAdapter = {
|
|
|
91
162
|
});
|
|
92
163
|
return { txHash: response.hash, raw: response };
|
|
93
164
|
},
|
|
94
|
-
|
|
95
|
-
|
|
165
|
+
|
|
166
|
+
async signTypedData(request) {
|
|
167
|
+
return wallet.signTypedData(
|
|
96
168
|
request.typedData.domain,
|
|
97
169
|
request.typedData.types,
|
|
98
170
|
request.typedData.message
|
|
99
|
-
)
|
|
100
|
-
|
|
171
|
+
);
|
|
172
|
+
},
|
|
173
|
+
|
|
174
|
+
async waitForTransaction(txHash) {
|
|
175
|
+
return provider.waitForTransaction(txHash);
|
|
176
|
+
},
|
|
101
177
|
};
|
|
102
178
|
|
|
179
|
+
const evmExecutor = createEvmExecutor(evmAdapter);
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
The EVM executor does not read the currently connected chain. It uses `tx.chainId` from the API build response. The wallet should prompt the user or switch networks when sending the transaction.
|
|
183
|
+
|
|
184
|
+
### 3.2 Create a SwapClient
|
|
185
|
+
|
|
186
|
+
```ts
|
|
187
|
+
import { SwapClient } from "@rhea-finance/cross-chain-aggregation-dex";
|
|
188
|
+
|
|
103
189
|
const client = new SwapClient({
|
|
104
190
|
baseUrl: "https://api.rhea.finance",
|
|
105
|
-
getAccessToken,
|
|
106
|
-
executors: [
|
|
191
|
+
getAccessToken: () => sessionStorage.getItem("access-token") ?? "",
|
|
192
|
+
executors: [evmExecutor],
|
|
193
|
+
});
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
### 3.3 Request a quote
|
|
197
|
+
|
|
198
|
+
```ts
|
|
199
|
+
import type {
|
|
200
|
+
AssetRef,
|
|
201
|
+
QuoteRequest,
|
|
202
|
+
} from "@rhea-finance/cross-chain-aggregation-dex";
|
|
203
|
+
|
|
204
|
+
const baseUsdc: AssetRef = {
|
|
205
|
+
chain: "8453",
|
|
206
|
+
address: "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913",
|
|
207
|
+
symbol: "USDC",
|
|
208
|
+
decimals: 6,
|
|
209
|
+
};
|
|
210
|
+
|
|
211
|
+
const solanaUsdc: AssetRef = {
|
|
212
|
+
chain: "solana",
|
|
213
|
+
address: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
|
|
214
|
+
symbol: "USDC",
|
|
215
|
+
decimals: 6,
|
|
216
|
+
};
|
|
217
|
+
|
|
218
|
+
const quoteRequest: QuoteRequest = {
|
|
219
|
+
fromChain: "8453",
|
|
220
|
+
toChain: "solana",
|
|
221
|
+
tokenIn: baseUsdc,
|
|
222
|
+
tokenOut: solanaUsdc,
|
|
223
|
+
amountIn: "1000000",
|
|
224
|
+
slippageBps: 50,
|
|
225
|
+
quoteWaitingTimeMs: 3000,
|
|
226
|
+
sender: "0xYourBaseAddress",
|
|
227
|
+
recipient: "YourSolanaAddress",
|
|
228
|
+
};
|
|
229
|
+
|
|
230
|
+
const quote = await client.quote(quoteRequest);
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
`quote()` calls `POST /api/swap/quote`. `quoteWaitingTimeMs` is a quote API request parameter used by routes such as Near Intents to wait for a quote. It is not an on-chain RPC timeout. The SDK sends `3000` when the field is omitted.
|
|
234
|
+
|
|
235
|
+
### 3.4 Execute the swap directly
|
|
236
|
+
|
|
237
|
+
```ts
|
|
238
|
+
const result = await client.swap({
|
|
239
|
+
quote,
|
|
240
|
+
waitFor: "submitted",
|
|
241
|
+
beforeSign(preview) {
|
|
242
|
+
console.log("Wallet action requested", preview);
|
|
243
|
+
},
|
|
244
|
+
});
|
|
245
|
+
|
|
246
|
+
console.log(result.status, result.txHash, result.orderId);
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
`swap()` does not request another quote. It uses the `buildContext` stored in the quote to call the swap API, normalizes the build response, and invokes the matching executor.
|
|
250
|
+
|
|
251
|
+
The default `waitFor` mode is `"submitted"`. The method returns after the wallet successfully signs or submits the transaction. This does not mean the assets have arrived on the destination chain.
|
|
252
|
+
|
|
253
|
+
To let the SDK continue polling for final delivery:
|
|
254
|
+
|
|
255
|
+
```ts
|
|
256
|
+
const result = await client.swap({
|
|
257
|
+
quote,
|
|
258
|
+
waitFor: "completed",
|
|
259
|
+
});
|
|
260
|
+
|
|
261
|
+
if (result.status === "completed") {
|
|
262
|
+
console.log("Order completed");
|
|
263
|
+
}
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
`"completed"` polls the API only when the build response contains a queryable `orderId`. The default polling interval is 5 seconds and the default timeout is 250 seconds. A timeout throws `ORDER_TIMEOUT`, but it does not revert an already submitted on-chain transaction.
|
|
267
|
+
|
|
268
|
+
### 3.5 Check final delivery status
|
|
269
|
+
|
|
270
|
+
If the swap first returns with `"submitted"`, use the returned `orderId` to poll manually:
|
|
271
|
+
|
|
272
|
+
```ts
|
|
273
|
+
if (result.orderId) {
|
|
274
|
+
const finalStatus = await client.waitForOrder({
|
|
275
|
+
orderId: result.orderId,
|
|
276
|
+
router: result.router,
|
|
277
|
+
intervalMs: 5000,
|
|
278
|
+
timeoutMs: 250000,
|
|
279
|
+
});
|
|
280
|
+
|
|
281
|
+
console.log(finalStatus.status);
|
|
282
|
+
}
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
For a single status request:
|
|
286
|
+
|
|
287
|
+
```ts
|
|
288
|
+
const status = await client.getOrderStatus({
|
|
289
|
+
orderId: result.orderId!,
|
|
290
|
+
router: result.router,
|
|
107
291
|
});
|
|
108
292
|
```
|
|
109
293
|
|
|
110
|
-
|
|
294
|
+
Terminal statuses are `completed`, `failed`, `refunded`, and `expired`.
|
|
295
|
+
|
|
296
|
+
## 4. Simple-flow field reference
|
|
297
|
+
|
|
298
|
+
### 4.1 SwapClientConfig
|
|
299
|
+
|
|
300
|
+
| Field | Type | Required | Description and default |
|
|
301
|
+
| --- | --- | --- | --- |
|
|
302
|
+
| `baseUrl` | `string` | Yes | API base URL, for example `https://api.rhea.finance`. A trailing `/` is removed. |
|
|
303
|
+
| `apiKey` | `string` | No | API credential sent with requests. |
|
|
304
|
+
| `getAccessToken` | `() => string \| Promise<string>` | No | Reads an access token before each request. Use this for refreshable sessions. |
|
|
305
|
+
| `fetch` | `typeof globalThis.fetch` | No | Custom fetch implementation. The SDK binds its invocation context to avoid browser `Illegal invocation` errors. It is normally required on Node.js 16. |
|
|
306
|
+
| `headers` | `Record<string,string>` or function | No | Additional request headers. The function form may return a promise. |
|
|
307
|
+
| `timeoutMs` | `number` | No | Timeout for each HTTP request in milliseconds. Default: `15000`. |
|
|
308
|
+
| `retry` | `Partial<RetryConfig>` | No | Retry policy for retryable quote/read operations. Defaults: 2 retries, 250ms base delay, 2000ms maximum delay, and jitter enabled. |
|
|
309
|
+
| `logger` | `SdkLogger` | No | Receives structured `api.request`, `api.response`, and `api.retry` entries. |
|
|
310
|
+
| `executors` | `readonly ChainExecutor[]` | Required for execution | Wallet executors. May be omitted when only calling `quote()` or `buildSwap()`. |
|
|
311
|
+
| `maxQuoteAgeMs` | `number \| null` | No | Maximum local quote age in milliseconds. Default: `30000`. Set to `null` to disable the local age check; an API-provided `expiresAt` still applies. |
|
|
312
|
+
| `reportMode` | `"auto" \| "manual" \| "disabled"` | No | Reporting policy. Default: `"auto"`. A reporting failure does not turn a submitted swap into a failed swap. |
|
|
313
|
+
| `onEvent` | `(event) => void` | No | Receives all lifecycle events. |
|
|
314
|
+
| `now` | `() => number` | No | Custom millisecond clock, mainly for testing. Default: `Date.now`. |
|
|
315
|
+
|
|
316
|
+
### 4.2 AssetRef
|
|
317
|
+
|
|
318
|
+
| Field | Type | Required | Format and meaning |
|
|
319
|
+
| --- | --- | --- | --- |
|
|
320
|
+
| `chain` | `ChainRef` | Yes | The SDK uses one chain ID format everywhere. EVM chains use decimal strings, such as Base `"8453"`. Other values are `"solana"`, `"aptos"`, `"near"`, `"tron"`, `"btc"`, `"zcash"`, and `"sui"`. |
|
|
321
|
+
| `address` | `string` | Yes | Token contract address, mint, coin type, or the API-defined native-token identifier. |
|
|
322
|
+
| `symbol` | `string` | No | Display symbol. It is not used for calculations. |
|
|
323
|
+
| `decimals` | `number` | No | Token precision. Supplying it is recommended so applications can format and convert amounts correctly. |
|
|
324
|
+
| `isNative` | `boolean` | No | Whether the asset is the chain's native token. |
|
|
325
|
+
|
|
326
|
+
`tokenIn.chain` should match `fromChain`, and `tokenOut.chain` should match `toChain`.
|
|
327
|
+
|
|
328
|
+
### 4.3 QuoteRequest
|
|
329
|
+
|
|
330
|
+
| Field | Type | Required | Format and meaning |
|
|
331
|
+
| --- | --- | --- | --- |
|
|
332
|
+
| `fromChain` | `ChainRef` | Yes | Source chain ID, for example `"8453"`. |
|
|
333
|
+
| `toChain` | `ChainRef` | Yes | Destination chain ID, for example `"solana"`. |
|
|
334
|
+
| `tokenIn` | `AssetRef` | Yes | Asset being spent. |
|
|
335
|
+
| `tokenOut` | `AssetRef` | Yes | Asset being received. |
|
|
336
|
+
| `amountIn` | `string` | Yes | A non-negative base-unit decimal integer string. Do not pass `"1.5"` or scientific notation. |
|
|
337
|
+
| `slippageBps` | `number` | Yes | Slippage in basis points. `50` means 0.5%; `100` means 1%. |
|
|
338
|
+
| `quoteWaitingTimeMs` | `number` | No | Time the quote API may wait for route quotes, in milliseconds. Must be a non-negative integer. Default: `3000`. |
|
|
339
|
+
| `sender` | `string` | Yes | Sender address on the source chain. |
|
|
340
|
+
| `recipient` | `string` | No | Recipient address on the destination chain. Cross-chain requests should normally provide it explicitly. |
|
|
341
|
+
| `extensions` | `Record<string,unknown>` | No | Additional fields forwarded to the API. Regular applications should not use this to replace standard fields. |
|
|
342
|
+
|
|
343
|
+
Important normalized quote fields:
|
|
344
|
+
|
|
345
|
+
| Field | Meaning |
|
|
346
|
+
| --- | --- |
|
|
347
|
+
| `estimatedOut` | Estimated output amount as a base-unit string. |
|
|
348
|
+
| `minAmountOut` | Minimum output after slippage as a base-unit string. |
|
|
349
|
+
| `route.router` | Router selected by the SDK. Use it for display or diagnostics, not application-side execution branching. |
|
|
350
|
+
| `alternatives` | Normalized summaries of other available routes. |
|
|
351
|
+
| `receivedAt` / `expiresAt` | Millisecond timestamps used for quote freshness validation. |
|
|
352
|
+
| `buildContext` | Read-only context used by `swap()` and `buildSwap()`. Do not modify it. |
|
|
353
|
+
| `raw` | Original quote API `data`, useful for diagnostics or fields that are not normalized. |
|
|
354
|
+
|
|
355
|
+
### 4.4 SwapInput and WaitMode
|
|
356
|
+
|
|
357
|
+
| Field | Type | Required | Description |
|
|
358
|
+
| --- | --- | --- | --- |
|
|
359
|
+
| `quote` | `Quote` | Yes | The value returned by `client.quote()`. Pass it directly without modification. |
|
|
360
|
+
| `waitFor` | `"submitted" \| "source-confirmed" \| "completed"` | No | Default: `"submitted"`. |
|
|
361
|
+
| `signal` | `AbortSignal` | No | Cancels unfinished SDK requests or waits. It cannot withdraw an already broadcast transaction. |
|
|
362
|
+
| `onEvent` | `(event) => void` | No | Receives lifecycle events for this swap only. |
|
|
363
|
+
| `beforeSign` | `(preview) => void \| Promise<void>` | No | Called before each wallet signature or transaction request. It can be used for application confirmation UI. |
|
|
364
|
+
| `idempotencyKey` | `string` | No | Sent with the build request. Duplicate-execution protection is determined by the server. |
|
|
365
|
+
|
|
366
|
+
Wait modes:
|
|
367
|
+
|
|
368
|
+
| Mode | Return condition |
|
|
369
|
+
| --- | --- |
|
|
370
|
+
| `submitted` | Returns after the wallet signs or broadcasts the source action. |
|
|
371
|
+
| `source-confirmed` | Waits for source-chain confirmation when the executor provides a confirmation method; otherwise falls back to `submitted`. |
|
|
372
|
+
| `completed` | After source execution, polls the server until a delivery terminal state when an order reference exists. Without an order reference, it returns the source execution result. |
|
|
373
|
+
|
|
374
|
+
### 4.5 SwapExecutionResult
|
|
375
|
+
|
|
376
|
+
| Field | Type | Description |
|
|
377
|
+
| --- | --- | --- |
|
|
378
|
+
| `executionId` | `string` | Unique identifier for this SDK execution. |
|
|
379
|
+
| `status` | `string` | `submitted`, `source-confirmed`, `processing`, `completed`, `failed`, `refunded`, or `expired`. |
|
|
380
|
+
| `router` | `string` | Router used for execution. Pass it unchanged when querying order status. |
|
|
381
|
+
| `txHash` | `string?` | Hash of a single source-chain transaction. |
|
|
382
|
+
| `txHashes` | `string[]?` | Hashes of multiple source-chain transactions, such as a NEAR transaction batch. |
|
|
383
|
+
| `orderId` | `string?` | Server order identifier. When present, it can be passed to `waitForOrder()`. |
|
|
384
|
+
| `depositAddress` | `string?` | Cross-chain deposit address. |
|
|
385
|
+
| `report` | `object?` | Reporting state: `reported`, `failed`, or `skipped`. A report warning does not invalidate the source submission. |
|
|
386
|
+
| `raw` | `unknown` | Executor confirmation response or original swap API build data. |
|
|
387
|
+
|
|
388
|
+
`submitted` and `source-confirmed` do not mean that the destination assets have arrived. Use `waitFor: "completed"` or `waitForOrder()` to check final delivery.
|
|
389
|
+
|
|
390
|
+
## 5. Advanced: buildSwap → executeSwap
|
|
391
|
+
|
|
392
|
+
Use the advanced flow only when you need to inspect the build, pass it between processes, or separate building from wallet execution:
|
|
111
393
|
|
|
112
394
|
```ts
|
|
395
|
+
const quote = await client.quote(quoteRequest);
|
|
396
|
+
|
|
397
|
+
// Builds and normalizes the execution without opening a wallet.
|
|
398
|
+
const build = await client.buildSwap({
|
|
399
|
+
quote,
|
|
400
|
+
idempotencyKey: crypto.randomUUID(),
|
|
401
|
+
});
|
|
402
|
+
|
|
403
|
+
console.log(build.router, build.execution.kind, build.raw);
|
|
404
|
+
|
|
405
|
+
// Wallet execution can happen later.
|
|
406
|
+
const result = await client.executeSwap({
|
|
407
|
+
build,
|
|
408
|
+
waitFor: "submitted",
|
|
409
|
+
});
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
The following calls are equivalent:
|
|
413
|
+
|
|
414
|
+
```ts
|
|
415
|
+
await client.swap({ quote });
|
|
416
|
+
|
|
417
|
+
// Equivalent to:
|
|
418
|
+
const build = await client.buildSwap({ quote });
|
|
419
|
+
await client.executeSwap({ build });
|
|
420
|
+
```
|
|
421
|
+
|
|
422
|
+
`buildSwap()` does not require an executor. `executeSwap()` requires a registered executor that supports `build.execution.kind`. MCA relayer withdrawals include an SDK-managed message-signing and submission flow, so use `swap()` instead of splitting that flow.
|
|
423
|
+
|
|
424
|
+
## 6. Executor adapters
|
|
425
|
+
|
|
426
|
+
Import each chain executor from its dedicated subpath:
|
|
427
|
+
|
|
428
|
+
```ts
|
|
429
|
+
import { createEvmExecutor } from "@rhea-finance/cross-chain-aggregation-dex/executors/evm";
|
|
113
430
|
import { createSolanaExecutor } from "@rhea-finance/cross-chain-aggregation-dex/executors/solana";
|
|
114
431
|
import { createAptosExecutor } from "@rhea-finance/cross-chain-aggregation-dex/executors/aptos";
|
|
115
432
|
import { createNearExecutor } from "@rhea-finance/cross-chain-aggregation-dex/executors/near";
|
|
@@ -119,227 +436,249 @@ import { createZcashExecutor } from "@rhea-finance/cross-chain-aggregation-dex/e
|
|
|
119
436
|
import { createSuiExecutor } from "@rhea-finance/cross-chain-aggregation-dex/executors/sui";
|
|
120
437
|
```
|
|
121
438
|
|
|
122
|
-
|
|
439
|
+
| Chain | Supported execution kinds | Core adapter capabilities |
|
|
440
|
+
| --- | --- | --- |
|
|
441
|
+
| EVM | `evm-transaction`, `evm-signature` | `sendTransaction`, `signTypedData`; optional `waitForTransaction`. |
|
|
442
|
+
| Solana | `solana-transaction` | Submit a serialized transaction; optional confirmation wait. |
|
|
443
|
+
| Aptos | `aptos-entry-function` | Submit an entry function; optional confirmation wait. |
|
|
444
|
+
| NEAR | `near-transaction-batch` | Submit NEAR transactions sequentially or as a batch; optional confirmation wait. |
|
|
445
|
+
| Tron | `tron-transfer` | Submit a native-token or token transfer; optional confirmation wait. |
|
|
446
|
+
| Bitcoin | `bitcoin-transfer` | Submit a UTXO transfer. Configure `defaultFeeRate` when the build does not provide a fee rate. |
|
|
447
|
+
| Zcash | `zcash-transfer` | Submit a transparent-address transfer and return a real `txHash`; optional confirmation wait. |
|
|
448
|
+
| Sui | `sui-transfer` | Submit a coin transfer; optional confirmation wait. |
|
|
123
449
|
|
|
124
|
-
|
|
125
|
-
const bitcoinExecutor = createBitcoinExecutor(bitcoinWallet, {
|
|
126
|
-
defaultFeeRate: 4,
|
|
127
|
-
});
|
|
128
|
-
```
|
|
450
|
+
Zcash follows the same standard as every other chain: a successful wallet submission must return a real transaction hash. The SDK never invents a transaction hash.
|
|
129
451
|
|
|
130
|
-
|
|
452
|
+
For MCA quotes, the SDK may also read these methods from the registered executor:
|
|
131
453
|
|
|
132
|
-
`
|
|
454
|
+
- `getIdentityKey()` generates `mca.signer.identityKey` and is required for MCA quotes;
|
|
455
|
+
- `signMessage()` signs the exact API-provided message when required by an MCA relayer withdrawal.
|
|
133
456
|
|
|
134
|
-
|
|
457
|
+
These are adapter capabilities. Application code calling `client.swap()` does not pass a separate signer.
|
|
135
458
|
|
|
136
|
-
|
|
459
|
+
## 7. EVM approvals
|
|
137
460
|
|
|
138
|
-
|
|
461
|
+
When the swap API build response contains an `approval`, the EVM executor performs these steps in order:
|
|
139
462
|
|
|
140
|
-
|
|
463
|
+
1. Call the optional `isApprovalRequired(approval)` method. If it is not implemented, approval is assumed to be required.
|
|
464
|
+
2. Submit the approval transaction.
|
|
465
|
+
3. If the adapter implements `waitForTransaction`, wait for the approval transaction to confirm.
|
|
466
|
+
4. Submit the main swap transaction or request the EIP-712 signature.
|
|
141
467
|
|
|
142
|
-
|
|
468
|
+
Applications do not need to query allowances or inspect `needsApprove`. To avoid unnecessary approval transactions, implement `isApprovalRequired` in the adapter:
|
|
143
469
|
|
|
144
470
|
```ts
|
|
145
|
-
const
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
tokenIn: ethereumUsdc,
|
|
151
|
-
tokenOut: mcaUsdc,
|
|
152
|
-
amountIn: "1000000",
|
|
153
|
-
slippageBps: 50,
|
|
154
|
-
sender: "0x...",
|
|
155
|
-
recipient: "account.near",
|
|
156
|
-
signerChain: "evm",
|
|
157
|
-
collateral: {
|
|
158
|
-
useAsCollateral: true,
|
|
471
|
+
const evmAdapter: EvmWalletAdapter = {
|
|
472
|
+
// ...sendTransaction, signTypedData, and other methods
|
|
473
|
+
async isApprovalRequired(approval) {
|
|
474
|
+
const allowance = await readAllowance(approval.spender);
|
|
475
|
+
return allowance < requiredAmount;
|
|
159
476
|
},
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
const result = await client.swap({ quote, waitFor: "completed" });
|
|
477
|
+
};
|
|
163
478
|
```
|
|
164
479
|
|
|
165
|
-
The
|
|
480
|
+
The lifecycle emits `approval-requested`, `approval-submitted`, and the subsequent signing or submission events in order.
|
|
481
|
+
|
|
482
|
+
## 8. MCA deposits and withdrawals
|
|
166
483
|
|
|
167
|
-
|
|
484
|
+
MCA flows use the same `client.quote()` and `client.swap()` methods. The `flow` field distinguishes deposits from withdrawals. Applications do not branch on the returned router.
|
|
168
485
|
|
|
169
|
-
|
|
486
|
+
Common MCA fields:
|
|
487
|
+
|
|
488
|
+
| Field | Type | Required | Description |
|
|
489
|
+
| --- | --- | --- | --- |
|
|
490
|
+
| `flow` | `"deposit" \| "withdraw"` | Yes | MCA operation. |
|
|
491
|
+
| `mcaAccountId` | `string` | Yes | NEAR account ID of the MCA. |
|
|
492
|
+
| `signerChain` | `McaSignerChain` | Yes | Selects the registered executor that supplies identity and signing capabilities. |
|
|
493
|
+
| `recipientMsgSignatures` | `string[]` | No | Existing recipient-message signatures forwarded in the MCA payload. |
|
|
494
|
+
| `depositSignerProofSignatures` | `string[]` | No | Existing deposit-signer-proof signatures forwarded in the MCA payload. |
|
|
495
|
+
|
|
496
|
+
### Deposit
|
|
170
497
|
|
|
171
498
|
```ts
|
|
172
499
|
const quote = await client.quote({
|
|
173
|
-
flow: "
|
|
500
|
+
flow: "deposit",
|
|
174
501
|
mcaAccountId: "account.near",
|
|
175
|
-
|
|
502
|
+
signerChain: "evm",
|
|
503
|
+
fromChain: "42161",
|
|
176
504
|
toChain: "near",
|
|
177
|
-
tokenIn:
|
|
178
|
-
tokenOut:
|
|
505
|
+
tokenIn: arbitrumUsdc,
|
|
506
|
+
tokenOut: mcaUsdc,
|
|
179
507
|
amountIn: "1000000",
|
|
180
508
|
slippageBps: 50,
|
|
181
|
-
sender: "
|
|
182
|
-
recipient: "
|
|
183
|
-
signerChain: "near",
|
|
509
|
+
sender: "0xYourAddress",
|
|
510
|
+
recipient: "account.near",
|
|
184
511
|
collateral: {
|
|
185
|
-
|
|
186
|
-
decreaseAmountBurrow: "0",
|
|
512
|
+
useAsCollateral: true,
|
|
187
513
|
},
|
|
188
|
-
executionPreference: "near",
|
|
189
|
-
boundNearAccountId: "alice.near",
|
|
190
514
|
});
|
|
191
515
|
|
|
192
|
-
await client.swap({ quote, waitFor: "completed" });
|
|
516
|
+
const result = await client.swap({ quote, waitFor: "completed" });
|
|
193
517
|
```
|
|
194
518
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
### Withdraw through the multichain relayer
|
|
519
|
+
`collateral.useAsCollateral` is a required boolean that specifies whether the deposited asset should be used as Burrow collateral.
|
|
198
520
|
|
|
199
|
-
|
|
521
|
+
### Withdraw
|
|
200
522
|
|
|
201
523
|
```ts
|
|
202
524
|
const quote = await client.quote({
|
|
203
525
|
flow: "withdraw",
|
|
204
526
|
mcaAccountId: "account.near",
|
|
527
|
+
signerChain: "evm",
|
|
205
528
|
fromChain: "near",
|
|
206
|
-
toChain: "
|
|
529
|
+
toChain: "8453",
|
|
207
530
|
tokenIn: mcaUsdc,
|
|
208
|
-
tokenOut:
|
|
531
|
+
tokenOut: baseUsdc,
|
|
209
532
|
amountIn: "1000000",
|
|
210
533
|
slippageBps: 50,
|
|
211
534
|
sender: "account.near",
|
|
212
|
-
recipient:
|
|
213
|
-
signerChain: "evm",
|
|
535
|
+
recipient: "0xYourBaseAddress",
|
|
214
536
|
collateral: {
|
|
215
537
|
needDecrease: true,
|
|
216
|
-
decreaseAmountBurrow: "
|
|
217
|
-
withdrawAll:
|
|
538
|
+
decreaseAmountBurrow: "1.0",
|
|
539
|
+
withdrawAll: false,
|
|
218
540
|
},
|
|
219
541
|
executionPreference: "relayer",
|
|
220
542
|
});
|
|
221
543
|
|
|
222
|
-
await client.swap({
|
|
544
|
+
const result = await client.swap({
|
|
223
545
|
quote,
|
|
224
546
|
waitFor: "completed",
|
|
225
547
|
beforeSign(preview) {
|
|
226
|
-
|
|
548
|
+
console.log("MCA message signature preview", preview);
|
|
227
549
|
},
|
|
228
550
|
});
|
|
229
551
|
```
|
|
230
552
|
|
|
231
|
-
|
|
553
|
+
Withdraw-only fields:
|
|
232
554
|
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
555
|
+
| Field | Type | Required | Description |
|
|
556
|
+
| --- | --- | --- | --- |
|
|
557
|
+
| `collateral.needDecrease` | `boolean` | Yes | Whether Burrow collateral must be decreased. |
|
|
558
|
+
| `collateral.decreaseAmountBurrow` | `string` | Yes | Human-readable Burrow decimal amount, such as `"1.0"`. This is not a token base-unit amount. |
|
|
559
|
+
| `collateral.withdrawAll` | `boolean` | No | Whether to withdraw the full available amount. |
|
|
560
|
+
| `executionPreference` | `"auto" \| "near" \| "relayer"` | No | Default: `"auto"`. Set explicitly to force direct NEAR or relayer execution. |
|
|
561
|
+
| `boundNearAccountId` | `string` | Required for automatic NEAR selection | In `auto` mode, direct NEAR execution is selected only when `toChain === "near"` and `recipient` exactly matches this field. Otherwise, the relayer is selected. |
|
|
240
562
|
|
|
241
|
-
|
|
242
|
-
```
|
|
563
|
+
For direct NEAR execution, the NEAR executor submits `nearMcaWithdrawTx`. For relayer execution, the executor selected by `signerChain` uses `signMessage()` to sign the API-provided `messageToSign`, after which the SDK submits the order. Application code only calls `swap()`.
|
|
243
564
|
|
|
244
|
-
|
|
565
|
+
## 9. Lifecycle, errors, and cancellation
|
|
245
566
|
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
The SDK does not fetch a lending portfolio. Pass collateral decisions explicitly, or calculate the API fields from data already held by the application:
|
|
567
|
+
Lifecycle events can be observed globally on the client or for an individual swap:
|
|
249
568
|
|
|
250
569
|
```ts
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
isMax: false,
|
|
570
|
+
const client = new SwapClient({
|
|
571
|
+
baseUrl: "https://api.rhea.finance",
|
|
572
|
+
executors: [evmExecutor],
|
|
573
|
+
onEvent(event) {
|
|
574
|
+
console.log("Swap lifecycle", event);
|
|
575
|
+
},
|
|
258
576
|
});
|
|
259
577
|
```
|
|
260
578
|
|
|
261
|
-
|
|
579
|
+
Events may cover build, approval, signing, submission, source confirmation, order status, completion, warnings, and failures.
|
|
262
580
|
|
|
263
|
-
|
|
581
|
+
SDK errors use the `SwapSdkError` type:
|
|
264
582
|
|
|
265
583
|
```ts
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
584
|
+
import { SwapSdkError } from "@rhea-finance/cross-chain-aggregation-dex";
|
|
585
|
+
|
|
586
|
+
try {
|
|
587
|
+
await client.swap({ quote });
|
|
588
|
+
} catch (error) {
|
|
589
|
+
if (error instanceof SwapSdkError) {
|
|
590
|
+
console.error({
|
|
591
|
+
code: error.code,
|
|
592
|
+
stage: error.stage,
|
|
593
|
+
message: error.message,
|
|
594
|
+
retryable: error.retryable,
|
|
595
|
+
cause: error.cause,
|
|
596
|
+
details: error.details,
|
|
597
|
+
});
|
|
598
|
+
}
|
|
599
|
+
}
|
|
269
600
|
```
|
|
270
601
|
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
## API surfaces
|
|
274
|
-
|
|
275
|
-
Normalized methods:
|
|
276
|
-
|
|
277
|
-
- `quote()`
|
|
278
|
-
- `buildSwap()`
|
|
279
|
-
- `executeSwap()` and `swap()`
|
|
280
|
-
- `getOrderStatus()` and `waitForOrder()`
|
|
281
|
-
- `report()` and `retryReport()`
|
|
282
|
-
- `getHistory()`
|
|
283
|
-
|
|
284
|
-
Raw methods preserve the unified API `data` shape:
|
|
602
|
+
Common `stage` values are `quote`, `build`, `approve`, `sign`, `broadcast`, `submit`, `report`, `status`, and `history`. Common `code` values include `QUOTE_EXPIRED`, `USER_REJECTED`, `APPROVAL_FAILED`, `SIGNING_FAILED`, `BROADCAST_FAILED`, and `ORDER_TIMEOUT`.
|
|
285
603
|
|
|
286
|
-
|
|
287
|
-
- `buildRaw()`
|
|
288
|
-
- `submitOrderRaw()`
|
|
289
|
-
- `getOrderStatusRaw()`
|
|
290
|
-
- `reportRaw()`
|
|
291
|
-
- `getHistoryRaw()`
|
|
604
|
+
Pass an `AbortSignal` to stop an unfinished request or wait:
|
|
292
605
|
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
- `solana-transaction`
|
|
300
|
-
- `aptos-entry-function`
|
|
301
|
-
- `near-transaction-batch`
|
|
302
|
-
- `tron-transfer`
|
|
303
|
-
- `bitcoin-transfer`
|
|
304
|
-
- `zcash-transfer`
|
|
305
|
-
- `sui-transfer`
|
|
306
|
-
|
|
307
|
-
The SDK core defines the executor contract and registry. Wallet-specific implementations are injected by the application, so importing the package does not access browser wallet globals.
|
|
308
|
-
|
|
309
|
-
## Runtime and credentials
|
|
310
|
-
|
|
311
|
-
- Browsers and Node.js 18+ use the global Fetch API.
|
|
312
|
-
- Node.js 16 requires a compatible `fetch` implementation through `new SwapClient({ fetch })`.
|
|
313
|
-
- Supply credentials with `apiKey` or `getAccessToken`; when both are present, `getAccessToken` takes precedence.
|
|
314
|
-
- The package contains no fixed API credential and never manages private keys or wallet recovery phrases.
|
|
315
|
-
- Use `AbortSignal` on network, build, execute, and polling calls when cancellation is required.
|
|
606
|
+
```ts
|
|
607
|
+
const controller = new AbortController();
|
|
608
|
+
const promise = client.swap({ quote, signal: controller.signal });
|
|
609
|
+
controller.abort();
|
|
610
|
+
await promise;
|
|
611
|
+
```
|
|
316
612
|
|
|
317
|
-
|
|
613
|
+
Cancellation only stops the SDK's current work. It cannot revert an approval, signature, or transaction that has already been submitted.
|
|
318
614
|
|
|
319
|
-
|
|
615
|
+
## 10. Retries, logging, and credentials
|
|
320
616
|
|
|
321
617
|
```ts
|
|
322
618
|
const client = new SwapClient({
|
|
323
619
|
baseUrl: "https://api.rhea.finance",
|
|
620
|
+
getAccessToken: async () => authStore.getToken(),
|
|
324
621
|
retry: {
|
|
325
622
|
maxRetries: 2,
|
|
326
623
|
baseDelayMs: 250,
|
|
327
|
-
maxDelayMs:
|
|
624
|
+
maxDelayMs: 2000,
|
|
328
625
|
jitter: true,
|
|
329
626
|
},
|
|
330
627
|
logger: {
|
|
331
628
|
log(entry) {
|
|
332
|
-
|
|
629
|
+
console.log("SDK API", entry);
|
|
333
630
|
},
|
|
334
631
|
},
|
|
335
632
|
});
|
|
336
633
|
```
|
|
337
634
|
|
|
338
|
-
|
|
635
|
+
The SDK automatically retries only retryable quote/read operations. It does not automatically retry build, broadcast, or order-submission operations that could execute twice. Network failures preserve the underlying error name and message to help diagnose CORS failures, connection resets, timeouts, or fetch invocation problems.
|
|
636
|
+
|
|
637
|
+
## 11. Raw API, reporting, and history
|
|
638
|
+
|
|
639
|
+
Most applications should use normalized methods. Use the Raw API only when the complete original server fields are required:
|
|
640
|
+
|
|
641
|
+
```ts
|
|
642
|
+
await client.quoteRaw(rawQuoteRequest);
|
|
643
|
+
await client.buildRaw(rawBuildRequest);
|
|
644
|
+
await client.submitOrderRaw(rawSubmitRequest);
|
|
645
|
+
await client.getOrderStatusRaw(rawStatusRequest);
|
|
646
|
+
await client.reportRaw(rawReportRequest);
|
|
647
|
+
await client.getHistoryRaw(rawHistoryRequest);
|
|
648
|
+
```
|
|
649
|
+
|
|
650
|
+
The default reporting mode is `reportMode: "auto"`. If a swap succeeds but reporting fails, `result.report.status` is `"failed"` and a warning is emitted. The SDK does not throw a misleading swap failure. For manual reporting:
|
|
651
|
+
|
|
652
|
+
```ts
|
|
653
|
+
const client = new SwapClient({
|
|
654
|
+
baseUrl: "https://api.rhea.finance",
|
|
655
|
+
executors: [evmExecutor],
|
|
656
|
+
reportMode: "manual",
|
|
657
|
+
});
|
|
658
|
+
|
|
659
|
+
const result = await client.swap({ quote });
|
|
660
|
+
await client.report(result);
|
|
661
|
+
|
|
662
|
+
// Retry after a reporting failure:
|
|
663
|
+
await client.retryReport(result);
|
|
664
|
+
```
|
|
665
|
+
|
|
666
|
+
Query history with:
|
|
339
667
|
|
|
340
|
-
|
|
668
|
+
```ts
|
|
669
|
+
const history = await client.getHistory({
|
|
670
|
+
sender: "0xYourAddress",
|
|
671
|
+
page: 1,
|
|
672
|
+
pageSize: 20,
|
|
673
|
+
status: ["processing", "completed"],
|
|
674
|
+
});
|
|
675
|
+
```
|
|
341
676
|
|
|
342
|
-
|
|
677
|
+
The SDK applies `status` filtering locally. The returned page has `filteredLocally: true`.
|
|
678
|
+
|
|
679
|
+
## 12. Amount utilities
|
|
680
|
+
|
|
681
|
+
Avoid JavaScript floating-point arithmetic for token amounts:
|
|
343
682
|
|
|
344
683
|
```ts
|
|
345
684
|
import {
|
|
@@ -347,16 +686,8 @@ import {
|
|
|
347
686
|
parseUnits,
|
|
348
687
|
} from "@rhea-finance/cross-chain-aggregation-dex";
|
|
349
688
|
|
|
350
|
-
parseUnits("1.25", 6);
|
|
689
|
+
parseUnits("1.25", 6); // "1250000"
|
|
351
690
|
formatUnits("1250000", 6); // "1.25"
|
|
352
691
|
```
|
|
353
692
|
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
## History filtering
|
|
357
|
-
|
|
358
|
-
The service handles sender and pagination. `getHistory({ status })` filters the current returned page locally and sets `filteredLocally: true`; server totals remain unchanged.
|
|
359
|
-
|
|
360
|
-
## License
|
|
361
|
-
|
|
362
|
-
MIT
|
|
693
|
+
`parseUnits()` rejects fractional precision beyond the token's decimals. `formatUnits()` accepts only non-negative base-unit decimal integer strings.
|