Add cross-chain swaps to your app without building a router
Four ways in: a drop-in widget, a typed SDK for JS/TS or Python, and React hooks. Pick one, copy the code, ship today.
Quick answer
Building cross-chain swaps from scratch means wallet plumbing, raw HTTP calls, quote-expiry handling, and Bitcoin's UTXO model, all before your first swap works. RAVN now ships four convenience layers on top of the same quote, execute, submit-signature, and status calls, so you skip the boilerplate: a hosted widget you embed in an iframe, a typed SDK for JS or TypeScript, a typed Python client, and React hooks for a custom UI. Same fields, same 0-bps-default fees, same routes as calling the API yourself.
Pick one
| Package | For | Handles |
|---|---|---|
| Widget | Anyone who wants a working swap UI today, zero UI code | A hosted iframe, bridged to whatever wallet your page already has connected |
@ravnexchange/sdk | Backends, or a wallet calling the API directly | A typed client for quote, execute, submit-signature, status. Zero dependencies |
ravnexchange (Python) | A plain, non-agent Python backend | Same scope as the JS SDK, snake_cased, stdlib only |
@ravnexchange/react | Dapps building their own swap UI | Hooks on top of the core SDK: quote-expiry tracking, execute, status polling |
Fastest: the widget
One iframe, pointed at your own origin:
<iframe src="https://app.ravn.exchange/widget/v1?origin=https://your-site.example" sandbox="allow-scripts allow-same-origin allow-forms" ></iframe>
That alone renders a working swap UI. To let users swap with the wallet already connected on your page instead of a second connect prompt, install the connector and hand it your existing wallet's send/sign functions:
npm install @ravnexchange/widget-connector
The widget never asks for a second wallet connection while that bridge is live, and it handles native BTC deposits entirely on its own: address, QR code, and status tracker, no wallet code required for that case. Full wiring guide (EVM and Solana wallets): docs.ravn.exchange/sdks/widget.
Building your own UI: the SDK
npm install @ravnexchange/sdk
import { RavnClient } from "@ravnexchange/sdk";
const client = new RavnClient(); // omit apiKey for the anonymous tier
const quote = await client.getQuote({
inputChainId: 1,
outputChainId: -2,
inputToken: "0xEeee...EEeE",
outputToken: "So1111...1112",
inputAmount: "1000000000000000000",
userAddress: "0xYourUser",
destinationAddress: "SoYourUser",
});
const execution = await client.execute({ quoteToken: quote.quoteToken });
// branch on execution.executionType: TRANSACTION, SIGNATURE, or DEPOSIT
Same request and response shapes as the raw API, just typed, with one error type (RavnApiError) instead of parsing HTTP status codes. Full reference: docs.ravn.exchange/sdks/core.
Python backends and bots
pip install ravnexchange
from ravnexchange import RavnClient
client = RavnClient() # omit api_key for the anonymous tier
quote = client.get_quote({
"inputChainId": 1,
"outputChainId": 8453,
"inputToken": "0xEeee...EEeE",
"outputToken": "0x8335...02913",
"inputAmount": "1000000000000000000",
"userAddress": "0xYourAddress",
"destinationAddress": "0xYourAddress",
})
execution = client.execute({"quoteToken": quote["quoteToken"]})
# branch on execution["executionType"]: TRANSACTION, SIGNATURE, or DEPOSIT
Zero dependencies, built on the stdlib urllib.request, so installing it adds nothing to your dependency tree. Same scope as the JS SDK, snake_cased. Full reference: docs.ravn.exchange/sdks/python.
React apps: hooks instead of hand-rolled state
npm install @ravnexchange/react @ravnexchange/sdk
const { quote, isExpired, refetch } = useRavnQuote(client, params);
const { execute } = useRavnExecute(client);
const { status } = useRavnStatus(client, statusRef ? { quoteToken, ref: statusRef } : null);
useRavnQuote refetches when your params change and flips isExpired on its own timer when the quote expires, no polling loop to write. useRavnStatus polls until the swap reaches a terminal state. You still bring your own wallet; none of the three hooks sign or send anything. Full reference: docs.ravn.exchange/sdks/react.
Test it first, no real funds
Every path above supports sandbox mode: set sandbox: true on the quote call and the entire quote, execute, and status flow runs end to end, RAVN never moves funds and never bills or meters the call. Same contract as live, so the integration code you write against sandbox is the code that ships. docs.ravn.exchange/sandbox-mode
Who this is for
- 1A wallet or dapp that wants a swap tab this week, not next quarter. Embed the widget iframe, wire your existing wallet's sign/send functions to the connector, done. No swap UI to design or maintain.
- 2A trading bot or backend service. The Python or JS/TS SDK gives you a typed client with one error type, so a bad quote or a failed execute is a caught exception, not a status code you have to remember to check.
- 3A dapp building its own swap UI. The React hooks hand you quote-expiry and status-polling state directly, so your component logic is the button and the loading state, not a
setTimeoutyou had to get right yourself.
Start integrating
Every path above is a convenience layer over the same free API. No signup required to try any of it.
FAQ
Do I need an API key to use the SDKs or widget?
No. All four work anonymously out of the box, rate-limited per IP. A free key, issued instantly with no review, raises the limit and attributes usage to your project.
Which one should I use?
The widget if you want a working swap UI today with no UI code of your own. The core SDK for a backend or a wallet calling the API directly. The Python client for a non-agent Python backend. React hooks if you are building your own swap UI in React and want quote-expiry and status-polling state handled for you.
Does the widget handle native Bitcoin?
Yes. When a route resolves to a Bitcoin deposit, the widget renders the deposit address, a QR code, and a live status tracker on its own. No wallet interface code is required for that case.
Can I test without real funds?
Yes. Set sandbox: true on a quote and the full quote, execute, and status flow runs end to end with no funds moved and no metering.
Do these SDKs unlock different pricing or routing?
No. All four are convenience layers over the same quote, execute, submit-signature, and status calls documented in the API reference: same fields, same fees, same routes as calling the REST API directly.