Walkthrough: Using a Topic Inference on-chain

Walkthrough: Using a Topic Inference on-chain

Follow these instructions to bring the most recent inference data on-chain for a given topic.

Complete Example:

    /**
     * @notice Example for calling a protocol function with topic inference data
     * 
     * @param protocolFunctionArgument An argument for the protocol function
     * @param alloraNetworkInferenceData The signed data from the Allora Consumer
     */
    function callProtocolFunctionWithAlloraTopicInference(
        uint256 protocolFunctionArgument,
        AlloraConsumerNetworkInferenceData calldata alloraNetworkInferenceData
    ) external payable {
        (
            uint256 value,
            uint256[] memory confidenceIntervalPercentiles,
            uint256[] memory confidenceIntervalValues,
        ) = IAlloraConsumer(<Consumer Contract Address>).verifyNetworkInference(alloraNetworkInferenceData);
 
        _protocolFunctionRequiringPredictionValue(
            protocolFunctionArgument, 
            value,
            confidenceIntervalPercentiles,
            confidenceIntervalValues
        );
    }

Step by Step Guide:

  1. Create an Upshot API key by creating an account (opens in a new tab).
  2. Call the Consumer Inference API using the topicId found in the deployed topics list and the correct chainId. For example, if you use sepolia, you would provide ethereum-11155111.
curl -X 'GET' --url 'https://api.upshot.xyz/v2/allora/consumer/<chainId>?allora_topic_id=<topicId>' -H 'accept: application/json' -H 'x-api-key: <apiKey>'

Here is an example response:

{
	"request_id": "b52b7c20-57ae-4852-bdbb-8f39cf317974",
	"status": true,
	"data": {
		"signature": "0x99b8b75f875a9ecc09fc499073656407458d464edeceb384686dba990ed785d841e6510b578d253a6e19a20503d1ec1e3c38b4c60980ff3b4df9ce3335ebd3851b",
		"inference_data": {
			"network_inference": "3365485208027959000000",
			"confidence_interval_percentiles": ["2280000000000000000", "15870000000000000000", "50000000000000000000", "84130000000000000000", "97720000000000000000"],
			"confidence_interval_values": ["2280000000000000000", "15870000000000000000", "50000000000000000000", "84130000000000000000", "97720000000000000000"],
			"topic_id": "9",
			"timestamp": "1719866777",
			"extra_data": "0x"
		}
	}
}
  1. Construct a call to the Allora Consumer contract on the chain of your choice (options listed under deployments) using the returned signature and network-inference as follows:

Creating the Transaction:

Note you be doing something more like callProtocolFunctionWithAlloraTopicInference in the example above, so you would want to construct your call to that contract in a similar way to the following. You can find the complete example here (opens in a new tab).

const alloraConsumer = 
  (new AlloraConsumer__factory())
    .attach(ALLORA_CONSUMER_ADDRESS)
    .connect(senderWallet) as AlloraConsumer
 
const tx = await alloraConsumer.verifyNetworkInference({
  signature: '0x99b8b75f875a9ecc09fc499073656407458d464edeceb384686dba990ed785d841e6510b578d253a6e19a20503d1ec1e3c38b4c60980ff3b4df9ce3335ebd3851b',
    networkInference: {
    topicId: 9,
    timestamp: 1719866777,
    extraData: ethers.toUtf8Bytes(''),
    networkInference: '3365485208027959000000',
    confidenceIntervalPercentiles:['2280000000000000000', '15870000000000000000', '50000000000000000000', '84130000000000000000', '97720000000000000000' ],
    confidenceIntervalValues:[ '3016256807053656000000', '3029849059956295000000', '3049738780726754000000', '3148682039955208400000', '3278333171848616500000' ],
  }, 
  extraData: ethers.toUtf8Bytes(''),
})
 
console.info('tx hash:', tx.hash) 
console.info('Awaiting tx confirmation...')
 
const result = await tx.wait()
 
console.info('tx receipt:', result)

Notes

  • The API endpoint uses snake_case, while the smart contract uses camelCase for attribute names.
  • Ethers.js does not accept '' for extraData. Empty extraData should be denoted with '0x'.

Code Links