Getting started
This page sweeps one chain with the SDK's ZeroDustAgent, which signs locally with a key you control. Run a dry run first: it does everything except submit, so nothing moves.
Before you start
- Node.js 18 or later.
- A wallet with a balance on a supported chain (
GET /chains). - The wallet's private key, kept in a secrets store or an environment variable. Never put a key in source code or commit it.
1. Install
npm install @zerodust/sdk viem
viem is a peer dependency.
2. Create an agent
import { ZeroDustAgent } from '@zerodust/sdk';
import { privateKeyToAccount } from 'viem/accounts';
const agent = new ZeroDustAgent({
account: privateKeyToAccount(process.env.ZERODUST_PRIVATE_KEY as `0x${string}`),
environment: 'mainnet',
});
console.log('Sweeping from', agent.address);
The key never leaves the process. The agent sends only signatures to the API.
3. Find what can be swept
const sweepable = await agent.getSweepableBalances();
for (const b of sweepable) {
console.log(b.chainId, b.name, b.balanceFormatted, b.nativeToken);
}
A balance shows as sweepable when it is above 0. Whether it covers the fees is decided by the quote.
4. Dry run
const check = await agent.sweep(
{ fromChainId: 42161, toChainId: 8453, destination: '0xYourDestination' },
{ dryRun: true },
);
if (!check.success) throw new Error(check.error);
console.log('Would receive (wei):', check.quote?.estimatedReceive);
A dry run fetches a real quote, verifies it, and produces all three signatures with your key, then stops before POST /sweep. Nothing is broadcast. If the quote fails a safety check, success is false and nothing was signed.
destination defaults to the agent's own address. Here the balance on Arbitrum (42161) is bridged to Base (8453). For a same-chain sweep, set toChainId to fromChainId and use a different destination address.
5. Sweep
const result = await agent.sweep({
fromChainId: 42161,
toChainId: 8453,
destination: '0xYourDestination',
});
if (result.success) {
console.log('Sweep', result.sweepId, 'tx', result.txHash);
} else {
console.error('Sweep failed:', result.error);
}
By default sweep() waits up to 120 seconds for the sweep to reach completed or failed.
6. Check the result on-chain
The API reports status, but the chain is the source of truth. A sweep is done when:
- the source balance is 0,
- the wallet has no code again (the delegation was revoked), and
- the funds arrived at the destination.
import { createPublicClient, http } from 'viem';
import { arbitrum } from 'viem/chains';
const source = createPublicClient({ chain: arbitrum, transport: http() });
console.log('Balance:', await source.getBalance({ address: agent.address })); // 0n
console.log('Code:', await source.getCode({ address: agent.address })); // undefined once revoked
The revoke is a separate transaction sent after the sweep, so the code can still be set for a short time after the sweep completes. getSweepStatus() reports it as revokeStatus.
Next
- Agent: batch sweeps,
sweepAll(), custom RPC URLs, and the checks the agent runs before signing. - API client: call each endpoint yourself.
- MCP server: give an AI client the same abilities.