That’s all. There’s no API key to request and no backend to run.
The backend holds the 1Click API key, so nothing secret ships in your client.
---
# UniportButton
Source: https://uniport.dev/docs/uniport-button
## Usage
console.log(result.txHash)}
onError={(error) => console.error(error.message)}
onOpenChange={(open) => console.log(open)}
/>
);
}`}
/>
## onSuccess
Called when the payment completes. It receives `{ txHash: string; amount: string }`.
## onError
Called when the payment fails. It receives an `Error`. Failures from Uniport’s backend arrive as a `UniportError` with a `code`; see [Errors](/docs/errors).
## onOpenChange
Called with `true` when the modal opens and `false` when it closes.
---
# Styling
Source: https://uniport.dev/docs/styling
## Theme
`theme` sets the button and the modal to `"light"` (the default) or `"dark"`. Use `"dark"` on dark backgrounds.
## Variant
"default", "A solid button with comfortable padding. The default."],
["compact" , "The same button, smaller, for dense toolbars and rows."],
["outline" , "A transparent button with a border."],
]}
/>
## className and disabled
`className` is added to the button so you can apply your own styles. `disabled` turns the button off, for example until your form has a recipient.
---
# Chains and tokens
Source: https://uniport.dev/docs/chains-and-tokens
## Naming
Destination tokens are named `{chain}{SYMBOL}`: `optimismUSDC`, `arbitrumUSDC`, `solanaSOL`, `bitcoinBTC`. Legacy short aliases such as `arbUSDC` and `ethUSDC` still work, but the canonical names are the ones to ship against.
## Source chains
Ethereum, Base, Optimism, Arbitrum, Polygon, Solana, Sui, NEAR, Bitcoin, Avalanche, BNB Chain, Aptos, TON, Tron, Stellar, Cardano, XRP Ledger, Dogecoin, Litecoin, Bitcoin Cash, Starknet, Berachain, Zcash and Scroll.
Destination tokens
## Display amounts
Cross-chain quotes often land on long decimals. The modal rounds the amounts it displays to 6 significant digits so they stay readable. The actual quote, deposit and settlement amounts are never changed.
---
# Refunds
Source: https://uniport.dev/docs/refunds
## The refund address
The payer enters a refund address in the modal, on the chain they’re paying from. You can prefill it with the `refundAddress` prop.
## EVM chains
On EVM source chains, a blank refund address defaults to Uniport’s own address, resolved from `uniport.eth` (with a fixed fallback if resolution fails), instead of blocking the payment. This exists because the underlying 1Click API needs an explicit refund address and can’t yet refund to the depositing wallet.
## Other chains
On Sui, Solana, Bitcoin and other non-EVM chains the payer must enter a refund address. There is no Uniport-controlled address on those chains to fall back to.
## Fixed amounts
rounded surplus and failed-swap refunds are credited to Uniport’s configured Intents account.
---
# Memo chains
Source: https://uniport.dev/docs/memo-chains
## Stellar
Stellar is currently the only chain that needs a memo. The modal requests the right deposit mode automatically and shows the memo prominently next to the deposit address, with its own copy button.
## Trustlines
Non-native Stellar assets, such as Stellar USDC, need the receiving address to have a trustline for that asset, or funds can’t be delivered. The modal warns about this when a payer enters a refund address for a non-XLM Stellar token.
## TON and XRP
The 1Click API’s documentation suggests TON and XRP may also need memos. Tested against the live API, they don’t for the chains Uniport supports today. Only Stellar does.
---
# Errors
Source: https://uniport.dev/docs/errors
## UniportError
A `UniportError` has a `message`, a stable `code`, and optionally `details` and the HTTP `status`. Timeouts, quote failures, deposit submission failures and status failures are all normalized before they reach your UI.
## Codes
VALIDATION_ERROR, "A request was missing or had an invalid field."],
[QUOTE_FAILED , "No quote could be produced for this route or amount."],
[DEPOSIT_SUBMISSION_FAILED , "The deposit couldn’t be submitted for tracking."],
[STATUS_CHECK_FAILED , "The payment’s status couldn’t be fetched."],
[REQUEST_TIMEOUT , "The backend didn’t answer within 20 seconds."],
[NETWORK_ERROR , "The backend couldn’t be reached."],
[INTERNAL_ERROR , "The backend failed unexpectedly."],
[UNKNOWN_ERROR , "Anything else."],
]}
/>
---
# FAQ
Source: https://uniport.dev/docs/faq
## Do I need an API key?
No. The SDK calls Uniport’s hosted backend, which keeps the routing API key server-side. Nothing secret ships in your client.
## Where do funds settle?
To the `recipient` address you pass, on the chain and token named by `destinationToken`. With `optimismUSDC`, your app receives USDC on Optimism.
## What happens if a payment fails?
Funds go back to the payer’s refund address on the chain they paid from. See [Refunds](/docs/refunds).
## Which chains need a memo?
Stellar. The modal shows the memo right next to the deposit address. See [Memo chains](/docs/memo-chains).
## What does Uniport cost?
Uniport takes 0.4% of each deposit. That’s the whole fee.
## Which frameworks does it work with?
Any React 18 or later app: Next.js, Vite, Remix and others.
---
# Changelog
Source: https://uniport.dev/docs/changelog
## 0.0.7
July 14, 2026
- The chain list in the modal is reordered, with Stellar first.
## 0.0.6
July 14, 2026
- Block explorer links for completed payments.
- On EVM chains, a blank refund address defaults to Uniport’s address, resolved from `uniport.eth`.
- Displayed amounts are rounded to 6 significant digits (display only).
- The memo is shown next to the deposit address on chains that need one.
- Stellar and Scroll support.
## Earlier releases
See [uniport-sdk on npm](https://www.npmjs.com/package/uniport-sdk) and the [GitHub repository](https://github.com/officialcmg/uniport).