@rhea-finance/cross-chain-aggregation-dex 2.0.1 → 2.0.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.
- package/README.md +567 -206
- package/dist/executors/aptos.d.mts +3 -4
- package/dist/executors/aptos.d.ts +3 -4
- package/dist/executors/aptos.js +22 -2
- package/dist/executors/aptos.js.map +1 -1
- package/dist/executors/aptos.mjs +22 -2
- package/dist/executors/aptos.mjs.map +1 -1
- package/dist/executors/bitcoin.d.mts +3 -4
- package/dist/executors/bitcoin.d.ts +3 -4
- package/dist/executors/bitcoin.js +22 -2
- package/dist/executors/bitcoin.js.map +1 -1
- package/dist/executors/bitcoin.mjs +22 -2
- package/dist/executors/bitcoin.mjs.map +1 -1
- package/dist/executors/evm.d.mts +3 -4
- package/dist/executors/evm.d.ts +3 -4
- package/dist/executors/evm.js +29 -13
- package/dist/executors/evm.js.map +1 -1
- package/dist/executors/evm.mjs +29 -13
- package/dist/executors/evm.mjs.map +1 -1
- package/dist/executors/near.d.mts +3 -4
- package/dist/executors/near.d.ts +3 -4
- package/dist/executors/near.js +22 -2
- package/dist/executors/near.js.map +1 -1
- package/dist/executors/near.mjs +22 -2
- package/dist/executors/near.mjs.map +1 -1
- package/dist/executors/solana.d.mts +3 -4
- package/dist/executors/solana.d.ts +3 -4
- package/dist/executors/solana.js +22 -2
- package/dist/executors/solana.js.map +1 -1
- package/dist/executors/solana.mjs +22 -2
- package/dist/executors/solana.mjs.map +1 -1
- package/dist/executors/sui.d.mts +3 -4
- package/dist/executors/sui.d.ts +3 -4
- package/dist/executors/sui.js +22 -2
- package/dist/executors/sui.js.map +1 -1
- package/dist/executors/sui.mjs +22 -2
- package/dist/executors/sui.mjs.map +1 -1
- package/dist/executors/tron.d.mts +3 -4
- package/dist/executors/tron.d.ts +3 -4
- package/dist/executors/tron.js +22 -2
- package/dist/executors/tron.js.map +1 -1
- package/dist/executors/tron.mjs +22 -2
- package/dist/executors/tron.mjs.map +1 -1
- package/dist/executors/zcash.d.mts +4 -5
- package/dist/executors/zcash.d.ts +4 -5
- package/dist/executors/zcash.js +24 -10
- package/dist/executors/zcash.js.map +1 -1
- package/dist/executors/zcash.mjs +24 -10
- package/dist/executors/zcash.mjs.map +1 -1
- package/dist/index.d.mts +4 -3
- package/dist/index.d.ts +4 -3
- package/dist/index.js +59 -25
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +59 -25
- package/dist/index.mjs.map +1 -1
- package/dist/{registry-DRYUqs7T.d.mts → shared-BEZXY_BM.d.mts} +39 -12
- package/dist/{registry-DRYUqs7T.d.ts → shared-BEZXY_BM.d.ts} +39 -12
- package/package.json +4 -1
- package/dist/shared-BdH3hWuP.d.ts +0 -23
- package/dist/shared-BqpFeosz.d.mts +0 -23
package/README.md
CHANGED
|
@@ -1,117 +1,455 @@
|
|
|
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 });
|
|
69
121
|
```
|
|
70
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
|
|
71
134
|
|
|
135
|
+
```bash
|
|
136
|
+
pnpm add @rhea-finance/cross-chain-aggregation-dex
|
|
137
|
+
```
|
|
72
138
|
|
|
73
|
-
|
|
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`.
|
|
74
140
|
|
|
75
|
-
|
|
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
|
|
146
|
+
|
|
147
|
+
The SDK does not receive private keys and is not coupled to a specific wallet library. Wrap your wallet implementation in an adapter:
|
|
76
148
|
|
|
77
149
|
```ts
|
|
78
|
-
import { SwapClient } from "@rhea-finance/cross-chain-aggregation-dex";
|
|
79
150
|
import {
|
|
80
151
|
createEvmExecutor,
|
|
81
152
|
type EvmWalletAdapter,
|
|
82
153
|
} from "@rhea-finance/cross-chain-aggregation-dex/executors/evm";
|
|
83
154
|
|
|
84
|
-
const
|
|
85
|
-
|
|
86
|
-
signMessage: (message) => wallet.signMessage(message),
|
|
87
|
-
sendTransaction: async (tx) => {
|
|
155
|
+
const evmAdapter: EvmWalletAdapter = {
|
|
156
|
+
async sendTransaction(tx) {
|
|
88
157
|
const response = await wallet.sendTransaction({
|
|
89
158
|
to: tx.to,
|
|
90
159
|
data: tx.data,
|
|
91
160
|
value: tx.value,
|
|
92
161
|
gasLimit: tx.gasLimit,
|
|
162
|
+
gasPrice: tx.gasPrice,
|
|
163
|
+
maxFeePerGas: tx.maxFeePerGas,
|
|
164
|
+
maxPriorityFeePerGas: tx.maxPriorityFeePerGas,
|
|
93
165
|
});
|
|
94
166
|
return { txHash: response.hash, raw: response };
|
|
95
167
|
},
|
|
96
|
-
|
|
97
|
-
|
|
168
|
+
|
|
169
|
+
async signTypedData(request) {
|
|
170
|
+
return wallet.signTypedData(
|
|
98
171
|
request.typedData.domain,
|
|
99
172
|
request.typedData.types,
|
|
100
173
|
request.typedData.message
|
|
101
|
-
)
|
|
102
|
-
|
|
174
|
+
);
|
|
175
|
+
},
|
|
176
|
+
|
|
177
|
+
async waitForTransaction(txHash) {
|
|
178
|
+
const receipt = await provider.waitForTransaction(txHash);
|
|
179
|
+
return {
|
|
180
|
+
status: receipt?.status === 1 ? "confirmed" : "failed",
|
|
181
|
+
raw: receipt,
|
|
182
|
+
};
|
|
183
|
+
},
|
|
103
184
|
};
|
|
104
185
|
|
|
186
|
+
const evmExecutor = createEvmExecutor(evmAdapter);
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
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.
|
|
190
|
+
|
|
191
|
+
The build normalizer accepts EVM chain IDs as numbers, decimal strings, or JSON-RPC hexadecimal strings and exposes them to the adapter as numbers. It also preserves `from`, `gasPrice`, `maxFeePerGas`, and `maxPriorityFeePerGas`. For standard ERC-20 approval calldata, the SDK treats the encoded allowance spender as authoritative when the API's separate `approve.spender` field is inconsistent.
|
|
192
|
+
|
|
193
|
+
### 3.2 Create a SwapClient
|
|
194
|
+
|
|
195
|
+
```ts
|
|
196
|
+
import { SwapClient } from "@rhea-finance/cross-chain-aggregation-dex";
|
|
197
|
+
|
|
105
198
|
const client = new SwapClient({
|
|
106
199
|
baseUrl: "https://api.rhea.finance",
|
|
107
|
-
getAccessToken,
|
|
108
|
-
executors: [
|
|
200
|
+
getAccessToken: () => sessionStorage.getItem("access-token") ?? "",
|
|
201
|
+
executors: [evmExecutor],
|
|
202
|
+
});
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
### 3.3 Request a quote
|
|
206
|
+
|
|
207
|
+
```ts
|
|
208
|
+
import type {
|
|
209
|
+
AssetRef,
|
|
210
|
+
QuoteRequest,
|
|
211
|
+
} from "@rhea-finance/cross-chain-aggregation-dex";
|
|
212
|
+
|
|
213
|
+
const baseUsdc: AssetRef = {
|
|
214
|
+
chain: "8453",
|
|
215
|
+
address: "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913",
|
|
216
|
+
symbol: "USDC",
|
|
217
|
+
decimals: 6,
|
|
218
|
+
};
|
|
219
|
+
|
|
220
|
+
const solanaUsdc: AssetRef = {
|
|
221
|
+
chain: "solana",
|
|
222
|
+
address: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
|
|
223
|
+
symbol: "USDC",
|
|
224
|
+
decimals: 6,
|
|
225
|
+
};
|
|
226
|
+
|
|
227
|
+
const quoteRequest: QuoteRequest = {
|
|
228
|
+
fromChain: "8453",
|
|
229
|
+
toChain: "solana",
|
|
230
|
+
tokenIn: baseUsdc,
|
|
231
|
+
tokenOut: solanaUsdc,
|
|
232
|
+
amountIn: "1000000",
|
|
233
|
+
slippageBps: 50,
|
|
234
|
+
quoteWaitingTimeMs: 3000,
|
|
235
|
+
sender: "0xYourBaseAddress",
|
|
236
|
+
recipient: "YourSolanaAddress",
|
|
237
|
+
};
|
|
238
|
+
|
|
239
|
+
const quote = await client.quote(quoteRequest);
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
`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.
|
|
243
|
+
|
|
244
|
+
### 3.4 Execute the swap directly
|
|
245
|
+
|
|
246
|
+
```ts
|
|
247
|
+
const result = await client.swap({
|
|
248
|
+
quote,
|
|
249
|
+
waitFor: "submitted",
|
|
250
|
+
beforeSign(preview) {
|
|
251
|
+
console.log("Wallet action requested", preview);
|
|
252
|
+
},
|
|
109
253
|
});
|
|
254
|
+
|
|
255
|
+
console.log(result.status, result.txHash, result.orderId);
|
|
110
256
|
```
|
|
111
257
|
|
|
112
|
-
|
|
258
|
+
`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.
|
|
259
|
+
|
|
260
|
+
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.
|
|
261
|
+
|
|
262
|
+
To let the SDK continue polling for final delivery:
|
|
113
263
|
|
|
114
264
|
```ts
|
|
265
|
+
const result = await client.swap({
|
|
266
|
+
quote,
|
|
267
|
+
waitFor: "completed",
|
|
268
|
+
orderPolling: {
|
|
269
|
+
intervalMs: 5000,
|
|
270
|
+
timeoutMs: 600000,
|
|
271
|
+
},
|
|
272
|
+
});
|
|
273
|
+
|
|
274
|
+
if (result.status === "completed") {
|
|
275
|
+
console.log("Order completed");
|
|
276
|
+
}
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
`"completed"` polls the API only when the build response contains a queryable `orderId`. The default polling interval is 5 seconds. There is no default polling timeout, so polling continues until the order reaches a terminal state or the supplied `AbortSignal` is aborted.
|
|
280
|
+
|
|
281
|
+
Set `orderPolling.timeoutMs` only when the application needs a time limit. An explicit timeout throws `ORDER_TIMEOUT`, but it does not revert an already submitted on-chain transaction.
|
|
282
|
+
|
|
283
|
+
### 3.5 Check final delivery status
|
|
284
|
+
|
|
285
|
+
If the swap first returns with `"submitted"`, use the returned `orderId` to poll manually:
|
|
286
|
+
|
|
287
|
+
```ts
|
|
288
|
+
if (result.orderId) {
|
|
289
|
+
const finalStatus = await client.waitForOrder({
|
|
290
|
+
orderId: result.orderId,
|
|
291
|
+
router: result.router,
|
|
292
|
+
intervalMs: 5000,
|
|
293
|
+
timeoutMs: 600000,
|
|
294
|
+
});
|
|
295
|
+
|
|
296
|
+
console.log(finalStatus.status);
|
|
297
|
+
}
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
For a single status request:
|
|
301
|
+
|
|
302
|
+
```ts
|
|
303
|
+
const status = await client.getOrderStatus({
|
|
304
|
+
orderId: result.orderId!,
|
|
305
|
+
router: result.router,
|
|
306
|
+
});
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
Terminal statuses are `completed`, `failed`, `refunded`, and `expired`.
|
|
310
|
+
|
|
311
|
+
## 4. Simple-flow field reference
|
|
312
|
+
|
|
313
|
+
### 4.1 SwapClientConfig
|
|
314
|
+
|
|
315
|
+
| Field | Type | Required | Description and default |
|
|
316
|
+
| --- | --- | --- | --- |
|
|
317
|
+
| `baseUrl` | `string` | Yes | API base URL, for example `https://api.rhea.finance`. A trailing `/` is removed. |
|
|
318
|
+
| `apiKey` | `string` | No | API credential sent with requests. |
|
|
319
|
+
| `getAccessToken` | `() => string \| Promise<string>` | No | Reads an access token before each request. Use this for refreshable sessions. |
|
|
320
|
+
| `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. |
|
|
321
|
+
| `headers` | `Record<string,string>` or function | No | Additional request headers. The function form may return a promise. |
|
|
322
|
+
| `timeoutMs` | `number` | No | Timeout for each HTTP request in milliseconds. Default: `15000`. |
|
|
323
|
+
| `retry` | `Partial<RetryConfig>` | No | Retry policy for retryable quote/read operations. Defaults: 2 retries, 250ms base delay, 2000ms maximum delay, and jitter enabled. |
|
|
324
|
+
| `logger` | `SdkLogger` | No | Receives structured `api.request`, `api.response`, and `api.retry` entries. |
|
|
325
|
+
| `executors` | `readonly ChainExecutor[]` | Required for execution | Wallet executors. May be omitted when only calling `quote()` or `buildSwap()`. |
|
|
326
|
+
| `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. |
|
|
327
|
+
| `reportMode` | `"auto" \| "manual" \| "disabled"` | No | Reporting policy. Default: `"auto"`. A reporting failure does not turn a submitted swap into a failed swap. |
|
|
328
|
+
| `onEvent` | `(event) => void` | No | Receives all lifecycle events. |
|
|
329
|
+
| `now` | `() => number` | No | Custom millisecond clock, mainly for testing. Default: `Date.now`. |
|
|
330
|
+
|
|
331
|
+
### 4.2 AssetRef
|
|
332
|
+
|
|
333
|
+
| Field | Type | Required | Format and meaning |
|
|
334
|
+
| --- | --- | --- | --- |
|
|
335
|
+
| `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"`. |
|
|
336
|
+
| `address` | `string` | Yes | Token contract address, mint, coin type, or the API-defined native-token identifier. |
|
|
337
|
+
| `symbol` | `string` | No | Display symbol. It is not used for calculations. |
|
|
338
|
+
| `decimals` | `number` | No | Token precision. Supplying it is recommended so applications can format and convert amounts correctly. |
|
|
339
|
+
| `isNative` | `boolean` | No | Whether the asset is the chain's native token. |
|
|
340
|
+
|
|
341
|
+
`tokenIn.chain` should match `fromChain`, and `tokenOut.chain` should match `toChain`.
|
|
342
|
+
|
|
343
|
+
### 4.3 QuoteRequest
|
|
344
|
+
|
|
345
|
+
| Field | Type | Required | Format and meaning |
|
|
346
|
+
| --- | --- | --- | --- |
|
|
347
|
+
| `fromChain` | `ChainRef` | Yes | Source chain ID, for example `"8453"`. |
|
|
348
|
+
| `toChain` | `ChainRef` | Yes | Destination chain ID, for example `"solana"`. |
|
|
349
|
+
| `tokenIn` | `AssetRef` | Yes | Asset being spent. |
|
|
350
|
+
| `tokenOut` | `AssetRef` | Yes | Asset being received. |
|
|
351
|
+
| `amountIn` | `string` | Yes | A non-negative base-unit decimal integer string. Do not pass `"1.5"` or scientific notation. |
|
|
352
|
+
| `slippageBps` | `number` | Yes | Slippage in basis points. `50` means 0.5%; `100` means 1%. |
|
|
353
|
+
| `quoteWaitingTimeMs` | `number` | No | Time the quote API may wait for route quotes, in milliseconds. Must be a non-negative integer. Default: `3000`. |
|
|
354
|
+
| `sender` | `string` | Yes | Sender address on the source chain. |
|
|
355
|
+
| `recipient` | `string` | No | Recipient address on the destination chain. Cross-chain requests should normally provide it explicitly. |
|
|
356
|
+
| `extensions` | `Record<string,unknown>` | No | Additional fields forwarded to the API. Regular applications should not use this to replace standard fields. |
|
|
357
|
+
|
|
358
|
+
Important normalized quote fields:
|
|
359
|
+
|
|
360
|
+
| Field | Meaning |
|
|
361
|
+
| --- | --- |
|
|
362
|
+
| `estimatedOut` | Estimated output amount as a base-unit string. |
|
|
363
|
+
| `minAmountOut` | Minimum output after slippage as a base-unit string. |
|
|
364
|
+
| `route.router` | Router selected by the SDK. Use it for display or diagnostics, not application-side execution branching. |
|
|
365
|
+
| `alternatives` | Normalized summaries of other available routes. |
|
|
366
|
+
| `receivedAt` / `expiresAt` | Millisecond timestamps used for quote freshness validation. |
|
|
367
|
+
| `buildContext` | Read-only context used by `swap()` and `buildSwap()`. Do not modify it. |
|
|
368
|
+
| `raw` | Original quote API `data`, useful for diagnostics or fields that are not normalized. |
|
|
369
|
+
|
|
370
|
+
### 4.4 SwapInput and WaitMode
|
|
371
|
+
|
|
372
|
+
| Field | Type | Required | Description |
|
|
373
|
+
| --- | --- | --- | --- |
|
|
374
|
+
| `quote` | `Quote` | Yes | The value returned by `client.quote()`. Pass it directly without modification. |
|
|
375
|
+
| `waitFor` | `"submitted" \| "source-confirmed" \| "completed"` | No | Default: `"submitted"`. |
|
|
376
|
+
| `orderPolling` | `OrderPollingOptions` | No | Used with `waitFor: "completed"`. `intervalMs` defaults to `5000`; omit `timeoutMs` to poll indefinitely. |
|
|
377
|
+
| `signal` | `AbortSignal` | No | Cancels unfinished SDK requests or waits. It cannot withdraw an already broadcast transaction. |
|
|
378
|
+
| `onEvent` | `(event) => void` | No | Receives lifecycle events for this swap only. |
|
|
379
|
+
| `beforeSign` | `(preview) => void \| Promise<void>` | No | Called before each wallet signature or transaction request. It can be used for application confirmation UI. |
|
|
380
|
+
| `idempotencyKey` | `string` | No | Sent with the build request. Duplicate-execution protection is determined by the server. |
|
|
381
|
+
|
|
382
|
+
Wait modes:
|
|
383
|
+
|
|
384
|
+
| Mode | Return condition |
|
|
385
|
+
| --- | --- |
|
|
386
|
+
| `submitted` | Returns after the wallet signs or broadcasts the source action. |
|
|
387
|
+
| `source-confirmed` | Calls the required wallet confirmation method and returns only when it reports `confirmed`. A `failed` or malformed status throws `BROADCAST_FAILED`. |
|
|
388
|
+
| `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. |
|
|
389
|
+
|
|
390
|
+
`waitForOrder()` accepts the same polling values directly:
|
|
391
|
+
|
|
392
|
+
| Field | Type | Required | Description |
|
|
393
|
+
| --- | --- | --- | --- |
|
|
394
|
+
| `intervalMs` | `number` | No | Delay between status requests in milliseconds. Default: `5000`. |
|
|
395
|
+
| `timeoutMs` | `number` | No | Maximum total polling duration in milliseconds. Omit it to poll indefinitely. |
|
|
396
|
+
|
|
397
|
+
### 4.5 SwapExecutionResult
|
|
398
|
+
|
|
399
|
+
| Field | Type | Description |
|
|
400
|
+
| --- | --- | --- |
|
|
401
|
+
| `executionId` | `string` | Unique identifier for this SDK execution. |
|
|
402
|
+
| `status` | `string` | `submitted`, `source-confirmed`, `processing`, `completed`, `failed`, `refunded`, or `expired`. |
|
|
403
|
+
| `router` | `string` | Router used for execution. Pass it unchanged when querying order status. |
|
|
404
|
+
| `txHash` | `string?` | Hash of a single source-chain transaction. |
|
|
405
|
+
| `txHashes` | `string[]?` | Hashes of multiple source-chain transactions, such as a NEAR transaction batch. |
|
|
406
|
+
| `orderId` | `string?` | Server order identifier. When present, it can be passed to `waitForOrder()`. |
|
|
407
|
+
| `depositAddress` | `string?` | Cross-chain deposit address. |
|
|
408
|
+
| `report` | `object?` | Reporting state: `reported`, `failed`, or `skipped`. A report warning does not invalidate the source submission. |
|
|
409
|
+
| `raw` | `unknown` | Executor confirmation response or original swap API build data. |
|
|
410
|
+
|
|
411
|
+
`submitted` and `source-confirmed` do not mean that the destination assets have arrived. Use `waitFor: "completed"` or `waitForOrder()` to check final delivery.
|
|
412
|
+
|
|
413
|
+
## 5. Advanced: buildSwap → executeSwap
|
|
414
|
+
|
|
415
|
+
Use the advanced flow only when you need to inspect the build, pass it between processes, or separate building from wallet execution:
|
|
416
|
+
|
|
417
|
+
```ts
|
|
418
|
+
const quote = await client.quote(quoteRequest);
|
|
419
|
+
|
|
420
|
+
// Builds and normalizes the execution without opening a wallet.
|
|
421
|
+
const build = await client.buildSwap({
|
|
422
|
+
quote,
|
|
423
|
+
idempotencyKey: crypto.randomUUID(),
|
|
424
|
+
});
|
|
425
|
+
|
|
426
|
+
console.log(build.router, build.execution.kind, build.raw);
|
|
427
|
+
|
|
428
|
+
// Wallet execution can happen later.
|
|
429
|
+
const result = await client.executeSwap({
|
|
430
|
+
build,
|
|
431
|
+
waitFor: "submitted",
|
|
432
|
+
});
|
|
433
|
+
```
|
|
434
|
+
|
|
435
|
+
The following calls are equivalent:
|
|
436
|
+
|
|
437
|
+
```ts
|
|
438
|
+
await client.swap({ quote });
|
|
439
|
+
|
|
440
|
+
// Equivalent to:
|
|
441
|
+
const build = await client.buildSwap({ quote });
|
|
442
|
+
await client.executeSwap({ build });
|
|
443
|
+
```
|
|
444
|
+
|
|
445
|
+
`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.
|
|
446
|
+
|
|
447
|
+
## 6. Executor adapters
|
|
448
|
+
|
|
449
|
+
Import each chain executor from its dedicated subpath:
|
|
450
|
+
|
|
451
|
+
```ts
|
|
452
|
+
import { createEvmExecutor } from "@rhea-finance/cross-chain-aggregation-dex/executors/evm";
|
|
115
453
|
import { createSolanaExecutor } from "@rhea-finance/cross-chain-aggregation-dex/executors/solana";
|
|
116
454
|
import { createAptosExecutor } from "@rhea-finance/cross-chain-aggregation-dex/executors/aptos";
|
|
117
455
|
import { createNearExecutor } from "@rhea-finance/cross-chain-aggregation-dex/executors/near";
|
|
@@ -121,229 +459,260 @@ import { createZcashExecutor } from "@rhea-finance/cross-chain-aggregation-dex/e
|
|
|
121
459
|
import { createSuiExecutor } from "@rhea-finance/cross-chain-aggregation-dex/executors/sui";
|
|
122
460
|
```
|
|
123
461
|
|
|
124
|
-
|
|
462
|
+
| Chain | Supported execution kinds | Core adapter capabilities |
|
|
463
|
+
| --- | --- | --- |
|
|
464
|
+
| EVM | `evm-transaction`, `evm-signature` | `sendTransaction`, `signTypedData`, and `waitForTransaction`. |
|
|
465
|
+
| Solana | `solana-transaction` | Submit a serialized transaction and implement `waitForTransaction`. |
|
|
466
|
+
| Aptos | `aptos-entry-function` | Submit an entry function and implement `waitForTransaction`. |
|
|
467
|
+
| NEAR | `near-transaction-batch` | Submit NEAR transactions and implement `waitForTransactions`. |
|
|
468
|
+
| Tron | `tron-transfer` | Submit a native-token or token transfer and implement `waitForTransaction`. |
|
|
469
|
+
| Bitcoin | `bitcoin-transfer` | Submit a UTXO transfer and implement `waitForTransaction`. Configure `defaultFeeRate` when the build does not provide a fee rate. |
|
|
470
|
+
| Zcash | `zcash-transfer` | Submit a transparent-address transfer and implement `waitForTransaction`. |
|
|
471
|
+
| Sui | `sui-transfer` | Submit a coin transfer and implement `waitForTransaction`. |
|
|
472
|
+
|
|
473
|
+
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.
|
|
474
|
+
|
|
475
|
+
Every built-in wallet adapter must implement a confirmation method. It must return this normalized result instead of returning a chain-specific receipt directly:
|
|
125
476
|
|
|
126
477
|
```ts
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
478
|
+
type TransactionConfirmation = {
|
|
479
|
+
status: "confirmed" | "failed";
|
|
480
|
+
raw?: unknown;
|
|
481
|
+
};
|
|
130
482
|
```
|
|
131
483
|
|
|
132
|
-
|
|
484
|
+
The adapter is responsible for interpreting its chain-specific receipt, including EVM `receipt.status`, Solana `meta.err`, Aptos execution success, NEAR final execution status, and the confirmation policy used for UTXO chains. The SDK rejects both `failed` and malformed confirmation statuses.
|
|
133
485
|
|
|
134
|
-
|
|
486
|
+
For MCA quotes, the SDK may also read these methods from the registered executor:
|
|
135
487
|
|
|
136
|
-
|
|
488
|
+
- `getIdentityKey()` generates `mca.signer.identityKey` and is required for MCA quotes;
|
|
489
|
+
- `signMessage()` signs the exact API-provided message when required by an MCA relayer withdrawal.
|
|
137
490
|
|
|
138
|
-
|
|
491
|
+
These are adapter capabilities. Application code calling `client.swap()` does not pass a separate signer.
|
|
139
492
|
|
|
140
|
-
|
|
493
|
+
## 7. EVM approvals
|
|
141
494
|
|
|
142
|
-
|
|
495
|
+
When the swap API build response contains an `approval`, the EVM executor performs these steps in order:
|
|
496
|
+
|
|
497
|
+
1. Call the optional `isApprovalRequired(approval)` method. If it is not implemented, approval is assumed to be required.
|
|
498
|
+
2. Submit the approval transaction.
|
|
499
|
+
3. Call the required `waitForTransaction` method and require a `confirmed` result.
|
|
500
|
+
4. Submit the main swap transaction or request the EIP-712 signature.
|
|
501
|
+
|
|
502
|
+
Applications do not need to query allowances or inspect `needsApprove`. To avoid unnecessary approval transactions, implement `isApprovalRequired` in the adapter:
|
|
143
503
|
|
|
144
504
|
```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,
|
|
505
|
+
const evmAdapter: EvmWalletAdapter = {
|
|
506
|
+
// ...sendTransaction, signTypedData, and other methods
|
|
507
|
+
async isApprovalRequired(approval) {
|
|
508
|
+
const allowance = await readAllowance(approval.spender);
|
|
509
|
+
return allowance < requiredAmount;
|
|
159
510
|
},
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
const result = await client.swap({ quote, waitFor: "completed" });
|
|
511
|
+
};
|
|
163
512
|
```
|
|
164
513
|
|
|
165
|
-
The
|
|
514
|
+
The lifecycle emits `approval-requested`, `approval-submitted`, and the subsequent signing or submission events in order.
|
|
515
|
+
|
|
516
|
+
## 8. MCA deposits and withdrawals
|
|
517
|
+
|
|
518
|
+
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.
|
|
519
|
+
|
|
520
|
+
Common MCA fields:
|
|
166
521
|
|
|
167
|
-
|
|
522
|
+
| Field | Type | Required | Description |
|
|
523
|
+
| --- | --- | --- | --- |
|
|
524
|
+
| `flow` | `"deposit" \| "withdraw"` | Yes | MCA operation. |
|
|
525
|
+
| `mcaAccountId` | `string` | Yes | NEAR account ID of the MCA. |
|
|
526
|
+
| `signerChain` | `McaSignerChain` | Yes | Selects the registered executor that supplies identity and signing capabilities. |
|
|
527
|
+
| `recipientMsgSignatures` | `string[]` | No | Existing recipient-message signatures forwarded in the MCA payload. |
|
|
528
|
+
| `depositSignerProofSignatures` | `string[]` | No | Existing deposit-signer-proof signatures forwarded in the MCA payload. |
|
|
168
529
|
|
|
169
|
-
|
|
530
|
+
### Deposit
|
|
170
531
|
|
|
171
532
|
```ts
|
|
172
533
|
const quote = await client.quote({
|
|
173
|
-
flow: "
|
|
534
|
+
flow: "deposit",
|
|
174
535
|
mcaAccountId: "account.near",
|
|
175
|
-
|
|
536
|
+
signerChain: "evm",
|
|
537
|
+
fromChain: "42161",
|
|
176
538
|
toChain: "near",
|
|
177
|
-
tokenIn:
|
|
178
|
-
tokenOut:
|
|
539
|
+
tokenIn: arbitrumUsdc,
|
|
540
|
+
tokenOut: mcaUsdc,
|
|
179
541
|
amountIn: "1000000",
|
|
180
542
|
slippageBps: 50,
|
|
181
|
-
sender: "
|
|
182
|
-
recipient: "
|
|
183
|
-
signerChain: "near",
|
|
543
|
+
sender: "0xYourAddress",
|
|
544
|
+
recipient: "account.near",
|
|
184
545
|
collateral: {
|
|
185
|
-
|
|
186
|
-
decreaseAmountBurrow: "0",
|
|
546
|
+
useAsCollateral: true,
|
|
187
547
|
},
|
|
188
|
-
executionPreference: "near",
|
|
189
|
-
boundNearAccountId: "alice.near",
|
|
190
548
|
});
|
|
191
549
|
|
|
192
|
-
await client.swap({ quote, waitFor: "completed" });
|
|
550
|
+
const result = await client.swap({ quote, waitFor: "completed" });
|
|
193
551
|
```
|
|
194
552
|
|
|
195
|
-
|
|
553
|
+
`collateral.useAsCollateral` is a required boolean that specifies whether the deposited asset should be used as Burrow collateral.
|
|
196
554
|
|
|
197
|
-
### Withdraw
|
|
198
|
-
|
|
199
|
-
For other destination chains, expose `getIdentityKey()` and `signMessage()` on the connected wallet adapter used by its registered executor. The SDK signs the exact `messageToSign` returned by the API, then submits `mcaRelayer` through `POST /api/swap/swap`. No source-chain executor broadcasts a transaction for this path.
|
|
555
|
+
### Withdraw
|
|
200
556
|
|
|
201
557
|
```ts
|
|
202
558
|
const quote = await client.quote({
|
|
203
559
|
flow: "withdraw",
|
|
204
560
|
mcaAccountId: "account.near",
|
|
561
|
+
signerChain: "evm",
|
|
205
562
|
fromChain: "near",
|
|
206
|
-
toChain: "
|
|
563
|
+
toChain: "8453",
|
|
207
564
|
tokenIn: mcaUsdc,
|
|
208
|
-
tokenOut:
|
|
565
|
+
tokenOut: baseUsdc,
|
|
209
566
|
amountIn: "1000000",
|
|
210
567
|
slippageBps: 50,
|
|
211
568
|
sender: "account.near",
|
|
212
|
-
recipient:
|
|
213
|
-
signerChain: "evm",
|
|
569
|
+
recipient: "0xYourBaseAddress",
|
|
214
570
|
collateral: {
|
|
215
571
|
needDecrease: true,
|
|
216
|
-
decreaseAmountBurrow: "
|
|
217
|
-
withdrawAll:
|
|
572
|
+
decreaseAmountBurrow: "1.0",
|
|
573
|
+
withdrawAll: false,
|
|
218
574
|
},
|
|
219
575
|
executionPreference: "relayer",
|
|
220
576
|
});
|
|
221
577
|
|
|
222
|
-
await client.swap({
|
|
578
|
+
const result = await client.swap({
|
|
223
579
|
quote,
|
|
224
580
|
waitFor: "completed",
|
|
225
581
|
beforeSign(preview) {
|
|
226
|
-
|
|
582
|
+
console.log("MCA message signature preview", preview);
|
|
227
583
|
},
|
|
228
584
|
});
|
|
229
585
|
```
|
|
230
586
|
|
|
231
|
-
|
|
587
|
+
Withdraw-only fields:
|
|
232
588
|
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
589
|
+
| Field | Type | Required | Description |
|
|
590
|
+
| --- | --- | --- | --- |
|
|
591
|
+
| `collateral.needDecrease` | `boolean` | Yes | Whether Burrow collateral must be decreased. |
|
|
592
|
+
| `collateral.decreaseAmountBurrow` | `string` | Yes | Human-readable Burrow decimal amount, such as `"1.0"`. This is not a token base-unit amount. |
|
|
593
|
+
| `collateral.withdrawAll` | `boolean` | No | Whether to withdraw the full available amount. |
|
|
594
|
+
| `executionPreference` | `"auto" \| "near" \| "relayer"` | No | Default: `"auto"`. Set explicitly to force direct NEAR or relayer execution. |
|
|
595
|
+
| `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. |
|
|
238
596
|
|
|
239
|
-
|
|
597
|
+
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()`.
|
|
240
598
|
|
|
241
|
-
|
|
242
|
-
```
|
|
599
|
+
## 9. Lifecycle, errors, and cancellation
|
|
243
600
|
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
### Collateral policy
|
|
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:
|
|
601
|
+
Lifecycle events can be observed globally on the client or for an individual swap:
|
|
249
602
|
|
|
250
603
|
```ts
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
isMax: false,
|
|
604
|
+
const client = new SwapClient({
|
|
605
|
+
baseUrl: "https://api.rhea.finance",
|
|
606
|
+
executors: [evmExecutor],
|
|
607
|
+
onEvent(event) {
|
|
608
|
+
console.log("Swap lifecycle", event);
|
|
609
|
+
},
|
|
258
610
|
});
|
|
259
611
|
```
|
|
260
612
|
|
|
261
|
-
|
|
613
|
+
Events may cover build, approval, signing, submission, source confirmation, order status, completion, warnings, and failures.
|
|
262
614
|
|
|
263
|
-
|
|
615
|
+
SDK errors use the `SwapSdkError` type:
|
|
264
616
|
|
|
265
617
|
```ts
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
618
|
+
import { SwapSdkError } from "@rhea-finance/cross-chain-aggregation-dex";
|
|
619
|
+
|
|
620
|
+
try {
|
|
621
|
+
await client.swap({ quote });
|
|
622
|
+
} catch (error) {
|
|
623
|
+
if (error instanceof SwapSdkError) {
|
|
624
|
+
console.error({
|
|
625
|
+
code: error.code,
|
|
626
|
+
stage: error.stage,
|
|
627
|
+
message: error.message,
|
|
628
|
+
retryable: error.retryable,
|
|
629
|
+
cause: error.cause,
|
|
630
|
+
details: error.details,
|
|
631
|
+
});
|
|
632
|
+
}
|
|
633
|
+
}
|
|
269
634
|
```
|
|
270
635
|
|
|
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:
|
|
285
|
-
|
|
286
|
-
- `quoteRaw()`
|
|
287
|
-
- `buildRaw()`
|
|
288
|
-
- `submitOrderRaw()`
|
|
289
|
-
- `getOrderStatusRaw()`
|
|
290
|
-
- `reportRaw()`
|
|
291
|
-
- `getHistoryRaw()`
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
## Execution kinds
|
|
296
|
-
|
|
297
|
-
Build responses are validated and represented as a discriminated union:
|
|
298
|
-
|
|
299
|
-
- `evm-transaction`
|
|
300
|
-
- `evm-signature`
|
|
301
|
-
- `solana-transaction`
|
|
302
|
-
- `aptos-entry-function`
|
|
303
|
-
- `near-transaction-batch`
|
|
304
|
-
- `tron-transfer`
|
|
305
|
-
- `bitcoin-transfer`
|
|
306
|
-
- `zcash-transfer`
|
|
307
|
-
- `sui-transfer`
|
|
308
|
-
|
|
309
|
-
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.
|
|
310
|
-
|
|
311
|
-
## Runtime and credentials
|
|
312
|
-
|
|
313
|
-
- Browsers and Node.js 18+ use the global Fetch API.
|
|
314
|
-
- Node.js 16 requires a compatible `fetch` implementation through `new SwapClient({ fetch })`.
|
|
315
|
-
- Supply credentials with `apiKey` or `getAccessToken`; when both are present, `getAccessToken` takes precedence.
|
|
316
|
-
- The package contains no fixed API credential and never manages private keys or wallet recovery phrases.
|
|
317
|
-
- Use `AbortSignal` on network, build, execute, and polling calls when cancellation is required.
|
|
636
|
+
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`.
|
|
318
637
|
|
|
638
|
+
Pass an `AbortSignal` to stop an unfinished request or wait:
|
|
319
639
|
|
|
640
|
+
```ts
|
|
641
|
+
const controller = new AbortController();
|
|
642
|
+
const promise = client.swap({ quote, signal: controller.signal });
|
|
643
|
+
controller.abort();
|
|
644
|
+
await promise;
|
|
645
|
+
```
|
|
320
646
|
|
|
321
|
-
|
|
647
|
+
Cancellation only stops the SDK's current work. It cannot revert an approval, signature, or transaction that has already been submitted.
|
|
322
648
|
|
|
323
|
-
|
|
649
|
+
## 10. Retries, logging, and credentials
|
|
324
650
|
|
|
325
651
|
```ts
|
|
326
652
|
const client = new SwapClient({
|
|
327
653
|
baseUrl: "https://api.rhea.finance",
|
|
654
|
+
getAccessToken: async () => authStore.getToken(),
|
|
328
655
|
retry: {
|
|
329
656
|
maxRetries: 2,
|
|
330
657
|
baseDelayMs: 250,
|
|
331
|
-
maxDelayMs:
|
|
658
|
+
maxDelayMs: 2000,
|
|
332
659
|
jitter: true,
|
|
333
660
|
},
|
|
334
661
|
logger: {
|
|
335
662
|
log(entry) {
|
|
336
|
-
|
|
663
|
+
console.log("SDK API", entry);
|
|
337
664
|
},
|
|
338
665
|
},
|
|
339
666
|
});
|
|
340
667
|
```
|
|
341
668
|
|
|
342
|
-
|
|
669
|
+
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.
|
|
343
670
|
|
|
344
|
-
##
|
|
671
|
+
## 11. Raw API, reporting, and history
|
|
345
672
|
|
|
346
|
-
|
|
673
|
+
Most applications should use normalized methods. Use the Raw API only when the complete original server fields are required:
|
|
674
|
+
|
|
675
|
+
```ts
|
|
676
|
+
await client.quoteRaw(rawQuoteRequest);
|
|
677
|
+
await client.buildRaw(rawBuildRequest);
|
|
678
|
+
await client.submitOrderRaw(rawSubmitRequest);
|
|
679
|
+
await client.getOrderStatusRaw(rawStatusRequest);
|
|
680
|
+
await client.reportRaw(rawReportRequest);
|
|
681
|
+
await client.getHistoryRaw(rawHistoryRequest);
|
|
682
|
+
```
|
|
683
|
+
|
|
684
|
+
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:
|
|
685
|
+
|
|
686
|
+
```ts
|
|
687
|
+
const client = new SwapClient({
|
|
688
|
+
baseUrl: "https://api.rhea.finance",
|
|
689
|
+
executors: [evmExecutor],
|
|
690
|
+
reportMode: "manual",
|
|
691
|
+
});
|
|
692
|
+
|
|
693
|
+
const result = await client.swap({ quote });
|
|
694
|
+
await client.report(result);
|
|
695
|
+
|
|
696
|
+
// Retry after a reporting failure:
|
|
697
|
+
await client.retryReport(result);
|
|
698
|
+
```
|
|
699
|
+
|
|
700
|
+
Query history with:
|
|
701
|
+
|
|
702
|
+
```ts
|
|
703
|
+
const history = await client.getHistory({
|
|
704
|
+
sender: "0xYourAddress",
|
|
705
|
+
page: 1,
|
|
706
|
+
pageSize: 20,
|
|
707
|
+
status: ["processing", "completed"],
|
|
708
|
+
});
|
|
709
|
+
```
|
|
710
|
+
|
|
711
|
+
The SDK applies `status` filtering locally. The returned page has `filteredLocally: true`.
|
|
712
|
+
|
|
713
|
+
## 12. Amount utilities
|
|
714
|
+
|
|
715
|
+
Avoid JavaScript floating-point arithmetic for token amounts:
|
|
347
716
|
|
|
348
717
|
```ts
|
|
349
718
|
import {
|
|
@@ -351,16 +720,8 @@ import {
|
|
|
351
720
|
parseUnits,
|
|
352
721
|
} from "@rhea-finance/cross-chain-aggregation-dex";
|
|
353
722
|
|
|
354
|
-
parseUnits("1.25", 6);
|
|
723
|
+
parseUnits("1.25", 6); // "1250000"
|
|
355
724
|
formatUnits("1250000", 6); // "1.25"
|
|
356
725
|
```
|
|
357
726
|
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
## History filtering
|
|
361
|
-
|
|
362
|
-
The service handles sender and pagination. `getHistory({ status })` filters the current returned page locally and sets `filteredLocally: true`; server totals remain unchanged.
|
|
363
|
-
|
|
364
|
-
## License
|
|
365
|
-
|
|
366
|
-
MIT
|
|
727
|
+
`parseUnits()` rejects fractional precision beyond the token's decimals. `formatUnits()` accepts only non-negative base-unit decimal integer strings.
|