Advanced Usage

A couple of patterns that come up once you have used the SDK for a bit.

A Reusable Token Selector

Building a swap form, a bridge, or anything with a "from" and "to" token? You will want a small wrapper so you are not copy-pasting SelectTokenModal everywhere.

Step 1: Wrap it

Code
tsx
1// components/ReusableSelectToken.tsx
2import { ReactNode } from 'react';
3import { SelectTokenModal, IToken } from 'starknet-tokenkit';
4 
5interface IReusableSelectToken {
6 selectedToken: IToken | null;
7 callBackFn: (token: IToken) => void;
8 children: ReactNode;
9}
10 
11const ReusableSelectToken = (props: IReusableSelectToken) => {
12 return (
13 <SelectTokenModal
14 selectedToken={props.selectedToken}
15 callBackFunc={props.callBackFn}
16 >
17 {props.children}
18 </SelectTokenModal>
19 );
20};
21 
22export default ReusableSelectToken;

Step 2: Use it in a swap form

Now your swap page is just two pickers, no boilerplate:

Code
tsx
1import { useState } from 'react';
2import { TokenKitWrapper, IToken, themes } from 'starknet-tokenkit';
3import ReusableSelectToken from './components/ReusableSelectToken';
4 
5function SwapPage() {
6 const [fromToken, setFromToken] = useState<IToken | null>(null);
7 const [toToken, setToToken] = useState<IToken | null>(null);
8 
9 return (
10 <TokenKitWrapper
11 network="SN_MAIN"
12 apiKey="your-api-key"
13 mainnetEndpoint="https://api.tokenkithq.io"
14 sepoliaEndpoint="https://api.sepolia.tokenkithq.io"
15 themeObject={themes.dark}
16 >
17 <div className="swap-container">
18 {/* From Token */}
19 <ReusableSelectToken selectedToken={fromToken} callBackFn={setFromToken}>
20 <button>{fromToken ? fromToken.symbol : 'Select From Token'}</button>
21 </ReusableSelectToken>
22 
23 {/* To Token */}
24 <ReusableSelectToken selectedToken={toToken} callBackFn={setToToken}>
25 <button>{toToken ? toToken.symbol : 'Select To Token'}</button>
26 </ReusableSelectToken>
27 </div>
28 </TokenKitWrapper>
29 );
30}

Reading the wrapper config

If you need to make your own API call with the same network and key the SDK is using, grab them from useTokenKitContext:

Code
tsx
1import { useTokenKitContext } from 'starknet-tokenkit';
2 
3const MyHoldings = () => {
4 const {
5 network,
6 apiKey,
7 mainnetEndpoint,
8 sepoliaEndpoint,
9 options, // { tokensToLoad, enableRecent }
10 origin, // optional X-Origin header value
11 } = useTokenKitContext();
12 
13 const endpoint = network === 'SN_MAIN' ? mainnetEndpoint : sepoliaEndpoint;
14 
15 // Reuse the same credentials the picker uses
16 const headers: HeadersInit = { 'api-key': apiKey ?? '' };
17 if (origin) headers['X-Origin'] = origin;
18 
19 // fetch(`${endpoint}/api/balances/`, { headers, ... })
20 return <p>Connected to {network}</p>;
21};

Useful for keeping things in sync without passing the config around manually. Note every value can be null until the wrapper is mounted, so guard accordingly when calling from libraries.

Browser-extension wallets — origin

If you're building a browser-extension wallet, set origin on TokenKitWrapper. The SDK forwards it as the X-Origin request header to the API — your API key can then be restricted to only that extension ID.

Code
tsx
1<TokenKitWrapper
2 /* ...other props */
3 origin={`chrome-extension://${chrome.runtime.id}`}
4>

Web apps almost always don't need this; the browser's natural Origin header is enough.

Picking which token set to load — options.tokensToLoad

The picker defaults to 'public', which is the curated set anyone listing through tokenkithq.io will appear in. If your dApp lets users paste arbitrary contract addresses and look them up (e.g. an admin tool, an explorer), switch to 'all':

Code
tsx
1<TokenKitWrapper
2 /* ...other props */
3 options={{ tokensToLoad: 'all' }}
4>

'all' includes every indexed ERC-20 we've seen, verified or not. Default to 'public' for end-user surfaces — 'all' will surface scams in the search results.

Opting into recent tokens — options.enableRecent

Recent-token persistence is off by default. When enabled, the picker writes the last few picks to localStorage (keyed by network) and shows a "Recent" section above the full list.

Code
tsx
1<TokenKitWrapper
2 /* ...other props */
3 options={{ enableRecent: true }}
4>

The user can clear their own list with the "Clear all" button next to the section header, or remove individual entries with the × on each row.