Installation
pnpm add @qubismic/quantumdex-react @qubismic/quantumdex-sdk wagmi viem @tanstack/react-query
Provider Setup
// app/providers.tsx
import { QuantumDEXProvider } from '@qubismic/quantumdex-react';
import { WagmiProvider } from 'wagmi';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { thichain, thichain_testnet } from '@qubismic/quantumdex-sdk/chains';
const queryClient = new QueryClient();
const wagmiConfig = createConfig({ chains: [thichain, thichain_testnet], ... });
export function Providers({ children }: { children: React.ReactNode }) {
return (
<WagmiProvider config={wagmiConfig}>
<QueryClientProvider client={queryClient}>
<QuantumDEXProvider
chainId={420420}
rpcUrl="https://rpc.thichain.io"
>
{children}
</QuantumDEXProvider>
</QueryClientProvider>
</WagmiProvider>
);
}
useSwap
import { useSwap } from '@qubismic/quantumdex-react';
function SwapWidget() {
const {
quote,
isLoading,
isError,
executeSwap,
isPending,
hash,
} = useSwap({
tokenIn: '0x...USDC',
tokenOut: '0x...THI',
amountIn: '100', // human-readable
slippageTolerance: 0.5, // %
});
return (
<div>
{quote && (
<p>
Receive: {quote.amountOutFormatted} THI
(Fee: {quote.feeBps} BPS · {quote.karmaTier})
</p>
)}
<button onClick={executeSwap} disabled={isPending}>
{isPending ? 'Swapping...' : 'Swap'}
</button>
{hash && <p>TX: {hash}</p>}
</div>
);
}
Return Value
| Field | Type | Description |
quote | SwapQuote | undefined | Current quote (refreshes every 10s) |
isLoading | boolean | Quote loading state |
executeSwap | () => void | Execute the swap |
isPending | boolean | TX awaiting wallet confirmation |
hash | string | undefined | TX hash after broadcast |
usePool
import { usePool, useAddLiquidity } from '@qubismic/quantumdex-react';
function PoolInfo({ tokenA, tokenB }) {
const { pool, isLoading } = usePool({ tokenA, tokenB });
const { addLiquidity, isPending } = useAddLiquidity();
if (isLoading) return <Spinner />;
return (
<div>
<p>TVL: {pool.tvlFormatted}</p>
<p>Fee: {pool.feeBps} BPS</p>
<p>APR: {pool.apr}%</p>
</div>
);
}
useKarmaScore
import { useKarmaScore } from '@qubismic/quantumdex-react';
function KarmaDisplay() {
const { karma, isLoading } = useKarmaScore();
// Uses connected wallet address by default
// Or pass: useKarmaScore({ address: '0x...' })
return (
<div className={`karma-badge tier-${karma?.tier.toLowerCase()}`}>
{isLoading ? '...' : (
<>
<span>{karma.score}</span>
<span>{karma.tier}</span>
<span>{karma.feeBps} BPS fee</span>
</>
)}
</div>
);
}
usePerps
import { usePerps, useOpenPosition } from '@qubismic/quantumdex-react';
function PerpsTrading() {
const { positions, markPrice } = usePerps({ pair: 'THI/USDC' });
const { openPosition, isPending } = useOpenPosition();
return (
<div>
<p>Mark Price: {markPrice}</p>
{positions.map(pos => (
<div key={pos.id}>
{pos.direction} {pos.leverage}× · PnL: {pos.pnlFormatted}
</div>
))}
</div>
);
}
useGovernance
import { useProposals, useVotingPower, useCastVote } from '@qubismic/quantumdex-react';
function GovernancePanel() {
const { proposals } = useProposals({ state: 'ACTIVE' });
const { votingPower } = useVotingPower();
const { castVote } = useCastVote();
return (
<div>
<p>Your veQBIT: {votingPower}</p>
{proposals.map(p => (
<div key={p.id}>
<h4>{p.description}</h4>
<button onClick={() => castVote(p.id, 1)}>Vote For</button>
</div>
))}
</div>
);
}