This guide explains the core concepts of the Citizen Wallet SDK, specifically how to instantiate and use CommunityConfig, which is the foundation for all SDK operations.
The CommunityConfig class is the central configuration object that must be instantiated and passed to almost all SDK functions. It contains all the information about a community, its tokens, accounts, chains, and other settings.
The configuration is typically fetched from a URL (usually from the community's domain) or loaded from a local file:
import { CommunityConfig, type Config } from "@citizenwallet/sdk";
// Option 1: Fetch from a URL
async function loadConfigFromUrl(configUrl: string): Promise<CommunityConfig> {
const response = await fetch(configUrl);
const configData: Config = await response.json();
return new CommunityConfig(configData);
}
// Option 2: Load from a local file (in Node.js)
import fs from 'fs';
function loadConfigFromFile(filePath: string): CommunityConfig {
const configData: Config = JSON.parse(fs.readFileSync(filePath, 'utf-8'));
return new CommunityConfig(configData);
}Once you have a CommunityConfig instance, you pass it as the first parameter to most SDK functions:
import {
CommunityConfig,
getAccountAddress,
getAccountBalance,
BundlerService
} from "@citizenwallet/sdk";
// Initialize config
const config = await loadConfigFromUrl("https://example.com/config/community.json");
// Use config in SDK functions
const accountAddress = await getAccountAddress(config, userAddress);
const balance = await getAccountBalance(config, accountAddress);
const bundler = new BundlerService(config);The Config interface (passed to CommunityConfig constructor) has the following structure:
interface Config {
community: {
name: string;
description: string;
url: string;
alias: string;
custom_domain?: string;
logo: string;
hidden?: boolean;
theme?: { primary: string };
profile: { address: string; chain_id: number };
primary_token: { address: string; chain_id: number };
primary_account_factory: { address: string; chain_id: number };
primary_card_manager?: { address: string; chain_id: number };
primary_session_manager?: { address: string; chain_id: number };
};
tokens: { [key: string]: ConfigToken };
scan: { url: string; name: string };
accounts: { [key: string]: ConfigAccount };
cards?: { [key: string]: ConfigClassicCard | ConfigSafeCard };
sessions?: { [key: string]: ConfigSession };
chains: { [key: string]: ConfigChain };
ipfs: { url: string };
plugins?: ConfigPlugin[];
config_location: string;
version: number;
}import { CommunityConfig, getAccountAddress, getAccountBalance } from "@citizenwallet/sdk";
const config = new CommunityConfig(configData);
// Get smart account address for a user
const accountAddress = await getAccountAddress(
config,
userWalletAddress,
BigInt(0) // salt
);
// Get token balance
const balance = await getAccountBalance(config, accountAddress);import { CommunityConfig, BundlerService } from "@citizenwallet/sdk";
import { Wallet } from "ethers";
const config = new CommunityConfig(configData);
const bundler = new BundlerService(config);
const signer = new Wallet(privateKey);
// Send tokens
const txHash = await bundler.sendERC20Token(
signer,
config.primaryToken.address,
fromAddress,
toAddress,
amount,
description
);import { CommunityConfig, getProfileFromAddress } from "@citizenwallet/sdk";
const config = new CommunityConfig(configData);
const ipfsDomain = config.ipfs.url.replace('https://', '');
const profile = await getProfileFromAddress(
ipfsDomain,
config,
userAddress
);import { CommunityConfig, LogsService } from "@citizenwallet/sdk";
const config = new CommunityConfig(configData);
const logsService = new LogsService(config);
const logs = await logsService.getLogs(
config.primaryToken.address,
topic,
{ limit: 10, offset: 0 }
);The CommunityConfig class provides many helper methods:
const config = new CommunityConfig(configData);
// Access primary resources
const primaryToken = config.primaryToken;
const primaryNetwork = config.primaryNetwork;
const primaryRPCUrl = config.primaryRPCUrl;
const primaryAccountConfig = config.primaryAccountConfig;
// Get RPC URL (with optional account factory override)
const rpcUrl = config.getRPCUrl(accountFactoryAddress);
// Get token by address
const token = config.getToken(tokenAddress);
// Get token by project name
const projectToken = config.getProjectToken("project-name");
// Get account config
const accountConfig = config.getAccountConfig(accountFactoryAddress);
// Access session config (if available)
const sessionConfig = config.primarySessionConfig;
// Access card config (if available)
const cardConfig = config.primaryCardConfig;-
Always pass CommunityConfig as first parameter: Almost all SDK functions expect
CommunityConfigas the first parameter. -
Config is required: You cannot use SDK functions without a valid
CommunityConfiginstance. The config must be fetched or loaded before using any SDK functions. -
Config structure is validated: The
CommunityConfigconstructor expects a completeConfigobject matching the interface. Ensure your JSON matches the expected structure. -
Config is typically fetched from a URL: Most communities host their config at a URL like
https://[alias].citizenwallet.xyz/config/community.jsonor similar. -
Config contains all necessary blockchain info: The config includes RPC URLs, contract addresses, chain IDs, and other blockchain-specific information needed by the SDK.
import {
CommunityConfig,
getAccountAddress,
getAccountBalance,
BundlerService,
getProfileFromAddress
} from "@citizenwallet/sdk";
import { Wallet } from "ethers";
// 1. Load configuration
async function initializeSDK(configUrl: string) {
const response = await fetch(configUrl);
const configData = await response.json();
const config = new CommunityConfig(configData);
return config;
}
// 2. Use the SDK
async function main() {
const config = await initializeSDK("https://example.com/config/community.json");
// Get account address
const userAddress = "0x...";
const accountAddress = await getAccountAddress(config, userAddress);
// Get balance
const balance = await getAccountBalance(config, accountAddress);
// Create bundler service
const bundler = new BundlerService(config);
// Get profile
const ipfsDomain = config.ipfs.url.replace('https://', '');
const profile = await getProfileFromAddress(ipfsDomain, config, accountAddress);
return { accountAddress, balance, profile };
}- CommunityConfig must be instantiated before using any SDK functions
- Config is typically loaded from a JSON URL or file
- Pass
CommunityConfigas the first parameter to most SDK functions - The config contains all blockchain and community-specific information
- Use helper methods on
CommunityConfigto access common resources likeprimaryToken,primaryNetwork, etc.