# Get chain by ID Source: https://developers.zerion.io/api-reference/chains/get-chain-by-id /openapi-v1.yaml get /v1/chains/{chain_id} This endpoint returns chain by unique chain identifier. This endpoint supports testnets. To get data for testnets use `X-Env` header. # Get list of all chains Source: https://developers.zerion.io/api-reference/chains/get-list-of-all-chains /openapi-v1.yaml get /v1/chains/ This endpoint returns list of all chains supported by Zerion. This endpoint supports testnets. To get data for testnets use `X-Env` header. # Get DApp by ID Source: https://developers.zerion.io/api-reference/dapps/get-dapp-by-id /openapi-v1.yaml get /v1/dapps/{dapp_id} This endpoint returns single DApp by its unique identifier. # Get list of DApps Source: https://developers.zerion.io/api-reference/dapps/get-list-of-dapps /openapi-v1.yaml get /v1/dapps This endpoint returns list of DApps by using different parameters. > NOTE: Consider all IDs as abstract strings, without making any assumptions about their format or relying on such assumptions. There is a non-zero probability that IDs may change in the future, and this should not result in any breaking changes. # Get a chart for a fungible asset Source: https://developers.zerion.io/api-reference/fungibles/get-a-chart-for-a-fungible-asset /openapi-v1.yaml get /v1/fungibles/{fungible_id}/charts/{chart_period} This endpoint returns the chart for the fungible asset for a selected period # Get a chart for a fungible asset by implementation Source: https://developers.zerion.io/api-reference/fungibles/get-a-chart-for-a-fungible-asset-by-implementation /openapi-v1.yaml get /v1/fungibles/by-implementation/charts/{chart_period} This endpoint returns the chart for a fungible asset for a selected period, identified by its implementation. The implementation is a chain:address pair (e.g., "ethereum:0xa5a4214bb5f00c86b7969b7dc007302e4f6f05d6"). # Get fungible asset by ID Source: https://developers.zerion.io/api-reference/fungibles/get-fungible-asset-by-id /openapi-v1.yaml get /v1/fungibles/{fungible_id} This endpoint returns a fungible asset by unique identifier # Get fungible asset by implementation Source: https://developers.zerion.io/api-reference/fungibles/get-fungible-asset-by-implementation /openapi-v1.yaml get /v1/fungibles/by-implementation This endpoint returns a fungible asset by its implementation. The implementation is a `chain` (for base asset) or `chain:address` pair (e.g., "ethereum", ethereum:0xa5a4214bb5f00c86b7969b7dc007302e4f6f05d6"). # Get list of fungible assets Source: https://developers.zerion.io/api-reference/fungibles/get-list-of-fungible-assets /openapi-v1.yaml get /v1/fungibles/ This endpoint returns a paginated list of fungible assets supported by Zerion. It also provides the ability to search for fungibles. If no fungible assets are found for given filters, the empty list with 200 status is returned. > NOTE: This endpoint supports a lot of filters, sorting, and pagination parameters. Ensure your request URL length is within a safe range for your platform. Usually, 2000 characters are the safe limit in virtually any combination of client and server software. > NOTE: The `filter[implementation_address]` parameter ignores `filter[search_query]`. It may be changed in the future. > NOTE: Consider all IDs as abstract strings, without making any assumptions about their format or relying on such assumptions. There is a non-zero probability that IDs may change in the future, and this should not result in any breaking changes. # Get list of all available gas prices Source: https://developers.zerion.io/api-reference/gas/get-list-of-all-available-gas-prices /openapi-v1.yaml get /v1/gas-prices/ This endpoint provides real-time information on the current gas prices across all supported blockchain networks. Gas prices play a crucial role in the speed and cost of executing transactions on a blockchain, and fluctuate frequently based on network demand and usage. By using this endpoint, developers can stay up-to-date with the latest gas prices and adjust their application's transaction parameters accordingly to ensure optimal speed and cost efficiency. # Get list of NFTs Source: https://developers.zerion.io/api-reference/nfts/get-list-of-nfts /openapi-v1.yaml get /v1/nfts/ This endpoint returns list of NFTs by using different parameters. It returns NFTs of both types - ERC721 and ERC1155. This endpoint supports testnets. To get data for testnets use `X-Env` header. > NOTE: Consider all IDs as abstract strings, without making any assumptions about their format or relying on such assumptions. There is a non-zero probability that IDs may change in the future, and this should not result in any breaking changes. # Get single NFT by ID Source: https://developers.zerion.io/api-reference/nfts/get-single-nft-by-id /openapi-v1.yaml get /v1/nfts/{nft_id} This endpoint returns single NFT by its unique identifier. This endpoint supports testnets. To get data for testnets use `X-Env` header. # Count wallets within subscription Source: https://developers.zerion.io/api-reference/subscriptions-to-transactions/count-wallets-within-subscription /openapi-v1.yaml get /v1/tx-subscriptions/{subscription_id}/wallets/count This endpoint returns the count of wallets within a specific subscription by subscription ID. > NOTE: Consider all IDs as abstract strings, without making any assumptions about their format or relying on such assumptions. There is a non-zero probability that IDs may change in the future, and this should not result in any breaking changes. # Create subscription Source: https://developers.zerion.io/api-reference/subscriptions-to-transactions/create-subscription /openapi-v1.yaml post /v1/tx-subscriptions/ This endpoint subscribes to new transactions associated with the wallets. > NOTE: Consider all IDs as abstract strings, without making any assumptions about their format or relying on such assumptions. There is a non-zero probability that IDs may change in the future, and this should not result in any breaking changes. ### Use Case The main use case for the webhooks system is to send notifications, similar to push notifications in the Zerion App. ### Setup Callback URL If you want to use this endpoint to test how it works, you might use your dev key to start. It has limits: one subscription & maximum 5 wallets per subscription. You may use callback URL from webhook.site to start from. If want use your custom - contact us at api@zerion.io, and we will whitelist your URL. If you want to use this endpoint in your production environment, you should contact us and provide the following details: - Your email associated with the API key - The URL that you prefer using as the callback (or host). After we've whitelisted your callback URL (or host), you may start using this endpoint. ### Note - **Subscription Validity**: Every subscription is valid for unlimited amount of time for production key, and one week for `dev` keys. - **Transaction Prices**: Prices are not attached to webhook notifications and will always be `null`. Prices are added to transactions in the backend after some time. To get prices, query the transactions endpoint by hash. - **Delivery Guarantees**: Webhook delivery is not guaranteed. If delivery fails three times, no further attempts will be made. - **Order of Dispatch**: The order of webhook dispatch is not guaranteed and may not correspond to the order of transactions occurring on the blockchain. ### Callback Format and Signature Verification Approved clients will receive notifications via POST requests to their provided URL. These notifications will include a signed notification object in the body (specified below in the `Callback` section) and a signature in the headers. Clients should verify the signature provided in the headers of the webhook request to ensure the authenticity of the data. The following headers will be included: - `X-Signature`: The signature of the request. - `X-Timestamp`: The timestamp of the request. - `X-Certificate-URL`: The URL to download the public certificate used to verify the signature. **To verify the signature:** 1. Concatenate the `X-Timestamp` header value, the request body, and a newline character: `$timestamp + "\n" + $request.body + "\n"` 2. Use the public certificate downloaded from the `X-Certificate-URL` header to verify the signature in the `X-Signature` header. Example code in go for message verification: ```go package signature import ( "crypto" "crypto/rsa" "crypto/sha256" "crypto/x509" "encoding/base64" "encoding/pem" "errors" "github.com/stretchr/testify/assert" "testing" ) // FetchCertificate fetches the certificate from the given URL func FetchCertificate() (*x509.Certificate, error) { certBytes := certificate() block, _ := pem.Decode(certBytes) if block == nil || block.Type != "CERTIFICATE" { return nil, errors.New("failed to decode PEM block containing the certificate") } return x509.ParseCertificate(block.Bytes) } func certificate() []byte { return []byte(`-----BEGIN CERTIFICATE----- MIIDMTCCAhmgAwIBAgIUDd3dFMswamyJ5A1bqF0nzS8v2wgwDQYJKoZIhvcNAQEL BQAwQTELMAkGA1UEBhMCVVMxFDASBgNVBAoMC1plcmlvbiBJbmMuMRwwGgYJKoZI hvcNAQkBFg1hcGlAemVyaW9uLmlvMB4XDTI0MDYyNzE1MzUzM1oXDTI1MDYyNzE1 MzUzM1owQTELMAkGA1UEBhMCVVMxFDASBgNVBAoMC1plcmlvbiBJbmMuMRwwGgYJ KoZIhvcNAQkBFg1hcGlAemVyaW9uLmlvMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A MIIBCgKCAQEAwcPVCPLDhS9dLA8s5J6GJ3t0+jWuUCFwI+q6c03xZnhCaz45FepN MTiApbvPw1Zm8F8JQB4BRp/F5anokNcDSl/qmNtj3M/z/FrsVvGnSH2FOkZu9TLU LTW5i8Q0LAYrpgiBHrTa2qrRXd2DiMrEs3QZVoylFYc9QIGet3SULPrlSsYEKxfB iBZDoFw619NnV6/kBO8FS34Lc+WH5SNNHNnItRrxMv4DMAFyFajSn1IwV6LSWSNK aPJHCzP/Omu95550HQKcXaJYNE/d99NrcLaFI2fCuEVd00nApFo5knKs0FiXpGca l3cLOQG5SCOzUOjQb6X5CynEV+0QiyYxDwIDAQABoyEwHzAdBgNVHQ4EFgQUVL4m u0PcI4nJGUS8syLi5DNL44YwDQYJKoZIhvcNAQELBQADggEBAKaA1oqW0D6KxvIp IZxWf02XK/YFYwxKV55Vas0VWlzNemE2IjlIj0tknZt0EiM9um2FC27U9n3u0ApS UDrk96dQ+/RY3T3fiuXysa3ZL05OpreRk0aPuFU9rB4iLTgFiv1G/X5XXJ8O7OQb 48u0vQnYXjT/nt72TMUoakjZ68QsP64FkG8mcK62Tg+FVWB9YWTFc0wOjsOt9RzJ muKCQ7qx7L1GhkxKX4ZhrYItsH1DzXjeP5aniZgLBSPbxt01tUrSjOGN5CLOpdG8 iOnAFP+Nz8S0h2C7hppOHgC+uxY285UrzAZQoMbCREMV+0Mq/aqdF1B6qoKGNGqL kFbUhvo= -----END CERTIFICATE----- `) } func VerifySignature(cert *x509.Certificate, message, signature string) error { pubKey := cert.PublicKey.(*rsa.PublicKey) hashed := sha256.Sum256([]byte(message)) sigBytes, err := base64.StdEncoding.DecodeString(signature) if err != nil { return err } return rsa.VerifyPKCS1v15(pubKey, crypto.SHA256, hashed[:], sigBytes) } func TestVerifySignature(t *testing.T) { // Example usage x509Cert, err := FetchCertificate() assert.NoError(t, err) xTimestamp := "2024-07-31T00:17:36Z" xSignature := "t65gdR8z3NGh/OQRPzGMFmw36JhDNvOe6LxL6K2hCd3SdYQoTGr76dAy1CpsX2G8XVOIYUIctUQvgICQvtDctVjkRZmXuQDvXHOmiJE0ZknORgjVLFoo5JRYKvwt3EPp6SMN7RtedIX17rH1s2Vp3GRQWSjzN7C/cNgInhCQOP0UDjYlaeNT/yW4B2Qt4uY01yK0YhvQJaFHN+NNr7DZAt4FJuDppItqjaYbHTaFNqLlpI1IX7YvQWVhEYTJY6M4T9IdcGYPJKDljckjvmj9mDHZeh/Y6w8eXjLziMSFvlhJeSn1kBIR3nS7lTcwFNv1CPxD3MM7VB++te3mBbFubg==" messageBody := `{"data":{"attributes":{"timestamp":"2024-07-31T00:17:36.661896043Z"},"id":"15daee90-5028-4b4c-bd49-b4d43fa1a89e","type":"callback"},"included":[{"attributes":{"application_metadata":{"contract_address":"0x8286d601a0ed6cf75e067e0614f73a5b9f024151","method":{"id":"0x7859bb8d","name":""}},"approvals":[],"fee":{"fungible_info":{"flags":{"verified":true},"icon":{"url":"https://cdn.zerion.io/eth.png"},"implementations":[{"address":"","chain_id":"redstone","decimals":18},{"address":"","chain_id":"polygon-zkevm","decimals":18},{"address":"","chain_id":"optimism","decimals":18},{"address":"","chain_id":"zksync-era","decimals":18},{"address":"","chain_id":"mode","decimals":18},{"address":"","chain_id":"base","decimals":18},{"address":"","chain_id":"ethereum","decimals":18},{"address":"","chain_id":"aurora","decimals":18},{"address":"","chain_id":"scroll","decimals":18},{"address":"","chain_id":"rari","decimals":18},{"address":"","chain_id":"astar-zkevm","decimals":18},{"address":"","chain_id":"arbitrum","decimals":18},{"address":"","chain_id":"zora","decimals":18},{"address":"","chain_id":"blast","decimals":18},{"address":"","chain_id":"linea","decimals":18},{"address":"","chain_id":"manta-pacific","decimals":18}],"name":"Ethereum","symbol":"ETH"},"price":null,"quantity":{"decimals":18,"float":0.0000016785001958,"int":"1678500195825","numeric":"0.000001678500195825"},"value":null},"flags":{"is_trash":false},"hash":"0xbbcfb0ac5e466ded168794a162da334634fee3f95adfdb55392999f91b4c6d41","mined_at":"2024-07-31T00:17:35Z","mined_at_block":7490818,"nonce":250,"operation_type":"execute","sent_from":"0xfc0f1b3fb88c5ab19e77a6f7d4d637272e71e684","sent_to":"0x8286d601a0ed6cf75e067e0614f73a5b9f024151","status":"confirmed","transfers":[]},"id":"a65b2541c58a5908a7333480f0ac6792","relationships":{"chain":{"id":"linea","type":"chains"},"dapp":{"id":"","type":"dapps"}},"type":"transactions"}]}` message := xTimestamp + "\n" + messageBody + "\n" err = VerifySignature(x509Cert, message, xSignature) assert.NoError(t, err) } ``` # Delete subscription by ID Source: https://developers.zerion.io/api-reference/subscriptions-to-transactions/delete-subscription-by-id /openapi-v1.yaml delete /v1/tx-subscriptions/{subscription_id} This endpoint deletes existing subscription > NOTE: Consider all IDs as abstract strings, without making any assumptions about their format or relying on such assumptions. There is a non-zero probability that IDs may change in the future, and this should not result in any breaking changes. # Disable a specific subscription Source: https://developers.zerion.io/api-reference/subscriptions-to-transactions/disable-a-specific-subscription /openapi-v1.yaml patch /v1/tx-subscriptions/{subscription_id}/disable This endpoint sets the status of a specific subscription to "disabled". > NOTE: Consider all IDs as abstract strings, without making any assumptions about their format or relying on such assumptions. This ensures flexibility and future-proofing against ID format changes. # Enable a specific subscription Source: https://developers.zerion.io/api-reference/subscriptions-to-transactions/enable-a-specific-subscription /openapi-v1.yaml patch /v1/tx-subscriptions/{subscription_id}/enable This endpoint sets the status of a specific subscription to "enabled". > NOTE: Consider all IDs as abstract strings, without making any assumptions about their format or relying on such assumptions. This ensures flexibility and future-proofing against ID format changes. # Find subscription by ID Source: https://developers.zerion.io/api-reference/subscriptions-to-transactions/find-subscription-by-id /openapi-v1.yaml get /v1/tx-subscriptions/{subscription_id} This endpoint by ID returns subscription to new transactions associated with the wallets and chains. > NOTE: Consider all IDs as abstract strings, without making any assumptions about their format or relying on such assumptions. There is a non-zero probability that IDs may change in the future, and this should not result in any breaking changes. # Find subscriptions Source: https://developers.zerion.io/api-reference/subscriptions-to-transactions/find-subscriptions /openapi-v1.yaml get /v1/tx-subscriptions/ This endpoint finds subscriptions to new transactions associated with the wallets and chains. Currently response is limited to 1000 subscriptions in the response. > NOTE: Consider all IDs as abstract strings, without making any assumptions about their format or relying on such assumptions. There is a non-zero probability that IDs may change in the future, and this should not result in any breaking changes. # Find wallets within subscription Source: https://developers.zerion.io/api-reference/subscriptions-to-transactions/find-wallets-within-subscription /openapi-v1.yaml get /v1/tx-subscriptions/{subscription_id}/wallets This endpoint by subscription ID returns wallets within specific subscription. > NOTE: Consider all IDs as abstract strings, without making any assumptions about their format or relying on such assumptions. There is a non-zero probability that IDs may change in the future, and this should not result in any breaking changes. # Patch wallets within subscription Source: https://developers.zerion.io/api-reference/subscriptions-to-transactions/patch-wallets-within-subscription /openapi-v1.yaml patch /v1/tx-subscriptions/{subscription_id}/wallets This endpoint works by subscription ID. It patches wallets list within specific subscription. > NOTE: Consider all IDs as abstract strings, without making any assumptions about their format or relying on such assumptions. There is a non-zero probability that IDs may change in the future, and this should not result in any breaking changes. # Replace wallets within subscription Source: https://developers.zerion.io/api-reference/subscriptions-to-transactions/replace-wallets-within-subscription /openapi-v1.yaml put /v1/tx-subscriptions/{subscription_id}/wallets This endpoint works by subscription ID. It replaces wallets list within specific subscription. > NOTE: Consider all IDs as abstract strings, without making any assumptions about their format or relying on such assumptions. There is a non-zero probability that IDs may change in the future, and this should not result in any breaking changes. # Update callback URL within subscription Source: https://developers.zerion.io/api-reference/subscriptions-to-transactions/update-callback-url-within-subscription /openapi-v1.yaml patch /v1/tx-subscriptions/{subscription_id}/callback_url This endpoint updates the callback URL for a specific subscription. > NOTE: Consider all IDs as abstract strings, without making any assumptions about their format or relying on such assumptions. There is a non-zero probability that IDs may change in the future, and this should not result in any breaking changes. # Update chain IDs within subscription Source: https://developers.zerion.io/api-reference/subscriptions-to-transactions/update-chain-ids-within-subscription /openapi-v1.yaml patch /v1/tx-subscriptions/{subscription_id}/chain_ids This endpoint updates the list of chain IDs associated with a specific subscription. > NOTE: > - Consider all IDs as abstract strings, without making any assumptions about their format or relying on such assumptions. > - The chain IDs provided will replace the existing chain IDs associated with the subscription. # Get swap and bridge quotes Source: https://developers.zerion.io/api-reference/swap/get-swap-and-bridge-quotes /openapi-v1.yaml get /v1/swap/quotes/ Returns quotes from multiple liquidity sources for a same-chain swap or a cross-chain bridge between two fungible assets. Supports EVM chains and Solana, including EVM ↔ Solana bridges. Quotes are returned best-first: sorted in descending order by the fiat value of `output_amount_after_fees` (output amount minus network, protocol and bridge fees that are not already included in the rate). Quotes with the same score are tied-broken alphabetically by `liquidity_source.id`, so identical requests always return quotes in the same order. The `input` and `output` parameters are objects encoded with bracket notation in the URL — the request is sent as a flat query string. For example: ``` GET /v1/swap/quotes/?currency=usd&input[chain_id]=base&input[fungible_id]=0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2&input[amount]=0.001&output[fungible_id]=0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48&from=0xd8da6bf26964af9d7eed9e03e53415d37aa96045&to=0xd8da6bf26964af9d7eed9e03e53415d37aa96045 ``` # List fungibles available for bridging Source: https://developers.zerion.io/api-reference/swap/list-fungibles-available-for-bridging /openapi-v1.yaml get /v1/swap/fungibles/ Returns the list of tokens available for bridging between two chains. Use this to populate a token picker UI. Only relevant for cross-chain swaps, same-chain swaps don't require this step. # Get wallet set balance chart Source: https://developers.zerion.io/api-reference/wallet-sets/get-wallet-set-balance-chart /openapi-v1.yaml get /v1/wallet-sets/charts/{chart_period} This endpoint returns a portfolio balance chart for a wallet set. A wallet set is represented by an EVM address, a Solana address, or both. At least one address must be provided. This is over a specified time period, based on the provided start and end timestamps. Results can be filtered by blockchain and asset type, offering flexible and detailed visualizations of wallet set performance, similar to what you see in the Zerion interface. Note: We do not support historical protocol positions data. # Get wallet set fungible positions Source: https://developers.zerion.io/api-reference/wallet-sets/get-wallet-set-fungible-positions /openapi-v1.yaml get /v1/wallet-sets/positions/ This endpoint returns a list of wallet set positions. A wallet set is represented by an EVM address, a Solana address, or both. At least one address must be provided. This endpoint supports testnets. To get data for testnets use `X-Env` header. **Understanding Liquidity Pool Positions:** Liquidity pools (Uniswap, Curve, Balancer, etc.) return **multiple positions** - one for each token in the pool. Positions belonging to the same pool share the same `group_id` value in attributes. For example, a Uniswap V2 USDC/WETH pool returns two positions: - Position 1: WETH token, `group_id="820ee2f1ca8ccb716f6beb5e450908a028be890ec44aba87c739b416ef41e197"`, `fungible_info.symbol="WETH"` - Position 2: USDC token, `group_id="820ee2f1ca8ccb716f6beb5e450908a028be890ec44aba87c739b416ef41e197"`, `fungible_info.symbol="USDC"` To display all tokens in a liquidity pool together, group positions by their `group_id` attribute. **Temporary limitations for Solana addresses:** - Doesn't support protocol positions > NOTE: Don't forget to stop retries after some reasonable period of time. If the `200` status is not returned within 2 minutes it most probably means that some unexpected error occurred and the client should stop the polling. > NOTE: This endpoint supports a lot of filters, sorting and pagination parameters. Make sure that a request URL length is in a safe range for your platform. Usually, 2000 characters are the safe limit in virtually any combination of client and server software. > NOTE: Consider all IDs as abstract strings, without making any assumptions about their format or relying on such assumptions. There is a non-zero probability that IDs may change in the future, and this should not result in any breaking changes. # Get wallet set PnL Source: https://developers.zerion.io/api-reference/wallet-sets/get-wallet-set-pnl /openapi-v1.yaml get /v1/wallet-sets/pnl This endpoint returns the Profit and Loss (PnL) details of a wallet set. A wallet set is represented by an EVM address, a Solana address, or both. At least one address must be provided. This includes Unrealized PnL, Realized PnL, Net Invested amounts and filters for asset categories like Non Fungible Tokens (NFTs). It uses the FIFO (First In, First Out) standard for calculations, providing accurate insights into wallet set performance. Ideal for tracking and analyzing financial outcomes of wallet activity across multiple addresses. The very first request for a wallet set might result in a 503 which should be retried later. Wallet sets with over 1 million transactions are not supported. # Get wallet set portfolio Source: https://developers.zerion.io/api-reference/wallet-sets/get-wallet-set-portfolio /openapi-v1.yaml get /v1/wallet-sets/portfolio This endpoint returns a wallet set's portfolio overview. A wallet set is represented by an EVM address, a Solana address, or both. At least one address must be provided. **Temporary limitations for Solana addresses:** - Doesn't support protocol positions > NOTE: Don't forget to stop retries after some reasonable period of time. If the `200` status is not returned within 2 minutes it most probably means that some unexpected error occurred and the client should stop the polling. > NOTE: Consider all IDs as abstract strings, without making any assumptions about their format or relying on such assumptions. There is a non-zero probability that IDs may change in the future, and this should not result in any breaking changes. # Get wallet set transactions Source: https://developers.zerion.io/api-reference/wallet-sets/get-wallet-set-transactions /openapi-v1.yaml get /v1/wallet-sets/transactions/ This endpoint returns a list of transactions associated with the wallet set. A wallet set is represented by an EVM address, a Solana address, or both. At least one address must be provided. This endpoint supports testnets. To get data for testnets use `X-Env` header. **Temporary limitations for Solana addresses:** - Doesn't support NFT transactions > NOTE: This endpoint supports a lot of filters, sorting, and pagination parameters. Make sure that your request URL length is safe for your platform. Usually, 2000 characters are the safe limit in virtually any combination of client and server software. > NOTE: Consider all IDs as abstract strings, without making any assumptions about their format or relying on such assumptions. There is a non-zero probability that IDs may change in the future, and this should not result in any breaking changes. # Get wallet balance chart Source: https://developers.zerion.io/api-reference/wallets/get-wallet-balance-chart /openapi-v1.yaml get /v1/wallets/{address}/charts/{chart_period} This endpoint returns a portfolio balance chart for a wallet. This is over a specified time period, based on the provided start and end timestamps. Results can be filtered by blockchain and asset type, offering flexible and detailed visualizations of wallet performance, similar to what you see in the Zerion interface. Note: We do not support historical protocol positions data. # Get wallet fungible positions Source: https://developers.zerion.io/api-reference/wallets/get-wallet-fungible-positions /openapi-v1.yaml get /v1/wallets/{address}/positions/ This endpoint returns a list of wallet positions. This endpoint supports testnets. To get data for testnets use `X-Env` header. **Understanding Liquidity Pool Positions:** Liquidity pools (Uniswap, Curve, Balancer, etc.) return **multiple positions** - one for each token in the pool. Positions belonging to the same pool share the same `group_id` value in attributes. For example, a Uniswap V2 USDC/WETH pool returns two positions: - Position 1: WETH token, `group_id="820ee2f1ca8ccb716f6beb5e450908a028be890ec44aba87c739b416ef41e197"`, `fungible_info.symbol="WETH"` - Position 2: USDC token, `group_id="820ee2f1ca8ccb716f6beb5e450908a028be890ec44aba87c739b416ef41e197"`, `fungible_info.symbol="USDC"` To display all tokens in a liquidity pool together, group positions by their `group_id` attribute. **Temporary limitations for Solana addresses:** - Doesn't support protocol positions > NOTE: Don't forget to stop retries after some reasonable period of time. If the `200` status is not returned within 2 minutes it most probably means that some unexpected error occurred and the client should stop the polling. > NOTE: This endpoint supports a lot of filters, sorting and pagination parameters. Make sure that a request URL length is in a safe range for your platform. Usually, 2000 characters are the safe limit in virtually any combination of client and server software. > NOTE: Consider all IDs as abstract strings, without making any assumptions about their format or relying on such assumptions. There is a non-zero probability that IDs may change in the future, and this should not result in any breaking changes. # Get wallet NFT collections Source: https://developers.zerion.io/api-reference/wallets/get-wallet-nft-collections /openapi-v1.yaml get /v1/wallets/{address}/nft-collections/ This endpoint returns a list of the NFT collections held by a specific wallet. This endpoint supports testnets. To get data for testnets use `X-Env` header. If the wallet address has not been previously added, this endpoint may return a `202` status code. This indicates that the wallet's collections are not yet available, but will be in the near future. In this case, the client should periodically request this endpoint until a `200` status code is returned. > NOTE: It is important to stop retrying after a reasonable period of time. If a `200` status code is not returned within 2 minutes, it is likely that an unexpected error has occurred, and the client should stop polling. > NOTE: This endpoint provides support for filters, sorting. Ensure that the length of the request URL falls within a safe range for your platform. Typically, a length of 2000 characters is a safe limit for most combinations of client and server software. > NOTE: Consider all IDs as abstract strings, without making any assumptions about their format or relying on such assumptions. There is a non-zero probability that IDs may change in the future, and this should not result in any breaking changes. # Get wallet NFT portfolio Source: https://developers.zerion.io/api-reference/wallets/get-wallet-nft-portfolio /openapi-v1.yaml get /v1/wallets/{address}/nft-portfolio This endpoint returns the NFT portfolio overview of a web3 wallet. This endpoint supports testnets. To get data for testnets use `X-Env` header. If the address was not added before it is possible that this endpoint will return `202` status. It means that portfolio for the wallet is not prepared yet, but will be available soon. In that case the client have to request this endpoint periodically, while `200` status wasn't returned. > NOTE: Don't forget to stop retries after some reasonable period of time. If the `200` status is not returned within 2 minutes it most probably means that some unexpected error occurred and the client should stop the polling. # Get wallet NFT positions Source: https://developers.zerion.io/api-reference/wallets/get-wallet-nft-positions /openapi-v1.yaml get /v1/wallets/{address}/nft-positions/ This endpoint returns a list of the NFT positions held by a specific wallet. This endpoint supports testnets. To get data for testnets use `X-Env` header. If the wallet address has not been previously added, this endpoint may return a `202` status code. This indicates that the wallet's positions are not yet available, but will be in the near future. In this case, the client should periodically request this endpoint until a `200` status code is returned. > NOTE: It is important to stop retrying after a reasonable period of time. If a `200` status code is not returned within 2 minutes, it is likely that an unexpected error has occurred and the client should stop polling. > NOTE: This endpoint provides support for filters, sorting, and pagination parameters. Ensure that the length of the request URL falls within a safe range for your platform. Typically, a length of 2000 characters is a safe limit for most combinations of client and server software. > NOTE: Consider all IDs as abstract strings, without making any assumptions about their format or relying on such assumptions. There is a non-zero probability that IDs may change in the future, and this should not result in any breaking changes. # Get wallet PnL Source: https://developers.zerion.io/api-reference/wallets/get-wallet-pnl /openapi-v1.yaml get /v1/wallets/{address}/pnl This endpoint returns the Profit and Loss (PnL) details of a web3 wallet. This includes Unrealized PnL, Realized PnL, Net Invested amounts and filters for asset categories like Non Fungible Tokens (NFTs). It uses the FIFO (First In, First Out) standard for calculations, providing accurate insights into wallet performance. Ideal for tracking and analyzing financial outcomes of wallet activity. The very first request for a wallet might result in a 503 which should be retried later. Wallets with over 1 million transactions are not supported. # Get wallet portfolio Source: https://developers.zerion.io/api-reference/wallets/get-wallet-portfolio /openapi-v1.yaml get /v1/wallets/{address}/portfolio This endpoint returns the portfolio overview of a web3 wallet. **Temporary limitations for Solana addresses:** - Doesn't support protocol positions > NOTE: Don't forget to stop retries after some reasonable period of time. If the `200` status is not returned within 2 minutes it most probably means that some unexpected error occurred and the client should stop the polling. > NOTE: Consider all IDs as abstract strings, without making any assumptions about their format or relying on such assumptions. There is a non-zero probability that IDs may change in the future, and this should not result in any breaking changes. # Get wallet transactions Source: https://developers.zerion.io/api-reference/wallets/get-wallet-transactions /openapi-v1.yaml get /v1/wallets/{address}/transactions/ This endpoint returns a list of transactions associated with the wallet. This endpoint supports testnets. To get data for testnets use `X-Env` header. **Temporary limitations for Solana addresses:** - Doesn't support NFT transactions > NOTE: This endpoint supports a lot of filters, sorting, and pagination parameters. Make sure that your request URL length is safe for your platform. Usually, 2000 characters are the safe limit in virtually any combination of client and server software. > NOTE: Consider all IDs as abstract strings, without making any assumptions about their format or relying on such assumptions. There is a non-zero probability that IDs may change in the future, and this should not result in any breaking changes. # Authentication Source: https://developers.zerion.io/authentication How to authenticate with the Zerion API The Zerion API supports three ways to authenticate a request: | Method | Best for | How it works | | ------------------------------- | ------------------------------------- | ----------------------------------------------------------------------------------------------------- | | **API key** | Apps and services with steady traffic | HTTP Basic Auth with a key from the [Dashboard](https://dashboard.zerion.io). Subject to rate limits. | | **[x402](/build-with-ai/x402)** | AI agents and per-call workloads | Pay USDC on Base or Solana per request. No API key, no rate limits. | | **[MPP](/build-with-ai/mpp)** | AI agents and per-call workloads | Pay USDC on Tempo per request. No API key, no rate limits. | The rest of this page covers the API key flow. For pay-per-request flows, see the dedicated [x402](/build-with-ai/x402) and [MPP](/build-with-ai/mpp) pages. ## API key The Zerion API uses [HTTP Basic Authentication](https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication#basic_authentication_scheme). You can get your API key from the [Dashboard](https://dashboard.zerion.io). ### Try it from the docs Every API reference page has an interactive playground. Click **Try it**, paste your API key in the **Username** field, leave **Password** empty, and hit **Send** to make a live request. ### Using the API from your code When calling the API from code, append a colon to your API key (`your_api_key:`), Base64-encode it, and pass it in the `Authorization` header: ``` Authorization: Basic BASE64_ENCODED_KEY ``` Go to the [Dashboard](https://dashboard.zerion.io) Get Started section for ready-to-use code snippets with your API key pre-filled. ```bash cURL theme={null} # Transform your API key for Basic Auth API_KEY_TRANSFORMED=$(echo -n "YOUR_API_KEY:" | base64) # Make the request curl -X GET "https://api.zerion.io/v1/wallets/0x42b9df65b219b3dd36ff330a4dd8f327a6ada990/portfolio" \ -H "Authorization: Basic $API_KEY_TRANSFORMED" \ -H "accept: application/json" ``` ```javascript JavaScript theme={null} // Transform your API key for Basic Auth const apiKey = 'YOUR_API_KEY'; const apiKeyTransformed = btoa(apiKey + ':'); // Make the request const response = await fetch( 'https://api.zerion.io/v1/wallets/0x42b9df65b219b3dd36ff330a4dd8f327a6ada990/portfolio', { headers: { 'Authorization': `Basic ${apiKeyTransformed}`, 'accept': 'application/json' } } ); const data = await response.json(); console.log(data); ``` ```python Python theme={null} import requests import base64 # Transform your API key for Basic Auth api_key = 'YOUR_API_KEY' api_key_transformed = base64.b64encode(f'{api_key}:'.encode()).decode() # Make the request response = requests.get( 'https://api.zerion.io/v1/wallets/0x42b9df65b219b3dd36ff330a4dd8f327a6ada990/portfolio', headers={ 'Authorization': f'Basic {api_key_transformed}', 'accept': 'application/json' } ) data = response.json() print(data) ``` ```go Go theme={null} import ( "encoding/base64" "net/http" ) // Transform your API key for Basic Auth apiKey := "YOUR_API_KEY" apiKeyTransformed := base64.StdEncoding.EncodeToString([]byte(apiKey + ":")) // Make the request client := &http.Client{} req, _ := http.NewRequest("GET", "https://api.zerion.io/v1/wallets/0x42b9df65b219b3dd36ff330a4dd8f327a6ada990/portfolio", nil) req.Header.Set("Authorization", "Basic " + apiKeyTransformed) req.Header.Set("accept", "application/json") resp, _ := client.Do(req) defer resp.Body.Close() ``` ### Security best practices Never expose your API key in client-side code or public repositories. * Store your API key in environment variables * Make API requests from server-side code * Rotate your key immediately if it's ever compromised * Use separate keys for development and production ## Pay-per-request: x402 and MPP Both x402 and MPP let you call the Zerion API by paying a small USDC fee per request instead of presenting an API key. They're a better fit than API keys when: * You're building an AI agent or automated pipeline that shouldn't manage long-lived credentials * Traffic is bursty or unpredictable and you don't want to size a rate-limited plan * You want usage-based cost accounting at the request level The two protocols differ only in which chain they settle on: * **[x402](/build-with-ai/x402)** ([Coinbase's open protocol](https://github.com/coinbase/x402)) — settles in USDC on **Base** or **Solana**. Uses the `PAYMENT-SIGNATURE` request header. * **[MPP](/build-with-ai/mpp)** ([Machine Payments Protocol](https://mpp.dev)) — settles in USDC on **Tempo**. Uses the `Authorization: Payment` request header. Both cover the same set of endpoints as API-key auth and accept the same parameters. Pick whichever chain your wallet already holds USDC on. The [Zerion CLI](/build-with-ai/zerion-cli) supports both via `--x402` / `--mpp` flags. # MCP Source: https://developers.zerion.io/build-with-ai/mcp Connect your AI tools to the Zerion API docs via Model Context Protocol. The Zerion API docs are available as a Model Context Protocol (MCP) server. Once connected, your AI tool can search our full documentation and OpenAPI spec while generating code — no copy-pasting needed. ## Connect via MCP Run this in your terminal: ```bash theme={null} claude mcp add --transport http zerion-api https://developers.zerion.io/mcp ``` The Zerion docs will be available as a tool in all Claude Code sessions. Open the command palette (`Cmd+Shift+P`) → "MCP: Edit Config", then add: ```json theme={null} { "mcpServers": { "zerion-api": { "url": "https://developers.zerion.io/mcp" } } } ``` Create `.vscode/mcp.json` in your project: ```json theme={null} { "servers": { "zerion-api": { "type": "http", "url": "https://developers.zerion.io/mcp" } } } ``` 1. Go to Claude settings → **Connectors** 2. Select **Add custom connector** 3. Name: `Zerion API`, URL: `https://developers.zerion.io/mcp` 4. Use the attachments button (+) in any chat to access it ## What you can ask Once connected, you can ask your AI assistant things like: * *"How do I get a wallet's token positions on Ethereum?"* * *"Write a Python script that fetches transaction history and filters for trades"* * *"What filters are available on the positions endpoint?"* The AI will search the Zerion docs in real-time to give you accurate, up-to-date answers. ## Open in AI assistants You can also open any documentation page directly in an AI chat for quick questions: Paste any docs page URL into Claude for API questions and code generation. Use ChatGPT to explore endpoints and generate integration code. For the best experience, use the MCP integration instead of copy-pasting. It gives the AI access to the full docs and API spec, not just one page at a time. # MPP Payments Source: https://developers.zerion.io/build-with-ai/mpp Access the Zerion API per-request using USDC on Tempo — no API key required. MPP ([Machine Payments Protocol](https://mpp.dev)) is an open protocol for pay-per-request HTTP access. Instead of an API key, you pay a small amount of USDC on Tempo for each request — ideal for AI agents that need onchain data without managing subscriptions or key rotation. This is an alternative authorization method for the same Zerion API. Endpoints, JSON:API responses, query parameters, and filters all behave exactly as in the rest of the docs — only the way you prove access changes. Zerion also supports [x402](./x402), a sibling protocol that settles on Base or Solana. See [Authentication](/authentication) for an overview of all access methods. ## Quickstart with the Zerion CLI The easiest way to use MPP is with the [Zerion CLI](./zerion-cli), which handles the payment handshake, wallet signing, and retries automatically. Set an EVM private key for a wallet that holds USDC on Tempo, then make a request with `--mpp`: ```bash theme={null} export WALLET_PRIVATE_KEY="0x..." zerion-cli wallet portfolio 0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045 --mpp ``` Set `ZERION_MPP=true` to enable MPP globally for analytics commands instead of passing `--mpp` on every call. If you already use `WALLET_PRIVATE_KEY` for x402, the same key works for MPP — or set `TEMPO_PRIVATE_KEY` to use a different wallet for Tempo. ## Direct integration If you're not using the CLI, use one of the [official MPP SDKs](https://mpp.dev/sdk) (TypeScript, Python, Go, Rust) to handle payment construction and retries. You'll need a wallet with USDC on Tempo and its EVM private key. ## Example ```ts theme={null} import { privateKeyToAccount } from 'viem/accounts' import { Mppx, tempo } from 'mppx/client' Mppx.create({ methods: [tempo({ account: privateKeyToAccount(process.env.WALLET_PRIVATE_KEY) })], }) // Global fetch now handles 402 automatically const res = await fetch( 'https://api.zerion.io/v1/wallets/0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045/portfolio' ) const data = await res.json() ``` ## How it works ``` Client Zerion API | | | 1. GET /v1/wallets/... | | --------------------------> | | | | 2. 402 Payment Required | | <-------------------------- | | WWW-Authenticate: | | Payment | | | | 3. GET /v1/wallets/... | | Authorization: | | Payment | | --------------------------> | | | | 4. 200 OK | | Payment-Receipt: ... | | <-------------------------- | | | ``` 1. Client sends a request to an API endpoint 2. Server returns `402` with a `WWW-Authenticate: Payment` challenge describing where and how much to pay 3. Client signs a USDC transfer on Tempo and retries with an `Authorization: Payment` header 4. Zerion verifies the credential with the MPP facilitator and returns the response ## Rate limits None — pay per request, no per-second or monthly quota. ## Error handling * `402 Payment required` — no or invalid payment credential. Inspect the `WWW-Authenticate: Payment` response header for a fresh challenge and retry. * `402 MPP payment rejected` — the facilitator rejected the credential. The `detail` field contains the reason (e.g. insufficient funds, expired authorization). # Overview Source: https://developers.zerion.io/build-with-ai/overview Connect AI agents and assistants to onchain data through the Zerion API. Give your AI agents access to wallet portfolios, token data, transactions, and DeFi positions across all supported chains. Zerion provides multiple ways to integrate depending on your setup. Give AI agents access to onchain data via shell commands — no API integration needed. Let AI agents pay for API access per-request using stablecoins — no API keys needed. Connect AI tools like Claude Code, Cursor, and VS Code to the Zerion docs and OpenAPI spec via Model Context Protocol. # x402 Payments Source: https://developers.zerion.io/build-with-ai/x402 Access the Zerion API per-request using USDC on Base or Solana — no API key required. x402 is [Coinbase's open protocol](https://github.com/coinbase/x402) for pay-per-request HTTP access. Instead of an API key, you pay a small amount of USDC on Base or Solana for each request — ideal for AI agents that need onchain data without managing subscriptions or key rotation. This is an alternative authorization method for the same Zerion API. Endpoints, JSON:API responses, query parameters, and filters all behave exactly as in the rest of the docs — only the way you prove access changes. Zerion also supports [MPP](./mpp), a sibling protocol that settles on Tempo. See [Authentication](/authentication) for an overview of all access methods. ## Quickstart with the Zerion CLI The easiest way to use x402 is with the [Zerion CLI](./zerion-cli), which handles the payment handshake, wallet signing, and retries automatically. Set the private key of the wallet that holds USDC, then make a request with `--x402`: ```bash theme={null} export WALLET_PRIVATE_KEY="0x..." zerion-cli wallet portfolio 0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045 --x402 ``` ```bash theme={null} export SOLANA_PRIVATE_KEY="" export ZERION_X402_PREFER_SOLANA=true zerion-cli wallet portfolio 0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045 --x402 ``` Set `ZERION_X402=true` to enable x402 globally for analytics commands instead of passing `--x402` on every call. ## Direct integration If you're not using the CLI, use the [Coinbase x402 SDK](https://github.com/coinbase/x402) (Go, TypeScript, Python) to handle payment construction and retries. You'll need a wallet with USDC on Base or Solana and its private key. ## Example ```ts theme={null} import { wrapFetchWithPayment, x402Client } from '@x402/fetch' import { registerExactEvmScheme } from '@x402/evm/exact/client' import { privateKeyToAccount } from 'viem/accounts' const client = new x402Client() registerExactEvmScheme(client, { signer: privateKeyToAccount(process.env.WALLET_PRIVATE_KEY), }) const fetchWithPayment = wrapFetchWithPayment(fetch, client) const res = await fetchWithPayment( 'https://api.zerion.io/v1/wallets/0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045/portfolio' ) const data = await res.json() ``` ## How it works ``` Client Zerion API | | | 1. GET /v1/wallets/... | | --------------------------> | | | | 2. 402 Payment Required | | <-------------------------- | | PAYMENT-REQUIRED: | | | | | | 3. GET /v1/wallets/... | | PAYMENT-SIGNATURE: | | | | --------------------------> | | | | 4. 200 OK | | <-------------------------- | | | ``` 1. Client sends a request to an API endpoint 2. Server returns `402` with a `PAYMENT-REQUIRED` header describing where and how much to pay 3. Client signs a USDC transfer and retries with a `PAYMENT-SIGNATURE` header 4. Zerion settles the payment via the Coinbase Developer Platform and returns the response ## Rate limits None — pay per request, no per-second or monthly quota. ## Error handling * `402 Payment required` — no or invalid payment signature. Inspect the `PAYMENT-REQUIRED` response header for a fresh challenge and retry. * `402 x402 payment rejected` — the facilitator rejected the signature. The `detail` field contains the reason. * `402 x402 payment settlement failed` — the signature was valid but on-chain settlement failed. See the [Coinbase x402 troubleshooting docs](https://docs.cdp.coinbase.com/x402/support/troubleshooting#common-errors) for more. # Skill + CLI Source: https://developers.zerion.io/build-with-ai/zerion-cli CLI for Zerion Wallet — analyze wallets, sign, swap, and bridge on-chain with agent-managed wallets across EVM chains and Solana, all from the command line. Plus agent skills that ship across every major AI coding agent. The Zerion CLI is an open-source tool that wraps the Zerion API and a local encrypted wallet vault. The same binary powers both humans and AI agents — any agent that can run shell commands can analyze wallets, sign messages, and execute swaps without writing API integration code. Wallet management is built on the [Open Wallet Standard](https://github.com/open-wallet-standard/core). Six agent skills ship alongside the CLI for AI coding agents (Claude Code, Cursor, Windsurf, Codex, Gemini, OpenCode, and any [agentskills.io](https://agentskills.io) host). **Repository:** [github.com/zeriontech/zerion-ai](https://github.com/zeriontech/zerion-ai) — CLI and skills ship from the same repo. **Alpha Preview** — The CLI is under active development. Commands, flags, and output formats may change between releases. Don't depend on current behavior in production workflows. ## Installation One-shot setup — installs the CLI globally, configures your API key, and adds skills across all detected coding agents: ```bash theme={null} npx -y zerion-cli init -y --browser ``` * `-y` runs setup non-interactively * `--browser` opens [dashboard.zerion.io](https://dashboard.zerion.io) so you can grab an API key and paste it back * Skills install globally to every detected AI coding agent Or install the CLI binary on its own: ```bash theme={null} npm install -g zerion-cli ``` Requires Node.js 20 or later. ## Authentication Three options. The CLI auto-detects which is active. ### API key (recommended) Get a free key at [dashboard.zerion.io](https://dashboard.zerion.io). Keys begin with `zk_`. ```bash theme={null} export ZERION_API_KEY="zk_..." ``` Or persist it via config: ```bash theme={null} zerion config set apiKey zk_... ``` Required for analysis and trading. Analysis can also use x402 / MPP pay-per-call. ### x402 pay-per-call No API key needed. Pays \$0.01 USDC per request via the [x402 protocol](https://www.x402.org/). Supports EVM (Base) and Solana. ```bash theme={null} export WALLET_PRIVATE_KEY="0x..." # EVM (Base) — 0x-prefixed hex export WALLET_PRIVATE_KEY="5C1y..." # Solana — base58 keypair zerion analyze 0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045 --x402 ``` Enable globally: ```bash theme={null} export ZERION_X402=true ``` Both chains simultaneously: ```bash theme={null} export EVM_PRIVATE_KEY="0x..." export SOLANA_PRIVATE_KEY="5C1y..." export ZERION_X402_PREFER_SOLANA=true ``` Pay-per-call applies to analytics commands only (`portfolio`, `positions`, `history`, `pnl`, `analyze`). Trading commands always use an API key. ### MPP pay-per-call No API key needed. Pays \$0.01 USDC per request via the [MPP protocol](https://mpp.dev) on [Tempo](https://tempo.xyz). EVM only. ```bash theme={null} export WALLET_PRIVATE_KEY="0x..." # or a dedicated key: export TEMPO_PRIVATE_KEY="0x..." zerion portfolio 0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045 --mpp ``` Enable globally: ```bash theme={null} export ZERION_MPP=true ``` ## Skills The CLI ships with six agent skills that install into AI coding agents. Each skill is self-contained — your agent loads the relevant one based on the user's intent. | Skill | What it does | | ------------------------- | ---------------------------------------------------------------------------------------------- | | `zerion` | Umbrella entry — install, authentication, routing to capability skills, chains reference | | `zerion-analyze` | Read-only wallet insights: portfolio, positions, history, PnL, watchlist (supports x402 / MPP) | | `zerion-trading` | Swap, bridge, send tokens (on-chain actions; needs API key + agent token) | | `zerion-sign` | Off-chain signing — sign-message (EIP-191 / raw), sign-typed-data (EIP-712) | | `zerion-wallet` | Wallet management — create, import, list, fund, backup, delete, sync | | `zerion-agent-management` | Agent tokens + policies (the autonomous-trading primitives) | Install or reinstall skills: ```bash theme={null} zerion setup skills # all detected agents (default: global) zerion setup skills --agent claude-code # scope to one agent zerion setup skills -g # force global install ``` Per-host plugin installs (alternative to `setup skills`): ```bash theme={null} # Claude Code /plugin marketplace add zeriontech/zerion-ai /plugin install zerion-agent@zerion # OpenAI Codex CLI codex plugin marketplace add zeriontech/zerion-ai # then run /plugins, choose the zerion marketplace, install zerion-agent # Cursor npx skills add zeriontech/zerion-ai --agent cursor # OpenCode npx skills add zeriontech/zerion-ai --agent opencode # Gemini CLI gemini extensions install https://github.com/zeriontech/zerion-ai # Any agentskills.io host npx skills add zeriontech/zerion-ai ``` ## Manual setup, agent execution The CLI splits cleanly into two surfaces, by design. * **Wallet management and agent token setup are manual.** `wallet create`, `import`, `backup`, and `delete` prompt for a passphrase. `wallet sync` emits a QR code you scan with the Zerion app. `agent create-token` mints a scoped trading credential bound to a specific wallet, and `agent create-policy` attaches the rules it must obey — allowed chains, expiry, transfer/approval gates, contract allowlists. No key material moves and no spending credential widens without you in the loop. * **Analysis, signing, trading, and discovery are for agents.** `analyze`, `portfolio`, `positions`, `history`, `pnl`, `sign-message`, `sign-typed-data`, `swap`, `bridge`, `send`, `search`, `chains`, and read-only listings emit JSON to stdout, structured errors to stderr, and skip confirmation dialogs. Once an agent token is configured, signing and trading fire immediately. You stage by hand once — create or import a wallet, set a passphrase, mint an agent token, attach a policy — then hand the agent token to an automation that can only do what the policy allows. Treat agent tokens like API keys with spending power. ## Commands Every command supports `--help` for full flag documentation. Run `zerion --help` for the top-level command list. ### Analyze Read-only wallet insights. Supports `--x402` and `--mpp` for pay-per-call. ```bash theme={null} # Full analysis — portfolio, positions, transactions, PnL in parallel zerion analyze vitalik.eth # Targeted reads zerion portfolio 0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045 zerion positions vitalik.eth --defi # grouped by protocol, loans netted zerion positions vitalik.eth --positions defi # flat list of DeFi positions zerion history vitalik.eth --limit 10 --chain ethereum zerion pnl vitalik.eth ``` #### Analyze Options | Command | Description | | --------------------------------- | -------------------------------------------------------------------------------------------------- | | `zerion analyze ` | Full analysis — portfolio, positions, transactions, PnL in parallel | | `zerion portfolio ` | Portfolio value and top positions | | `zerion positions ` | Token + DeFi positions (`--positions all\|simple\|defi`, or `--defi` for grouped-by-protocol view) | | `zerion history ` | Transaction history (`--limit`, `--chain`) | | `zerion pnl ` | Profit & loss (realized, unrealized, fees) | | `zerion search ` | Search tokens by name or symbol | | `zerion chains` | List supported chains | ### Trade Requires an API key plus an agent token for unattended use. Chain is the first positional argument. ```bash theme={null} # Same-chain swap — zerion swap zerion swap base 1 USDC ETH zerion swap ethereum 0.1 ETH USDC zerion swap solana 0.1 SOL USDC zerion swap monad 1 USDC MON # List tokens available for swap on a chain zerion swap tokens base zerion swap tokens solana # Bridge — zerion bridge # Default: list all provider offers (no transaction signed) zerion bridge base USDC 5 arbitrum USDC # Execute the highest-output offer zerion bridge base USDC 5 arbitrum USDC --cheapest # Execute the fastest offer zerion bridge base USDC 5 arbitrum USDC --fast # Bridge + swap on destination zerion bridge base USDC 5 arbitrum ETH --cheapest # Cross-format bridge (EVM ↔ Solana) — destination wallet required if source is EVM-only or Solana-only zerion bridge ethereum USDC 50 solana USDC --to-wallet sol-bot --cheapest zerion bridge ethereum USDC 50 solana USDC --to-address 8xLdox... --cheapest # Send — chain auto-detected from recipient format zerion send USDC 50 --to 0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045 --chain base zerion send SOL 0.1 --to 2Nsnn... ``` #### Trade Options | Command | Description | | ------------------------------------------------------------------------ | -------------------------------------------------------------------------- | | `zerion swap ` | Same-chain swap | | `zerion swap tokens [chain]` | List tokens available for swap | | `zerion bridge ` | List all bridge providers (multi-offer mode; no execute) | | `zerion bridge ... --cheapest` | Execute the highest-output offer | | `zerion bridge ... --fast` | Execute the lowest-time offer (falls back to `--cheapest` if no time data) | | `zerion bridge ... --to-wallet ` | Destination wallet for cross-format bridges (Solana ↔ EVM) | | `zerion bridge ... --to-address ` | Raw destination address (must match destination-chain format) | | `zerion send --to
` | Send tokens (chain auto-inferred from address format) | | `zerion send SOL --to ` | Send native SOL on Solana | `--fast` and `--cheapest` are mutually exclusive. When used, the strategy flag must come last on the command line so flag parsing doesn't consume the next positional as its value. Single-offer routes auto-execute even without a strategy flag. ### Sign Off-chain signatures (EIP-191, EIP-712, Solana raw) — no broadcast. Requires an agent token. ```bash theme={null} # EIP-191 (EVM) or raw (Solana) zerion sign-message "Login to dApp" --chain ethereum # Hex bytes zerion sign-message 0xdeadbeef --encoding hex --chain ethereum # EIP-712 typed data zerion sign-typed-data --data "$(cat permit.json)" zerion sign-typed-data --file permit.json cat permit.json | zerion sign-typed-data ``` #### Sign Options | Command | Description | | ----------------------------------------------- | ------------------------------------------ | | `zerion sign-message --chain ` | Sign EIP-191 (EVM) or raw (Solana) message | | `zerion sign-message --encoding hex` | Treat message as hex bytes | | `zerion sign-typed-data --data ''` | Sign EIP-712 typed data (EVM only) | | `zerion sign-typed-data --file ` | Read EIP-712 typed data from file | ### Wallet Encrypted local wallets. EVM + Solana supported. Passphrase required for destructive ops. ```bash theme={null} zerion wallet create --name trading-bot zerion wallet import --name old-wallet --evm-key zerion wallet list zerion wallet fund --wallet trading-bot zerion wallet backup --wallet trading-bot zerion wallet sync --wallet trading-bot ``` #### Wallet Options | Command | Description | | ----------------------------------------------- | -------------------------------------------- | | `zerion wallet create --name ` | Create encrypted wallet (EVM + Solana) | | `zerion wallet import --name --evm-key` | Import from EVM private key (interactive) | | `zerion wallet import --name --sol-key` | Import from Solana private key (interactive) | | `zerion wallet import --name --mnemonic` | Import from seed phrase (all chains) | | `zerion wallet list` | List all wallets | | `zerion wallet fund` | Show deposit addresses for funding | | `zerion wallet backup --wallet ` | Export recovery phrase | | `zerion wallet delete ` | Permanently delete a wallet | | `zerion wallet sync --wallet ` | Sync wallet to Zerion app via QR code | | `zerion wallet sync --all` | Sync all wallets | ### Agent Scoped API tokens for unattended trading. Tokens auto-save to config and are required for `swap`, `bridge`, `send`. ```bash theme={null} # Create a tight policy first zerion agent create-policy --name safe-base \ --chains base \ --expires 24h \ --deny-transfers # Mint a token bound to that policy zerion agent create-token --name dca-bot \ --wallet trading-bot \ --policy safe-base ``` #### Agent Token Options | Command | Description | | ---------------------------------------------------------- | ----------------------------- | | `zerion agent create-token --name --wallet ` | Create scoped token | | `zerion agent list-tokens` | List active agent tokens | | `zerion agent use-token --wallet ` | Switch active token by wallet | | `zerion agent revoke-token --name ` | Revoke a token | #### Agent Policy Options | Command | Description | | -------------------------------------------- | ------------------------------------ | | `zerion agent create-policy --name ` | Create security policy (flags below) | | `zerion agent list-policies` | List all policies | | `zerion agent show-policy ` | Show policy details | | `zerion agent delete-policy ` | Delete a policy | #### Policy Flags | Flag | Description | | ------------------------- | --------------------------------------------- | | `--chains ` | Restrict to specific chains (comma-separated) | | `--expires ` | Token expiry (e.g. `24h`, `7d`) | | `--deny-transfers` | Block raw ETH/native transfers | | `--deny-approvals` | Block ERC-20 approval calls | | `--allowlist ` | Only allow listed contract/wallet addresses | ### Watch Track wallets by name without exposing addresses in commands. ```bash theme={null} zerion watch 0xFe89Cc7Abb2C4183683Ab71653c4cCd1b9cC194e --name ens-dao zerion analyze ens-dao ``` #### Watch Options | Command | Description | | --------------------------------------- | ----------------------- | | `zerion watch
--name