{"openapi":"3.1.0","info":{"title":"dRPC over Airnode","version":"1.0.0","description":"dRPC is a decentralised RPC network over 100+ chains. This Airnode wraps both halves worth attesting: raw JSON-RPC reads of chain state, and the indexed Data API for wallets, tokens, NFTs and DeFi.\n\nEvery response carries an EIP-191 signature from the Airnode that served it, so the data can be attributed back to its source rather than trusted on reputation."},"servers":[{"url":"http://airnode-drpc.fly.dev"}],"paths":{"/":{"get":{"operationId":"getDocumentation","summary":"This document.","description":"Describes the operations this Airnode serves and how to verify what it returns. Free.","responses":{"200":{"description":"An OpenAPI document describing this Airnode.","content":{"application/json":{"schema":{"type":"object"}}}}}},"post":{"operationId":"performRequest","summary":"Perform an operation and attest to the response.","requestBody":{"required":true,"content":{"application/json":{"schema":{"oneOf":[{"title":"jsonRpc","type":"object","required":["operation","parameters"],"additionalProperties":false,"properties":{"operation":{"const":"jsonRpc","description":"Read chain state with a JSON-RPC call against any chain dRPC serves.","x-airnode-returns":{"jsonrpc":"string","id":"null","result":"unknown"}},"parameters":{"type":"object","additionalProperties":false,"required":["network","method"],"properties":{"network":{"description":"The chain, as a dRPC network slug. Not an EIP-155 number: 1 and 0x1 are refused, and supportedChains returns id_numeric to resolve one. supportedChains is a guide rather than an index, since it lists what the Data API indexes and neither set contains the other; https://drpc.org/chainlist is authoritative.","type":"string","examples":["ethereum","base","solana","bitcoin"]},"method":{"type":"string","description":"The JSON-RPC method.","examples":["eth_blockNumber","eth_getBalance","eth_call"]},"params":{"type":"array","description":"The method's positional arguments, in the order it defines them. Omit it for a method that takes none, such as eth_blockNumber."}}}}},{"title":"supportedChains","type":"object","required":["operation","parameters"],"additionalProperties":false,"properties":{"operation":{"const":"supportedChains","description":"Every chain the Data API indexes, with its id and numeric chain ID.","x-airnode-returns":{"next_page_token":"string","data":"object"}},"parameters":{"type":"object","additionalProperties":false,"required":["limit"],"properties":{"limit":{"description":"How many chains to return. Required: dRPC rejects the call without it. 1000 returns every chain in one page.","type":"integer"},"page_token":{"description":"The next_page_token of a previous response, to continue from where it stopped. Omit it for the first page.","type":"string"}}}}},{"title":"chainInfo","type":"object","required":["operation","parameters"],"additionalProperties":false,"properties":{"operation":{"const":"chainInfo","description":"One chain by id, with its numeric chain ID.","x-airnode-returns":{"data":"object"}},"parameters":{"type":"object","additionalProperties":false,"required":["chain_id"],"properties":{"chain_id":{"description":"The chain id to look up.","type":"string","examples":["ethereum"]}}}}},{"title":"walletBalances","type":"object","required":["operation","parameters"],"additionalProperties":false,"properties":{"operation":{"const":"walletBalances","description":"What one wallet holds across every chain dRPC indexes, priced in US dollars.","x-airnode-returns":{"data":"object"}},"parameters":{"type":"object","additionalProperties":false,"required":["address"],"properties":{"address":{"description":"The wallet to value, as a hex address.","type":"string"}}}}},{"title":"chainWalletBalances","type":"object","required":["operation","parameters"],"additionalProperties":false,"properties":{"operation":{"const":"chainWalletBalances","description":"What one wallet holds on one named EVM chain, priced in US dollars.","x-airnode-returns":{"data":"object"}},"parameters":{"type":"object","additionalProperties":false,"required":["chain","address"],"properties":{"chain":{"description":"The chain to value the wallet on. It has to be one dRPC both routes and indexes for EVM portfolios.","type":"string"},"address":{"description":"The wallet to value, as a hex address.","type":"string"}}}}},{"title":"nonEvmWalletBalances","type":"object","required":["operation","parameters"],"additionalProperties":false,"properties":{"operation":{"const":"nonEvmWalletBalances","description":"What one wallet holds on a non-EVM chain, priced in US dollars.","x-airnode-returns":{"data":"object"}},"parameters":{"type":"object","additionalProperties":false,"required":["chain","address"],"properties":{"chain":{"description":"The non-EVM chain to value the wallet on. Only solana, bitcoin and tron are indexed this way.","type":"string"},"address":{"description":"The wallet to ask about, as an address.","type":"string"}}}}},{"title":"netWorthHistory","type":"object","required":["operation","parameters"],"additionalProperties":false,"properties":{"operation":{"const":"netWorthHistory","description":"How one wallet's token net worth moved over time, across every indexed chain.","x-airnode-returns":{"data":"object"}},"parameters":{"type":"object","additionalProperties":false,"required":["address"],"properties":{"address":{"description":"The wallet to ask about, as an address.","type":"string"}}}}},{"title":"chainNetWorthHistory","type":"object","required":["operation","parameters"],"additionalProperties":false,"properties":{"operation":{"const":"chainNetWorthHistory","description":"How one wallet's token net worth moved over time on one chain.","x-airnode-returns":{"data":"object"}},"parameters":{"type":"object","additionalProperties":false,"required":["chain","address"],"properties":{"chain":{"description":"The chain to ask about, as a dRPC chain id from supportedChains.","type":"string"},"address":{"description":"The wallet to ask about, as an address.","type":"string"}}}}},{"title":"transactionHistory","type":"object","required":["operation","parameters"],"additionalProperties":false,"properties":{"operation":{"const":"transactionHistory","description":"One wallet's transaction history, decoded, across chains.","x-airnode-returns":{"next_page_token":"string","data":"array"}},"parameters":{"type":"object","additionalProperties":false,"required":["address"],"properties":{"address":{"description":"The wallet whose history to return, as a hex address.","type":"string"},"chain_ids":{"description":"Restrict to these chains, as a comma-separated list of the ids supportedChains returns. Every chain by default.","type":"string"},"limit":{"description":"How many transactions to return.","type":"integer","default":100},"page_token":{"description":"The next_page_token of a previous response, to continue from where it stopped.","type":"string"}}}}},{"title":"supportedTokens","type":"object","required":["operation","parameters"],"additionalProperties":false,"properties":{"operation":{"const":"supportedTokens","description":"Every token the Data API prices and indexes.","x-airnode-returns":{"next_page_token":"string","data":"object"}},"parameters":{"type":"object","additionalProperties":false,"required":["limit"],"properties":{"limit":{"description":"How many to return, and dRPC pages the rest behind a token. Required: dRPC has no default for it and answers 422 without it, so it is required here too rather than left optional for a caller to discover the hard way.","type":"integer"},"page_token":{"description":"The next_page_token of a previous response. Omit it for the first page.","type":"string"}}}}},{"title":"tokenInfo","type":"object","required":["operation","parameters"],"additionalProperties":false,"properties":{"operation":{"const":"tokenInfo","description":"One token: its symbol, name and per-chain contract addresses.","x-airnode-returns":{"data":"object"}},"parameters":{"type":"object","additionalProperties":false,"required":["token_id"],"properties":{"token_id":{"description":"The token id to look up, or a contract address.","type":"string","examples":["eth"]}}}}},{"title":"priceSymbols","type":"object","required":["operation","parameters"],"additionalProperties":false,"properties":{"operation":{"const":"priceSymbols","description":"Every ticker symbol historicalPrices will price.","x-airnode-returns":{"data":"array"}},"parameters":{"type":"object","additionalProperties":false,"required":[],"properties":{}}}},{"title":"historicalPrices","type":"object","required":["operation","parameters"],"additionalProperties":false,"properties":{"operation":{"const":"historicalPrices","description":"What a token was worth at a given moment, for one or more symbols and times.","x-airnode-returns":{"data":"object"}},"parameters":{"type":"object","additionalProperties":false,"required":["symbols","timestamps"],"properties":{"symbols":{"type":"array","description":"Ticker symbols to price, as priceSymbols lists them.","examples":[["BTC"]]},"timestamps":{"type":"array","description":"The moments to price them at, as Unix milliseconds."}}}}},{"title":"walletNfts","type":"object","required":["operation","parameters"],"additionalProperties":false,"properties":{"operation":{"const":"walletNfts","description":"Every NFT one wallet holds, across every indexed chain.","x-airnode-returns":{"next_page_token":"string","data":"array"}},"parameters":{"type":"object","additionalProperties":false,"required":["address","limit"],"properties":{"address":{"description":"The wallet to ask about, as an address.","type":"string"},"limit":{"description":"How many to return, and dRPC pages the rest behind a token. Required: dRPC has no default for it and answers 422 without it, so it is required here too rather than left optional for a caller to discover the hard way.","type":"integer"},"page_token":{"description":"The next_page_token of a previous response. Omit it for the first page.","type":"string"}}}}},{"title":"nonEvmWalletNfts","type":"object","required":["operation","parameters"],"additionalProperties":false,"properties":{"operation":{"const":"nonEvmWalletNfts","description":"Every NFT one wallet holds on a non-EVM chain.","x-airnode-returns":{"data":"array"}},"parameters":{"type":"object","additionalProperties":false,"required":["chain","address"],"properties":{"chain":{"description":"The non-EVM chain to list NFTs on. Only solana is indexed this way.","type":"string"},"address":{"description":"The wallet to ask about, as an address.","type":"string"}}}}},{"title":"nftCollections","type":"object","required":["operation","parameters"],"additionalProperties":false,"properties":{"operation":{"const":"nftCollections","description":"The NFT collections one wallet holds on one chain.","x-airnode-returns":{"data":"array"}},"parameters":{"type":"object","additionalProperties":false,"required":["chain","address"],"properties":{"chain":{"description":"The chain to ask about, as a dRPC chain id from supportedChains.","type":"string"},"address":{"description":"The wallet to ask about, as an address.","type":"string"}}}}},{"title":"nftMetadata","type":"object","required":["operation","parameters"],"additionalProperties":false,"properties":{"operation":{"const":"nftMetadata","description":"One NFT: its metadata, media and collection.","x-airnode-returns":{"data":"object"}},"parameters":{"type":"object","additionalProperties":false,"required":["chain","contract","nft_id"],"properties":{"chain":{"description":"The chain to ask about, as a dRPC chain id from supportedChains.","type":"string"},"contract":{"description":"The collection's contract address.","type":"string"},"nft_id":{"description":"The token id within that contract.","type":"string"}}}}},{"title":"ledgerGrow","type":"object","required":["operation","parameters"],"additionalProperties":false,"properties":{"operation":{"const":"ledgerGrow","description":"Current yield on a DeFi protocol's deposit products.","x-airnode-returns":{"network":"string","deposit_token":"string","interest":"object"}},"parameters":{"type":"object","additionalProperties":false,"required":["protocol"],"properties":{"protocol":{"description":"The protocol to read. Only aave_v3 and lido are covered.","type":"string"}}}}},{"title":"ledgerStakes","type":"object","required":["operation","parameters"],"additionalProperties":false,"properties":{"operation":{"const":"ledgerStakes","description":"What given addresses have staked in a DeFi protocol, and what it earns.","x-airnode-returns":{"id":"object","stake":"object"}},"parameters":{"type":"object","additionalProperties":false,"required":["protocol","stake_addresses"],"properties":{"protocol":{"description":"The protocol to read. Only aave_v3 and lido are covered.","type":"string"},"stake_addresses":{"description":"The addresses whose stakes to return, comma-separated. Required: dRPC rejects the call without it.","type":"string"}}}}},{"title":"aprHistory","type":"object","required":["operation","parameters"],"additionalProperties":false,"properties":{"operation":{"const":"aprHistory","description":"How a DeFi pool's APR moved over time.","x-airnode-returns":{"data":"array"}},"parameters":{"type":"object","additionalProperties":false,"required":["requests"],"properties":{"requests":{"type":"array","description":"One entry per pool to read, each an object with chain and protocol required, and pool_id and asset optional. Only aave_v3 and lido are covered."}}}}}]}}}},"responses":{"200":{"description":"The upstream response and the attestation over it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Attestation"}}}},"400":{"description":"The operation exists but the parameters are missing, unknown or malformed."},"404":{"description":"No such operation."},"502":{"description":"The upstream API could not be reached or refused the request."}}}}},"components":{"schemas":{"Attestation":{"type":"object","required":["airnode","requestHash","timestamp","data","signature"],"properties":{"airnode":{"type":"string","description":"The address whose signature attests to this response."},"requestHash":{"type":"string","description":"Identifies the request this response answers."},"timestamp":{"type":"string","description":"Unix seconds at which the response was signed."},"data":{"description":"The upstream response body: the JSON value when it parses as JSON, the text as received otherwise."},"signature":{"type":"string","description":"The attestation itself."}}}}},"x-airnode":{"address":"0x511AcE8648D2f64260d50D036F8f8ce622d92137","version":"0.1.0","attestation":{"scheme":"eip191-secp256k1","digest":"keccak256(abi.encodePacked(bytes32 requestHash, uint256 timestamp, bytes dataBytes))","dataBytes":"UTF-8 of data, or of its compact JSON when data is not a string","requestHash":"keccak256(utf8(JSON.stringify([operation, parameterEntriesSortedByName]))), where an object value is itself entries sorted by name, at any depth, and an array keeps its order","verify":"Recover the signer of the signature over the digest and check it equals the address above."}}}