Token Search and Discovery
To add a new token to the list, the user must search for it via the search interface. The system supports two primary ways to find tokens:
- Search by Text: Finding known tokens (from the manifest or price provider) by their name or symbol (e.g., "USDT", "Wrapped Bitcoin").
- Search by Address: Providing the exact contract or token address. This is the primary method for adding new or obscure tokens.
Requirements for Searching a New Token
- A Valid Address: The input must pass the network's address validation (e.g., a 42-character hex string for EVM, a Base58 string for Solana).
- On-Chain Existence: For address-based search, the token must exist on the blockchain. The system performs a check to verify if the address corresponds to a token contract.
- Metadata Discovery: The system attempts to fetch the token's name, symbol, and decimals from the chain if they are not already known.
Implementation Details
1. The Search Flow (SearchTokens.vue)
The search input triggers a debounced call to the BlockchainManager's findTokens method.
- Component:
src/components/SearchTokens.vue - Logic:
- Listens for user input and waits (1000ms debounce).
- Calls
mgr.findTokens(searchQuery). - Emits the results to be displayed in a list.
2. Multi-Source Discovery (BlockchainManagerBase.findTokens)
The findTokens method implemented in src/api/manager-base.ts follows a hierarchical search strategy:
- Cached/Added Tokens: Checks if the token is already in the active list.
- Network Manifest: Searches a predefined list of popular tokens for the current network.
- Price Provider (CoinGecko): Queries the price provider's repository for tokens matching the text.
- On-Chain Verification: If an address is provided and no metadata is found elsewhere, it checks the blockchain directly using
_checkTokenOnChain(address).
3. Adding a Token (SearchTokenListItem.vue)
Once a token is found, the user can add it to their dashboard.
- Component:
src/components/SearchTokenListItem.vue - Flow:
- Confirmation: The user clicks "Add", triggering a confirmation modal.
- Manager Addition:
mgr.addToken(token)is called to include the token in the active session. - Persistence: The token address is dispatched to the Vuex store (
customtoken/setCustomToken) to ensure it persists across sessions. - Balance Fetching: The system immediately triggers a balance and price update for the new token.
Usage Examples
Searching for a Token by Address
If you want to programmatically search for a token by its address:
javascript
import { initialManager } from '@/api/ApiHandler';
const searchForToken = async (address) => {
const mgr = initialManager(); // Get manager for current network
if (mgr.isValidAddress(address)) {
const results = await mgr.findTokens(address);
if (results.length > 0) {
console.log('Token Found:', results[0]);
return results[0];
}
}
console.log('Token not found or invalid address');
};Adding a Custom Token to the System
How to add a token object to the manager and persist it in the user's settings:
javascript
import { initialManager, getStorePrefix } from '@/api/ApiHandler';
import { useStore } from 'vuex';
const store = useStore();
const mgr = initialManager();
const addNewToken = async (tokenObject) => {
try {
// 1. Add to the active BlockchainManager
mgr.addToken(tokenObject);
// 2. Persist to local storage via Vuex
const prefix = getStorePrefix();
const currentCustomTokens = store.state[`${prefix}.customtoken`].customToken[mgr.networkName] || [];
if (!currentCustomTokens.includes(tokenObject.id)) {
const updatedList = [...currentCustomTokens, tokenObject.id];
await store.dispatch(`${prefix}.customtoken/setCustomToken`, {
key: mgr.networkName,
value: updatedList
});
}
// 3. Initialize balance in the UI
await store.dispatch('user/setTokenBalanceItem', {
provider: mgr.networkName,
key: tokenObject.id,
value: {
root: tokenObject.id,
symbol: await tokenObject.getSymbol(),
balance: 0
},
action: "newToken"
});
} catch (error) {
console.error('Failed to add token:', error);
}
};Data Persistence
Custom tokens are stored in a network-specific and account-specific store module (dynamicCustomToken.js). This ensures that:
- Tokens added on Ethereum don't appear on Solana.
- Tokens are associated with the specific public key of the connected card/wallet.
- The list is automatically reloaded when the
BlockchainManageris initialized from the store'sextraTokensstate.
