This guide will help developers who want to integrate their smart contracts with UDF. It uses Hardhat for contract compilation, although similar methods apply with other frameworks.
Step #1: Initialize new project and install dependencies
In the first step, we are establising a basic solidity development setup.
Step #2: Write a contract that accepts UDF updates for verification
To create a new contract that utilizes the PullOracle functionality for verifying updates, follow these steps:
Create a file named PullOracleConsumer.sol.
Copy the IPullOracle interface into this file, or create a separate .sol file for the interface and import it into your main contract using an import statement.
interface IPullOracle {structLatestUpdate {/// @notice The price for asset from latest updateuint256 latestPrice;/// @notice The timestamp of latest updateuint256 latestTimestamp; }/// @dev Represents a digital signaturestructSignature {bytes32 r; // The first 32 bytes of the signaturebytes32 s; // The second 32 bytes of the signatureuint8 v; // The recovery byte }/// @notice mapping of dataKey to the latest updatefunctionlatestUpdate(bytes32 dataKey) externalpurereturns (LatestUpdatememory);// @notice Verifies that the update was emitted on EOB. // @dev It does so by checking following properties:// * Calculated merkle root of Update + merkle proofs, and ensure that it is// equal to the provided merkle root// * Validate the signatures of EOB agents on the Merkle root to ensure// merkle root integrity. The consensus check passes only if the number of valid// unique signatures meets or exceeds the protocol's consensus rate threshold.functiongetLastPrice(bytes32 merkleRoot,bytes32[] calldata merkleProof,Signature[] calldata signatures,bytes32 dataKey,uint256 price,uint256 timestamp ) externalreturns (uint256);}
In this example, the PullOracleConsumer contract takes in data required for update verification, checks the update, and then emits an event to signal a price change.
This response provides all necessary details to verify the NGL/USD update, including:
merkleRoot: The resulting merkle root from a merkle tree containing the latest updates for our asset collection (prices-feed1).
signatures: Transmitter signatures on the merkleRoot bytes, confirming its emission on the EOB.
feeds: An array containing updates and verification data for requested assets.
key: Asset data key.
value: The price value and its timestamp.
merkleProofs: An array of merkle proofs to verify the presence of the NGL/USD asset in the merkle tree.
This data enables executing the getLastPrice transaction on the PullOracleConsumer contract. To begin, fetch the latest update from the Finalized Data API for the NGL/USD price.
Step #5: Send a transaction with the update data
Now that we understand the Finalized Data API, we can create a script that retrieves an update from the API, parses the response, encodes it to EVM calldata, and sends a getLastPrice transaction for the NGL/USD asset.
Below is a TypeScript script that accomplishes this task.