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:
- Create an Upshot API key by creating an account (opens in a new tab).
- 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 provideethereum-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"
}
}
}
- Construct a call to the Allora Consumer contract on the chain of your choice (options listed under deployments) using the returned
signature
andnetwork-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 usescamelCase
for attribute names. - Ethers.js does not accept
''
forextraData
. EmptyextraData
should be denoted with'0x'
.
Code Links
- Open source consumer code (opens in a new tab)
- IAlloraConsumer (opens in a new tab), including the structs used for Solidity code.