Skip to Content
SDKQuery API

Query API

MACI SDK provides rich query functions to retrieve various information.

Round Queries

Query Round by ID

// Method 1: Use getRoundInfo (recommended) const round = await client.getRoundInfo({ contractAddress: 'dora1contractaddress...' }); // Method 2: Use indexer query const round = await client.indexer.getRoundById('dora1contractaddress...'); console.log('Round info:', { title: round.title, description: round.description, status: round.status, coordinatorPubkey: round.coordinatorPubkey, numSignups: round.numSignups, votingTime: round.votingTime, voteOptionMap: round.voteOptionMap });

Get Round List

const rounds = await client.getRounds('first', 10); rounds.forEach(round => { console.log(`- ${round.title} (${round.status})`); });

Query by Status

const activeRounds = await client.indexer.getRoundsByStatus( 'Voting', 'first', 10 ); // Available statuses: 'Created', 'Voting', 'Processing', 'Tallied'

Query by Operator

const operatorRounds = await client.indexer.getRoundsByOperator( 'dora1operator...', 'first', 10 );

Query by Circuit Type

// Query all QV votes const qvRounds = await client.indexer.getRoundsByCircuitName( 'amaci-qv', 'first', 10 ); // Query all 1P1V votes const p1vRounds = await client.indexer.getRoundsByCircuitName( 'amaci-1p1v', 'first', 10 );

Operator Queries

Query Operator by Address

const operator = await client.indexer.getOperatorByAddress('dora1operator...'); console.log('Operator info:', { address: operator.address, pubkey: operator.pubkey, identity: operator.identity, isActive: operator.isActive });

Get Operator List

const operators = await client.indexer.getOperators('first', 10); operators.forEach(op => { console.log(`- ${op.identity || op.address}`); });

Circuit Queries

Query Circuit by Name

const circuit = await client.indexer.getCircuitByName('amaci-qv'); console.log('Circuit info:', { name: circuit.name, type: circuit.type, description: circuit.description });

Get All Circuits

const circuits = await client.indexer.getCircuits(); circuits.forEach(circuit => { console.log(`- ${circuit.name}: ${circuit.description}`); });

Transaction Queries

Query Transaction by Hash

const tx = await client.indexer.getTransactionByHash('ABCD1234...'); console.log('Transaction info:', { hash: tx.hash, height: tx.height, success: tx.success, gasUsed: tx.gasUsed, timestamp: tx.timestamp });

Query Transactions by Contract Address

const transactions = await client.indexer.getTransactionsByContractAddress( 'dora1contract...', 'first', 10 ); transactions.forEach(tx => { console.log(`- ${tx.type} at block ${tx.height}`); });

Get Transaction List

const recentTxs = await client.indexer.getTransactions('first', 20);

Proof Queries

Query Proof Information

const proof = await client.indexer.getProofByContractAddress('dora1contract...'); console.log('Proof info:', { contractAddress: proof.contractAddress, hasProcessMessagesProof: proof.hasProcessMessagesProof, hasTallyProof: proof.hasTallyProof, processedAt: proof.processedAt, talliedAt: proof.talliedAt });

Balance Queries

Query Account Balance

const balance = await client.indexer.balanceOf('dora1address...'); console.log('Balance:', { amount: balance.amount, denom: balance.denom });

Advanced Queries

Pagination

All list queries support pagination:

// First page const page1 = await client.getRounds('first', 10); // Next page (use last item's ID) const lastId = page1[page1.length - 1].id; const page2 = await client.getRounds('after', 10, lastId); // Previous page const page0 = await client.getRounds('before', 10, page1[0].id);

Combined Query Example

async function findActiveQVRounds(client: MaciClient) { const qvRounds = await client.indexer.getRoundsByCircuitName('amaci-qv', 'first', 100); const activeRounds = qvRounds.filter(round => { const now = Date.now() / 1000; return ( round.votingTime.startTime <= now && round.votingTime.endTime >= now && round.status === 'Voting' ); }); activeRounds.sort((a, b) => b.numSignups - a.numSignups); return activeRounds; } const popularRounds = await findActiveQVRounds(client); console.log(`Found ${popularRounds.length} active QV rounds`);

Monitor Round Status

async function waitForRoundToFinish( client: MaciClient, contractAddress: string ): Promise<void> { while (true) { const round = await client.getRoundInfo({ contractAddress }); if (round.status === 'Tallied') { console.log('Round finished'); break; } console.log(`Current status: ${round.status}`); await new Promise(resolve => setTimeout(resolve, 10000)); } }

Error Handling

async function safeQuery<T>( queryFn: () => Promise<T> ): Promise<T | null> { try { return await queryFn(); } catch (error) { console.error('Query failed:', error); return null; } } const round = await safeQuery(() => client.getRoundInfo({ contractAddress: 'dora1contract...' }) ); if (round) { console.log('Round:', round.title); } else { console.log('Round not found or query failed'); }

Cached Queries

For frequently queried data, implement simple caching:

class CachedMaciClient { private cache = new Map<string, { data: any; expiry: number }>(); private cacheDuration = 60000; constructor(private client: MaciClient) {} async getRoundById(contractAddress: string) { const key = `round:${contractAddress}`; const cached = this.cache.get(key); if (cached && cached.expiry > Date.now()) { return cached.data; } const data = await this.client.getRoundInfo({ contractAddress }); this.cache.set(key, { data, expiry: Date.now() + this.cacheDuration }); return data; } } const cachedClient = new CachedMaciClient(client); const round1 = await cachedClient.getRoundById('dora1...'); const round2 = await cachedClient.getRoundById('dora1...'); // Uses cache
Last updated on