Integrating API3 into Your Smart Contracts
Your decentralized application (dApp) often needs real-world data for price feeds, weather reports, sports scores, or any external API endpoint. Oracles bridge the on-chain/off-chain divide. API3 offers a first-party oracle network through Airnode—a fully serverless, permissionless oracle node that allows smart contracts to consume data directly from API providers.
Why Choose API3
- First-party data: API providers operate their own oracles, eliminating intermediaries.
- Serverless: Airnode runs without you provisioning servers.
- Permissionless: Anyone can deploy an Airnode or integrate an existing one.
- Secure: QRNG (Quantum Random Number Generation) and rigorous audits.
Core Components
| Component | Description |
|---|---|
| Airnode | API3’s serverless oracle adapter. |
| API3 DAO | Governance of the API3 network. |
| Requests Manager | Smart contract adaptor to handle requests responses. |
1. Understanding the Architecture
At a high level, an Airnode listens for on-chain requests, calls the external API, and returns the result on-chain. There are four phases:
- Deployment: Deploy the Airnode (as a serverless container) and configure your
config.json. - Authorization: Define which requester contracts can query your Airnode.
- Request: The dApp’s smart contract emits a request event.
- Fulfillment: Airnode listens, accesses the API, and calls back your contract with data or error.
2. Setting Up Your Airnode
2.1 Prerequisites
- Node.js (v14 )
- Docker
- Access to an RPC endpoint (Infura, Alchemy, etc.)
2.2 Install the CLI
npm install -g @api3/airnode-cli
2.3 Initialize a Project
airnode init --name my-airnode cd my-airnode
This generates config.json, secrets.env, and a template requester contract.
3. Deploying Your Airnode
- Configure
secrets.envwith your API key. - Define providers and endpoints in
config.json. - Run:
airnode deploy --stage testnet
After deployment, note down the AirnodeRrpAddress and endpointId from the logs.
4. Crafting Your Smart Contract
Use the Airnode RRP Package to simplify requests:
pragma solidity ^0.8.0
import @api3/airnode-protocol/contracts/rrp/interfaces/IAirnodeRrpV0.sol
contract PriceConsumer {
IAirnodeRrpV0 public airnodeRrp
address public sponsorWallet
bytes32 public endpointId // Set after deployment
uint256 public price
constructor(address _rrp, address _sponsor, bytes32 _endpointId) {
airnodeRrp = IAirnodeRrpV0(_rrp)
sponsorWallet = _sponsor
endpointId = _endpointId
}
function requestPrice() external {
bytes32 requestId = airnodeRrp.makeRequest(
airnode, // Airnode address
endpointId, // Endpoint ID
address(this), // Sponsor
sponsorWallet, // Sponsor wallet
address(this), // Fulfill address
this.fulfillPrice.selector,
abi.encode(path, data,price) // Adapter parameters
)
}
function fulfillPrice(bytes32 requestId, bytes calldata data) external {
require(msg.sender == address(airnodeRrp), Only RRP can fulfill)
price = abi.decode(data, (uint256))
}
}
5. Testing Deployment
- Use Hardhat or Truffle for local tests. Set
HARDHAT_NETWORKto your provider. - Mock the AirnodeRrp interface for unit tests.
- Deploy to a testnet and verify on a block explorer (Etherscan, Polygonscan).
6. Security Best Practices
- Validate responses: Always validate data ranges and types.
- Access control: Restrict who can call
requestPrice. - Sponsor wallets: Monitor balance to ensure uninterrupted operations.
- Audit: Use static analysis (Slither, MythX) and conduct third-party audits.
7. Advanced Patterns
7.1 Multi-Endpoint Requests
Batch multiple endpoints to reduce gas:
// Example pseudocode: airnodeRrp.makeRequests(airnode, [endpointA, endpointB], ...)
7.2 Dynamic Parameters
Allow user-provided query parameters:
abi.encode(symbol, userSymbol, interval, 1d)
8. Gas Consumption Estimates
| Operation | Approx. Gas |
|---|---|
| makeRequest | 80,000 |
| fulfill (callback) | 60,000 |
Leave a Reply