# Uniport > Uniport is a chain-abstraction SDK. Apps receive funds on their home chain while users pay from any of 24 chains. One React component, `UniportButton` from `uniport-sdk`; no API key. The whole integration: ```tsx import { UniportButton } from "uniport-sdk"; export function DepositAction() { return ( ); } ``` ## Getting started - [Introduction](https://uniport.dev/docs/introduction): What Uniport is, and what it does for your app. - [Quickstart](https://uniport.dev/docs/quickstart): Add a cross-chain deposit button to a React app. - [How it works](https://uniport.dev/docs/how-it-works): What happens between a click and a settled deposit. ## UniportButton - [UniportButton](https://uniport.dev/docs/uniport-button): Every prop the button accepts, and every destination token. - [Callbacks](https://uniport.dev/docs/callbacks): onSuccess, onError and onOpenChange. - [Styling](https://uniport.dev/docs/styling): Theme, variant and className. ## Reference - [Chains and tokens](https://uniport.dev/docs/chains-and-tokens): All 24 source chains and 63 destination tokens. - [Refunds](https://uniport.dev/docs/refunds): Where funds go when a payment can’t complete. - [Memo chains](https://uniport.dev/docs/memo-chains): Chains that need a memo alongside the deposit address. - [Errors](https://uniport.dev/docs/errors): UniportError and its codes. ## Resources - [FAQ](https://uniport.dev/docs/faq): Answers to what developers ask first. - [Changelog](https://uniport.dev/docs/changelog): What changed in each uniport-sdk release. --- # Introduction Source: https://uniport.dev/docs/introduction ## What you get One React component, UniportButton, that opens a complete deposit flow., "No API key. The SDK talks to Uniport’s hosted backend, which keeps keys server-side.", "24 source chains your users can pay from, and 63 destination tokens your app can receive.", "An exact quote and one deposit address for every payment, with refunds on the source chain.", ]} /> ## The whole integration Install it with `npm i uniport-sdk`, then follow the [quickstart](/docs/quickstart). It takes about three minutes. ## How it’s built Uniport routes payments through NEAR Intents (the 1Click API). The SDK calls Uniport’s hosted backend, which returns quotes, deposit addresses and payment status. Your client never holds an API key. ## Next steps --- # Quickstart Source: https://uniport.dev/docs/quickstart ## Before you start An address your app controls on the chain you want to receive on. For USDC on Optimism, that’s an 0x address., ]} />

That’s all. There’s no API key to request and no backend to run.

Install the SDK Add the button Render `UniportButton` wherever your app asks for funds. This is the whole integration: The SDK talks to Uniport’s hosted backend, which handles quotes, deposit addresses and status. No keys live in your client. Set your values Replace the three props with your own: recipient, "Your address on the destination chain. Funds settle here, so it must be valid for that chain."], [destinationToken, <>What your app receives, written {"{chain}{SYMBOL}"}: optimismUSDC, baseUSDC, suiUSDC. All 63 tokens], [label, <>The button text. Optional; defaults to Pay with Crypto.], ]} /> Try a deposit Click the button in your app. Your users go through four steps, all inside the modal: Try your first one with a small amount, from a chain you already hold funds on. ## Next steps Every destinationToken you can name., href: "/docs/chains-and-tokens" }, { title: "Try the demo", body: "Configure the button and pay for real.", href: "https://demo.uniport.dev" }, ]} /> --- # How it works Source: https://uniport.dev/docs/how-it-works ## The four steps ## The quote When you set `amount`, the modal asks for exactly that much of your destination token, and the payer is told exactly what to send. The payer’s amount is rounded up only when the increase is 0.25% or less. Without `amount`, the payer enters how much they want to send and your app receives the quoted output. ## Deposit and settlement The modal shows one deposit address, with a QR code and a copy button. The payer sends exactly the quoted amount from their own wallet. Uniport routes the funds and settles them to your `recipient` on the destination chain, while the modal tracks the payment’s status. When the payment completes, the modal links to the transaction on a block explorer and the button calls `onSuccess`. ## Where the backend fits The backend holds the 1Click API key, so nothing secret ships in your client. --- # UniportButton Source: https://uniport.dev/docs/uniport-button ## Usage ## Props Only `recipient` and `destinationToken` are required.

Fixed amounts

With `amount`, the modal asks for exactly that much of your destination token. The payer’s quote is rounded up only when the increase is 0.25% or less. Without it, the payer enters how much they send and your app receives the quoted output.

Refund address

If a payment can’t complete, funds go back to the payer’s refund address on the chain they paid from. The payer enters it in the modal, or you prefill it with `refundAddress`. a blank refund address defaults to Uniport’s address, uniport.eth. On Solana, Sui, Bitcoin and other non-EVM chains the payer has to enter one.

Destination tokens

Pass any of these as `destinationToken`. Stablecoins are the common choice. --- # Callbacks Source: https://uniport.dev/docs/callbacks ## 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).