Quick Start – Browser
This guide covers installing the Atomiq SDK in a browser and its chain-specific connectors and walks you through setting up and initializing the Atomiq SDK.
Core SDK
Install the main SDK package:
npm install @atomiqlabs/sdk@latest
Chain Connectors
The SDK supports multiple chains. Install only the chain connectors your project needs, and mix and match them as required:
npm install @atomiqlabs/chain-solana@latest
npm install @atomiqlabs/chain-starknet@latest
npm install @atomiqlabs/chain-evm@latest
Setup
Not all chains support both Bitcoin testnets (testnet3 & testnet4), check the network availability.
- Mainnet
- Testnet3
- Testnet4
Set your RPC URLs:
const solanaRpc = "https://api.mainnet-beta.solana.com";
const starknetRpc = "https://rpc.starknet.lava.build/"; //Alternatively: https://starknet.api.onfinality.io/public or https://api.zan.top/public/starknet-mainnet
const citreaRpc = "https://rpc.mainnet.citrea.xyz";
Create a swapper factory with your desired chain support. Use as const so TypeScript can properly infer the types:
import {SolanaInitializer} from "@atomiqlabs/chain-solana";
import {StarknetInitializer} from "@atomiqlabs/chain-starknet";
import {CitreaInitializer} from "@atomiqlabs/chain-evm";
import {BitcoinNetwork, TypedSwapper, SwapperFactory, TypedTokens} from "@atomiqlabs/sdk";
// Define chains you want to support
const chains = [SolanaInitializer, StarknetInitializer, CitreaInitializer] as const;
type SupportedChains = typeof chains;
// Create the swapper factory
const Factory = new SwapperFactory<SupportedChains>(chains);
// Get the tokens for the supported chains
const Tokens: TypedTokens<SupportedChains> = Factory.Tokens;
// Create one swapper instance for your entire app, and use that instance for all your swaps.
const swapper: TypedSwapper<SupportedChains> = Factory.newSwapper({
chains: {
SOLANA: {
rpcUrl: solanaRpc // Can also pass Connection object
},
STARKNET: {
rpcUrl: starknetRpc // Can also pass Provider object
},
CITREA: {
rpcUrl: citreaRpc, // Can also pass JsonRpcProvider object
}
},
bitcoinNetwork: BitcoinNetwork.MAINNET
});
// Initialize the swapper
await swapper.init();
On testnets, only native tokens are generally supported (e.g. SOL, STRK, cBTC).
Set your testnet RPC URLs:
const solanaRpc = "https://api.devnet.solana.com";
const starknetRpc = "https://rpc.starknet-testnet.lava.build/";
Create a swapper factory with your desired chain support:
import {SolanaInitializer} from "@atomiqlabs/chain-solana";
import {StarknetInitializer} from "@atomiqlabs/chain-starknet";
import {BitcoinNetwork, TypedSwapper, SwapperFactory, TypedTokens} from "@atomiqlabs/sdk";
const chains = [SolanaInitializer, StarknetInitializer] as const;
type SupportedChains = typeof chains;
const Factory = new SwapperFactory<SupportedChains>(chains);
const Tokens: TypedTokens<SupportedChains> = Factory.Tokens;
const swapper: TypedSwapper<SupportedChains> = Factory.newSwapper({
chains: {
SOLANA: {
rpcUrl: solanaRpc // Can also pass Connection object
},
STARKNET: {
rpcUrl: starknetRpc // Can also pass Provider object
}
},
bitcoinNetwork: BitcoinNetwork.TESTNET3
});
await swapper.init();
On testnets, only native tokens are generally supported (e.g. SOL, STRK, cBTC).
Set your testnet RPC URLs:
const starknetRpc = "https://rpc.starknet-testnet.lava.build/";
const citreaRpc = "https://rpc.testnet.citrea.xyz";
Create a swapper factory with your desired chain support:
import {StarknetInitializer} from "@atomiqlabs/chain-starknet";
import {CitreaInitializer} from "@atomiqlabs/chain-evm";
import {BitcoinNetwork, TypedSwapper, SwapperFactory, TypedTokens} from "@atomiqlabs/sdk";
const chains = [StarknetInitializer, CitreaInitializer] as const;
type SupportedChains = typeof chains;
const Factory = new SwapperFactory<SupportedChains>(chains);
const Tokens: TypedTokens<SupportedChains> = Factory.Tokens;
const swapper: TypedSwapper<SupportedChains> = Factory.newSwapper({
chains: {
STARKNET: {
rpcUrl: starknetRpc // Can also pass Provider object
},
CITREA: {
rpcUrl: citreaRpc, // Can also pass JsonRpcProvider object
}
},
bitcoinNetwork: BitcoinNetwork.TESTNET4
});
await swapper.init();
Initialize the swapper with await swapper.init(); shown above once when your app starts. You should create only one swapper instance for your entire app, and use that instance for all your swaps. This checks existing in-progress swaps and does initial LP discovery.
Setting Up Signers
Atomiq's AbstractSigner object wraps around the wallet object of the respective chain and makes it easy to approve transactions via it by passing it to the swap methods. You can alternatively skip this step, obtain the transactions required to be signed and sign & send them manually.
Solana
Using Solana wallet adapter in React
Install the Solana wallet adapter:
npm install --save \
@solana/wallet-adapter-base \
@solana/wallet-adapter-react \
@solana/wallet-adapter-react-ui \
@solana/wallet-adapter-wallets
Wrap your app with the wallet adapter providers:
import { useMemo } from "react";
import { ConnectionProvider, WalletProvider, useAnchorWallet } from "@solana/wallet-adapter-react";
import { WalletModalProvider, WalletMultiButton } from "@solana/wallet-adapter-react-ui";
import "@solana/wallet-adapter-react-ui/styles.css";
import { SolanaSigner } from "@atomiqlabs/chain-solana";
// In your component, create the signer from the connected wallet:
function YourApp() {
const anchorWallet = useAnchorWallet();
//Create atomiq signer object out of the anchor wallet, which you can then use to execute swaps
const wallet = useMemo(() => new SolanaSigner(anchorWallet), [anchorWallet]);
return (
<div>
<h1>Your App</h1>
{/* Place a `WalletMultiButton` button in your app to allow the user to connect their wallet */}
<WalletMultiButton />
</div>
);
}
function App() {
return (
// Use the same solanaRpc that was used to create the swapper earlier
<ConnectionProvider endpoint={solanaRpc}>
<WalletProvider wallets={[]} autoConnect>
<WalletModalProvider>
<YourApp />
</WalletModalProvider>
</WalletProvider>
</ConnectionProvider>
);
}
Starknet
Using get-starknet in the Browser
Install get-starknet:
npm install --save \
@starknet-io/get-starknet
Connect the wallet and create a signer:
import { connect, getStarknet } from "@starknet-io/get-starknet";
import { WalletAccount } from "starknet";
import { StarknetBrowserSigner } from "@atomiqlabs/chain-starknet";
const starknet = getStarknet();
async function connectStarknetWallet() {
// Connect the starknet wallet
const swo = await connect();
// Use the same starknetRpc that was used to create the swapper earlier
const walletAccount = await WalletAccount.connect(starknetRpc, swo);
//Create atomiq signer object out of the wallet account, which you can then use to execute swaps
const wallet = new StarknetBrowserSigner(walletAccount);
}
EVM (Citrea, etc.)
Using Wagmi + RainbowKit in React
Install Wagmi and RainbowKit:
npm install --save @rainbow-me/rainbowkit \
wagmi \
[email protected] \
@tanstack/react-query
Set up Wagmi with your EVM chain and wrap your app:
import { useEffect, useState } from "react";
import { getDefaultConfig, RainbowKitProvider, ConnectButton } from '@rainbow-me/rainbowkit';
import { WagmiProvider, useAccount } from "wagmi";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { BrowserProvider } from "ethers";
import { EVMBrowserSigner } from "@atomiqlabs/chain-evm";
// Define your chain (example: Citrea Mainnet)
const citreaChain = {
id: 4114,
name: "Citrea",
nativeCurrency: { name: "cBTC", symbol: "cBTC", decimals: 18 },
rpcUrls: { default: { http: ["https://rpc.mainnet.citrea.xyz"] } },
};
const config = getDefaultConfig({
appName: 'My RainbowKit App',
projectId: 'YOUR_PROJECT_ID', // Every dApp that relies on WalletConnect needs to obtain a projectId from https://dashboard.reown.com
chains: [citreaChain], // Include your desired EVM chain (can have multiple)
ssr: false, // If your dApp uses server side rendering (SSR)
});
const queryClient = new QueryClient();
// In your component, create the signer from the connected wallet:
function YourApp() {
const { connector, isConnected } = useAccount();
//Create atomiq signer object out of browser provider, which you can then use to execute swaps
const [wallet, setWallet] = useState<EVMBrowserSigner>();
useEffect(() => {
if(!isConnected) {
setWallet(undefined);
return;
}
connector.getProvider().then(provider => {
return new BrowserProvider(provider).getSigner();
}).then(signer => {
setWallet(new EVMBrowserSigner(signer, signer.address));
});
}, [connector, isConnected]);
return (
<div>
<h1>Your App</h1>
{/* Place a `ConnectButton` button in your app to allow the user to connect their wallet */}
<ConnectButton />
</div>
);
}
function App() {
return (
<WagmiProvider config={config}>
<QueryClientProvider client={queryClient}>
<RainbowKitProvider>
<YourApp />
</RainbowKitProvider>
</QueryClientProvider>
</WagmiProvider>
);
}
Your First Swap
Here's a complete example of a Smart Chain to Bitcoin on-chain swap:
import {SwapAmountType} from "@atomiqlabs/sdk";
// Create a swap: SOL to Bitcoin on-chain
const swap = await swapper.swap(
Tokens.SOLANA.SOL, // From token
Tokens.BITCOIN.BTC, // To Bitcoin on-chain
"0.0001", // Amount of BTC to receive
SwapAmountType.EXACT_OUT, // Specify amount in output token
solanaSigner.getAddress(), // Source address
"bc1q..." // Bitcoin destination address
);
// Check quote details
console.log("Input:", swap.getInput().toString());
console.log("Output:", swap.getOutput().toString());
console.log("Expires:", new Date(swap.getQuoteExpiry()));
// Execute the swap
const success = await swap.execute(solanaSigner, {
onSourceTransactionSent: (txId) => console.log("Tx sent:", txId),
onSwapSettled: (btcTxId) => console.log("Bitcoin transaction sent:", btcTxId)
});
// Handle failure
if (!success) {
await swap.refund(solanaSigner);
}
Next Steps
Creating Quotes
Guides you through creating swap quotes.
Configuration
Explains swapper configuration parameters passed in the Factory.newSwapper() function and debug logging config.
Utilities
SDK-exposed utilities allow you to parse addresses (including LNURL links), fetch token balances, list supported tokens and swap types.