Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 14 additions & 3 deletions cmd/sim/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,24 @@ import (
func NewAuthCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "auth",
Short: "Authenticate with the Sim API",
Long: "Save your Sim API key so you don't need to pass --sim-api-key or set DUNE_SIM_API_KEY every time.",
Short: "Save your Sim API key to the local configuration file",
Long: "Persist your Sim API key to ~/.config/dune/config.yaml so subsequent\n" +
"'dune sim' commands authenticate automatically without requiring\n" +
"--sim-api-key or the DUNE_SIM_API_KEY environment variable.\n\n" +
"The key can be provided via:\n" +
" 1. --api-key flag\n" +
" 2. DUNE_SIM_API_KEY environment variable\n" +
" 3. Interactive prompt (if neither of the above is set)\n\n" +
"The saved key is used as the lowest-priority fallback; --sim-api-key and\n" +
"DUNE_SIM_API_KEY always take precedence when set.\n\n" +
"Examples:\n" +
" dune sim auth\n" +
" dune sim auth --api-key sim_abc123...",
Annotations: map[string]string{"skipSimAuth": "true"},
RunE: runSimAuth,
}

cmd.Flags().String("api-key", "", "Sim API key to save")
cmd.Flags().String("api-key", "", "Sim API key to save (prefixed 'sim_'); if omitted, reads from DUNE_SIM_API_KEY or prompts interactively")

return cmd
}
Expand Down
36 changes: 26 additions & 10 deletions cmd/sim/evm/activity.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,23 +14,39 @@ import (
func NewActivityCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "activity <address>",
Short: "Get EVM activity feed for a wallet address",
Long: "Return a chronological feed of on-chain activity for the given wallet address\n" +
"including native transfers, ERC20 movements, NFT transfers, swaps, and contract calls.\n\n" +
Short: "Get a decoded activity feed for a wallet address across EVM chains",
Long: "Return a reverse-chronological feed of human-readable on-chain activity for\n" +
"the given wallet address. Unlike raw transactions, activity entries are decoded\n" +
"and classified into semantic types: sends, receives, mints, burns, token swaps,\n" +
"approvals, and contract calls.\n\n" +
"Activity types:\n" +
" - send/receive: native or token transfers to/from the wallet\n" +
" - mint/burn: token creation or destruction involving the wallet\n" +
" - swap: DEX token exchanges (includes from/to token details)\n" +
" - approve: ERC20/ERC721 spending approvals\n" +
" - call: contract interactions with decoded function name and inputs\n\n" +
"Asset types: native, erc20, erc721, erc1155.\n\n" +
"Each activity item includes the transaction context, transfer amounts with\n" +
"USD values, and token metadata. Swap entries include both sides of the trade.\n" +
"Call entries include the decoded function name and inputs.\n\n" +
"By default, returns all activity types across all default chains.\n" +
"Run 'dune sim evm supported-chains' to see which chains support activity.\n\n" +
"For raw transaction data (hashes, gas, calldata), use 'dune sim evm transactions'.\n\n" +
"Examples:\n" +
" dune sim evm activity 0xd8da6bf26964af9d7eed9e03e53415d37aa96045\n" +
" dune sim evm activity 0xd8da... --activity-type send,receive --chain-ids 1\n" +
" dune sim evm activity 0xd8da... --asset-type erc20 --limit 50 -o json",
" dune sim evm activity 0xd8da... --asset-type erc20 --limit 50 -o json\n" +
" dune sim evm activity 0xd8da... --token-address 0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
Args: cobra.ExactArgs(1),
RunE: runActivity,
}

cmd.Flags().String("chain-ids", "", "Comma-separated chain IDs or tags (default: all default chains)")
cmd.Flags().String("token-address", "", "Filter by token contract address (comma-separated for multiple)")
cmd.Flags().String("activity-type", "", "Filter by type: send,receive,mint,burn,swap,approve,call")
cmd.Flags().String("asset-type", "", "Filter by asset standard: native,erc20,erc721,erc1155")
cmd.Flags().Int("limit", 0, "Max results (1-100)")
cmd.Flags().String("offset", "", "Pagination cursor from previous response")
cmd.Flags().String("chain-ids", "", "Restrict to specific chains by numeric ID or tag name (comma-separated, e.g. '1,8453' or 'default'); defaults to all chains tagged 'default'")
cmd.Flags().String("token-address", "", "Filter activities involving specific token contracts (comma-separated ERC20/ERC721/ERC1155 addresses)")
cmd.Flags().String("activity-type", "", "Filter by activity classification (comma-separated): send, receive, mint, burn, swap, approve, call; defaults to all types")
cmd.Flags().String("asset-type", "", "Filter by token standard (comma-separated): native, erc20, erc721, erc1155; defaults to all standards")
cmd.Flags().Int("limit", 0, "Maximum number of activity items to return per page (1-100, default: server-determined)")
cmd.Flags().String("offset", "", "Pagination cursor returned as next_offset in a previous response; use to fetch the next page of results")
output.AddFormatFlag(cmd, "text")

return cmd
Expand Down
23 changes: 14 additions & 9 deletions cmd/sim/evm/balance.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,21 +14,26 @@ import (
func NewBalanceCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "balance <wallet_address>",
Short: "Get balance for a single token",
Long: "Return the balance of a single token for the given wallet address on one chain.\n" +
"Use \"native\" as the --token value to query the native asset (e.g. ETH).\n\n" +
Short: "Get the balance of a single token for a wallet on one chain",
Long: "Return the balance of a specific token for the given wallet address on a\n" +
"single EVM chain. This is a targeted lookup that returns exactly one balance\n" +
"entry, unlike 'dune sim evm balances' which returns all tokens across chains.\n\n" +
"Both --token and --chain-ids are required. Use the literal string 'native'\n" +
"as the --token value to query the chain's native asset (e.g. ETH on Ethereum,\n" +
"MATIC on Polygon), or pass an ERC20 contract address.\n\n" +
"For multi-token or multi-chain lookups, use 'dune sim evm balances' instead.\n\n" +
"Examples:\n" +
" dune sim evm balance 0xd8da... --token native --chain-ids 1\n" +
" dune sim evm balance 0xd8da... --token 0xa0b8...eb48 --chain-ids 8453\n" +
" dune sim evm balance 0xd8da... --token native --chain-ids 1 -o json",
" dune sim evm balance 0xd8da... --token 0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48 --chain-ids 8453\n" +
" dune sim evm balance 0xd8da... --token native --chain-ids 1 --historical-prices 168,24 -o json",
Args: cobra.ExactArgs(1),
RunE: runBalance,
}

cmd.Flags().String("token", "", "Token contract address or \"native\" (required)")
cmd.Flags().String("chain-ids", "", "Chain ID (required)")
cmd.Flags().String("metadata", "", "Extra metadata fields: logo,url,pools")
cmd.Flags().String("historical-prices", "", "Hour offsets for historical prices (e.g. 720,168,24)")
cmd.Flags().String("token", "", "Token to query: an ERC20 contract address (0x...) or the literal string 'native' for the chain's native asset (required)")
cmd.Flags().String("chain-ids", "", "Numeric EVM chain ID to query (required, single value, e.g. '1' for Ethereum, '8453' for Base)")
cmd.Flags().String("metadata", "", "Request additional metadata fields in the response (comma-separated): 'logo' (token icon URL), 'url' (project website), 'pools' (liquidity pool details)")
cmd.Flags().String("historical-prices", "", "Include historical USD prices at the specified hour offsets from now (comma-separated, e.g. '720,168,24' for 30d, 7d, 1d ago)")
_ = cmd.MarkFlagRequired("token")
_ = cmd.MarkFlagRequired("chain-ids")
output.AddFormatFlag(cmd, "text")
Expand Down
33 changes: 21 additions & 12 deletions cmd/sim/evm/balances.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,28 @@ import (
func NewBalancesCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "balances <address>",
Short: "Get EVM token balances for a wallet address",
Long: "Return native and ERC20 token balances for the given wallet address\n" +
"across supported EVM chains, including USD valuations.\n\n" +
Short: "Get EVM token balances for a wallet address across multiple chains",
Long: "Return native and ERC20 token balances for the given wallet address across\n" +
"supported EVM chains. Each balance entry includes the token identity, raw\n" +
"balance amount, current USD price, total USD value, and liquidity indicators.\n" +
"Data comes from Dune's real-time index.\n\n" +
"By default, queries all chains tagged 'default'. Use --chain-ids to restrict\n" +
"to specific networks. Run 'dune sim evm supported-chains' to see valid IDs.\n\n" +
"For a single-token balance lookup, use 'dune sim evm balance' instead.\n" +
"For stablecoin-only balances, use 'dune sim evm stablecoins'.\n\n" +
"Results are paginated; use --offset with the next_offset value from a\n" +
"previous response to retrieve additional pages.\n\n" +
"Examples:\n" +
" dune sim evm balances 0xd8da6bf26964af9d7eed9e03e53415d37aa96045\n" +
" dune sim evm balances 0xd8da... --chain-ids 1,8453 --exclude-spam\n" +
" dune sim evm balances 0xd8da... --historical-prices 168 -o json",
" dune sim evm balances 0xd8da... --filters erc20 --metadata logo,url\n" +
" dune sim evm balances 0xd8da... --historical-prices 720,168,24 -o json",
Args: cobra.ExactArgs(1),
RunE: runBalances,
}

addBalanceFlags(cmd)
cmd.Flags().String("asset-class", "", "Asset class filter: stablecoin")
cmd.Flags().String("asset-class", "", "Filter by asset classification: 'stablecoin' (returns only stablecoins like USDC, USDT, DAI); prefer 'dune sim evm stablecoins' as a shorthand")

return cmd
}
Expand Down Expand Up @@ -103,13 +112,13 @@ func runBalances(cmd *cobra.Command, args []string) error {
// addBalanceFlags registers the common flags shared by the balances and
// stablecoins commands.
func addBalanceFlags(cmd *cobra.Command) {
cmd.Flags().String("chain-ids", "", "Comma-separated chain IDs or tags (default: all default chains)")
cmd.Flags().String("filters", "", "Token filter: erc20 or native")
cmd.Flags().String("metadata", "", "Extra metadata fields: logo,url,pools")
cmd.Flags().Bool("exclude-spam", false, "Exclude tokens with <100 USD liquidity")
cmd.Flags().String("historical-prices", "", "Hour offsets for historical prices (e.g. 720,168,24)")
cmd.Flags().Int("limit", 0, "Max results (1-1000)")
cmd.Flags().String("offset", "", "Pagination cursor from previous response")
cmd.Flags().String("chain-ids", "", "Restrict to specific chains by numeric ID or tag name (comma-separated, e.g. '1,8453' or 'default'); defaults to all chains tagged 'default'. Run 'dune sim evm supported-chains' for valid values")
cmd.Flags().String("filters", "", "Filter by token standard: 'erc20' (only ERC20 tokens) or 'native' (only native chain assets like ETH)")
cmd.Flags().String("metadata", "", "Request additional metadata fields in the response (comma-separated): 'logo' (token icon URL), 'url' (project website), 'pools' (liquidity pool details)")
cmd.Flags().Bool("exclude-spam", false, "Exclude low-liquidity tokens (less than $100 USD pool size) commonly associated with spam airdrops")
cmd.Flags().String("historical-prices", "", "Include historical USD prices at the specified hour offsets from now (comma-separated, e.g. '720,168,24' for 30d, 7d, 1d ago)")
cmd.Flags().Int("limit", 0, "Maximum number of balance entries to return per page (1-1000, default: server-determined)")
cmd.Flags().String("offset", "", "Pagination cursor returned as next_offset in a previous response; use to fetch the next page of results")
output.AddFormatFlag(cmd, "text")
}

Expand Down
27 changes: 18 additions & 9 deletions cmd/sim/evm/collectibles.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,22 +14,31 @@ import (
func NewCollectiblesCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "collectibles <address>",
Short: "Get NFT collectibles for a wallet address",
Long: "Return ERC721 and ERC1155 collectibles (NFTs) held by the given wallet address\n" +
"across supported EVM chains. Spam filtering is enabled by default.\n\n" +
Short: "Get NFT collectibles (ERC721/ERC1155) held by a wallet address",
Long: "Return ERC721 and ERC1155 collectibles (NFTs) held by the given wallet\n" +
"address across supported EVM chains. Each entry includes the collection and\n" +
"token identity, image URL, quantity held, acquisition timestamp, and spam\n" +
"classification when requested. Spam filtering is enabled by default to hide\n" +
"airdropped junk NFTs.\n\n" +
"Spam filtering uses a scoring model based on collection traits (holder count,\n" +
"transfer patterns, metadata quality). Disable with --filter-spam=false to see\n" +
"all NFTs including suspected spam.\n\n" +
"By default, queries all chains tagged 'default'. Run 'dune sim evm\n" +
"supported-chains' to see which chains support collectibles.\n\n" +
"Examples:\n" +
" dune sim evm collectibles 0xd8da6bf26964af9d7eed9e03e53415d37aa96045\n" +
" dune sim evm collectibles 0xd8da... --chain-ids 1\n" +
" dune sim evm collectibles 0xd8da... --filter-spam=false --show-spam-scores -o json",
" dune sim evm collectibles 0xd8da... --filter-spam=false --show-spam-scores -o json\n" +
" dune sim evm collectibles 0xd8da... --limit 100 -o json",
Args: cobra.ExactArgs(1),
RunE: runCollectibles,
}

cmd.Flags().String("chain-ids", "", "Comma-separated chain IDs or tags (default: all default chains)")
cmd.Flags().Bool("filter-spam", true, "Hide collectibles identified as spam")
cmd.Flags().Bool("show-spam-scores", false, "Include spam scoring details")
cmd.Flags().Int("limit", 0, "Max results per page (1-2500, default 250)")
cmd.Flags().String("offset", "", "Pagination cursor from previous response")
cmd.Flags().String("chain-ids", "", "Restrict to specific chains by numeric ID or tag name (comma-separated, e.g. '1,8453' or 'default'); defaults to all chains tagged 'default'")
cmd.Flags().Bool("filter-spam", true, "Hide collectibles identified as spam by the scoring model (default: true); set --filter-spam=false to include all NFTs")
cmd.Flags().Bool("show-spam-scores", false, "Include spam classification details in the response: is_spam flag, numeric spam_score, and per-feature explanations with weights")
cmd.Flags().Int("limit", 0, "Maximum number of collectibles to return per page (1-2500, default: 250)")
cmd.Flags().String("offset", "", "Pagination cursor returned as next_offset in a previous response; use to fetch the next page of results")
output.AddFormatFlag(cmd, "text")

return cmd
Expand Down
25 changes: 19 additions & 6 deletions cmd/sim/evm/defi_positions.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,24 @@ import (
func NewDefiPositionsCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "defi-positions <address>",
Short: "Get DeFi positions for a wallet address",
Long: "Return DeFi positions for the given wallet address including USD values,\n" +
"position-specific metadata, and aggregation summaries across supported protocols.\n\n" +
"Supported position types: Erc4626 (vaults), Tokenized (lending, e.g. aTokens),\n" +
"UniswapV2 (AMM LP), Nft (Uniswap V3 NFT), NftV4 (Uniswap V4 NFT).\n\n" +
Short: "Get DeFi positions (lending, LPs, vaults) for a wallet address",
Long: "Return DeFi positions for the given wallet address across supported EVM\n" +
"chains and protocols. Each position includes USD valuation and protocol-\n" +
"specific metadata. The response also includes aggregation summaries with\n" +
"total USD value and per-chain breakdowns.\n\n" +
"Note: This endpoint is in beta (served under /beta/evm/defi/positions/*).\n\n" +
"Supported position types:\n" +
" - Erc4626: ERC-4626 vault positions (e.g. yield vaults, staking wrappers)\n" +
" - Tokenized: lending protocol positions with receipt tokens (e.g. Aave\n" +
" aTokens, Compound cTokens)\n" +
" - UniswapV2: AMM liquidity provider positions (Uniswap V2 and forks)\n" +
" - Nft: Uniswap V3 concentrated liquidity positions (NFT-based)\n" +
" - NftV4: Uniswap V4 concentrated liquidity positions (NFT-based)\n\n" +
"Each position includes the chain, USD value, protocol name, and type-\n" +
"specific details (token identities, pool info, balances). The response\n" +
"also includes aggregation summaries with total value and per-chain\n" +
"breakdowns. Use -o json for the full structured response.\n\n" +
"Run 'dune sim evm supported-chains' to see which chains support defi-positions.\n\n" +
"Examples:\n" +
" dune sim evm defi-positions 0xd8da6bf26964af9d7eed9e03e53415d37aa96045\n" +
" dune sim evm defi-positions 0xd8da... --chain-ids 1,8453\n" +
Expand All @@ -31,7 +44,7 @@ func NewDefiPositionsCmd() *cobra.Command {
RunE: runDefiPositions,
}

cmd.Flags().String("chain-ids", "", "Comma-separated chain IDs or tags (default: all default chains)")
cmd.Flags().String("chain-ids", "", "Restrict to specific chains by numeric ID or tag name (comma-separated, e.g. '1,8453' or 'default'); defaults to all chains tagged 'default'")
output.AddFormatFlag(cmd, "text")

return cmd
Expand Down
23 changes: 19 additions & 4 deletions cmd/sim/evm/evm.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,25 @@ func SimClientFromCmd(cmd *cobra.Command) SimClient {
func NewEvmCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "evm",
Short: "Query EVM chain data (balances, activity, transactions, etc.)",
Long: "Access real-time EVM blockchain data including token balances, activity feeds,\n" +
"transaction history, NFT collectibles, token metadata, token holders,\n" +
"and DeFi positions.",
Short: "Query EVM chain data (balances, activity, transactions, tokens, NFTs, DeFi)",
Long: "Access real-time, indexed EVM blockchain data. All commands accept an\n" +
"Ethereum-style address (0x...) as the primary argument and return data\n" +
"across multiple EVM chains simultaneously.\n\n" +
"Available subcommands:\n" +
" supported-chains - List all supported EVM chains and endpoint availability (public, no auth)\n" +
" balances - Native + ERC20 token balances with USD valuations\n" +
" balance - Single-token balance lookup on one chain\n" +
" stablecoins - Stablecoin-only balances (USDC, USDT, DAI, etc.)\n" +
" activity - Chronological feed of transfers, swaps, mints, burns, approvals\n" +
" transactions - Raw transaction history with optional ABI decoding\n" +
" collectibles - ERC721 and ERC1155 NFT holdings with spam filtering\n" +
" token-info - Token metadata, pricing, supply, and market cap\n" +
" token-holders - Top holders of an ERC20 token ranked by balance\n" +
" defi-positions - DeFi positions across lending, AMM, and vault protocols (beta)\n\n" +
"Most commands support --chain-ids to restrict results to specific networks.\n" +
"Run 'dune sim evm supported-chains' to discover valid chain IDs, tags, and\n" +
"which endpoints are available per chain.\n\n" +
"All commands except 'supported-chains' require a Sim API key.",
}

cmd.AddCommand(NewSupportedChainsCmd())
Expand Down
15 changes: 11 additions & 4 deletions cmd/sim/evm/stablecoins.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,20 @@ import (
func NewStablecoinsCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "stablecoins <address>",
Short: "Get stablecoin balances for a wallet address",
Long: "Return stablecoin balances for the given wallet address across supported\n" +
"EVM chains, including USD valuations.\n\n" +
Short: "Get stablecoin balances for a wallet address across multiple chains",
Long: "Return only stablecoin balances (USDC, USDT, DAI, FRAX, etc.) for the given\n" +
"wallet address across supported EVM chains. This is a convenience shorthand\n" +
"for 'dune sim evm balances <address> --asset-class stablecoin'.\n\n" +
"Each balance entry includes the token amount, current USD price, and total\n" +
"USD value. The same response format and pagination as 'dune sim evm balances'\n" +
"applies.\n\n" +
"By default, queries all chains tagged 'default'. Use --chain-ids to restrict\n" +
"to specific networks. Run 'dune sim evm supported-chains' for valid IDs.\n\n" +
"For all token balances (not just stablecoins), use 'dune sim evm balances'.\n\n" +
"Examples:\n" +
" dune sim evm stablecoins 0xd8da6bf26964af9d7eed9e03e53415d37aa96045\n" +
" dune sim evm stablecoins 0xd8da... --chain-ids 1,8453\n" +
" dune sim evm stablecoins 0xd8da... -o json",
" dune sim evm stablecoins 0xd8da... --exclude-spam -o json",
Args: cobra.ExactArgs(1),
RunE: runStablecoins,
}
Expand Down
Loading
Loading