Skip to content

Instantly share code, notes, and snippets.

@ericjaurena
Created May 4, 2022 20:59
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ericjaurena/86132c6b6ad6ed1c7079fe20fe03a034 to your computer and use it in GitHub Desktop.
Save ericjaurena/86132c6b6ad6ed1c7079fe20fe03a034 to your computer and use it in GitHub Desktop.
Example Consumer for Enetscores
// SPDX-License-Identifier: MIT
pragma solidity 0.8.9;
import "@chainlink/contracts/src/v0.8/ChainlinkClient.sol";
/**
* **** Data Conversions ****
*
* market (uint256)
* --------------------------
* Value Type
* --------------------------
* 0 create
* 1 resolve
*
*/
/**
* @title A consumer contract for Enetscores.
* @author LinkPool.
* @notice Interact with the daily events API.
* @dev Uses @chainlink/contracts 0.4.0.
*/
contract EnetscoresConsumer is ChainlinkClient {
using Chainlink for Chainlink.Request;
using CBORChainlink for BufferChainlink.buffer;
struct GameCreate {
uint256 gameId;
uint256 startTime;
string homeTeam;
string awayTeam;
}
struct GameResolve {
uint256 gameId;
uint128 homeScore;
uint128 awayScore;
string status;
}
mapping(bytes32 => bytes[]) public requestIdGames;
error FailedTransferLINK(address to, uint256 amount);
/**
* @param _link the LINK token address.
* @param _oracle the Operator.sol contract address.
*/
constructor(address _link, address _oracle) {
setChainlinkToken(_link);
setChainlinkOracle(_oracle);
}
/* ========== CONSUMER REQUEST FUNCTIONS ========== */
/**
* @notice Requests the tournament games either to be created or to be resolved on a specific date.
* @dev Requests the 'schedule' endpoint. Result is an array of GameCreate or GameResolve encoded (see structs).
* @param _specId the jobID.
* @param _payment the LINK amount in Juels (i.e. 10^18 aka 1 LINK).
* @param _market the number associated with the type of market (see Data Conversions).
* @param _leagueId the tournament ID.
* @param _date the starting time of the event as a UNIX timestamp in seconds.
*/
function requestSchedule(
bytes32 _specId,
uint256 _payment,
uint256 _market,
uint256 _leagueId,
uint256 _date
) external {
Chainlink.Request memory req = buildOperatorRequest(_specId, this.fulfillSchedule.selector);
req.addUint("market", _market);
req.addUint("leagueId", _leagueId);
req.addUint("date", _date);
sendOperatorRequest(req, _payment);
}
/**
* @notice Requests the tournament games either to be created or to be resolved on a specific date.
* @dev Requests the 'schedule' endpoint. Result is an array of GameCreate or GameResolve encoded (see structs).
* @param _specId the jobID.
* @param _payment the LINK amount in Juels (i.e. 10^18 aka 1 LINK).
* @param _market the context of the games data to be requested: `0` (markets to be created),
* `1` (markets to be resolved).
* @param _leagueId the tournament ID.
* @param _date the date to request events by, as a UNIX timestamp in seconds.
* @param _gameIds the list of game IDs to filter by for market `1`, otherwise the value is ignored.
*/
function requestSchedule(
bytes32 _specId,
uint256 _payment,
uint256 _market,
uint256 _leagueId,
uint256 _date,
uint256[] calldata _gameIds
) external {
Chainlink.Request memory req = buildOperatorRequest(_specId, this.fulfillSchedule.selector);
req.addUint("market", _market);
req.addUint("leagueId", _leagueId);
req.addUint("date", _date);
_addUintArray(req, "gameIds", _gameIds);
sendOperatorRequest(req, _payment);
}
/* ========== CONSUMER FULFILL FUNCTIONS ========== */
/**
* @notice Stores the scheduled games.
* @param _requestId the request ID for fulfillment.
* @param _result the games either to be created or resolved.
*/
function fulfillSchedule(bytes32 _requestId, bytes[] memory _result)
external
recordChainlinkFulfillment(_requestId)
{
requestIdGames[_requestId] = _result;
}
function getGameCreateList(bytes32 _requestId, uint256 _idx) external view returns (GameCreate memory) {
GameCreate memory game = abi.decode(requestIdGames[_requestId][_idx], (GameCreate));
return game;
}
function getGameResolveList(bytes32 _requestId, uint256 _idx) external view returns (GameResolve memory) {
GameResolve memory game = abi.decode(requestIdGames[_requestId][_idx], (GameResolve));
return game;
}
/* ========== OTHER FUNCTIONS ========== */
function getOracleAddress() external view returns (address) {
return chainlinkOracleAddress();
}
function setOracle(address _oracle) external {
setChainlinkOracle(_oracle);
}
function withdrawLink(uint256 _amount, address payable _payee) external {
LinkTokenInterface linkToken = LinkTokenInterface(chainlinkTokenAddress());
_requireTransferLINK(linkToken.transfer(_payee, _amount), _payee, _amount);
}
function _addUintArray(
Chainlink.Request memory _req,
string memory _key,
uint256[] memory _values
) private pure {
Chainlink.Request memory r2 = _req;
r2.buf.encodeString(_key);
r2.buf.startArray();
uint256 valuesLength = _values.length;
for (uint256 i = 0; i < valuesLength; ) {
r2.buf.encodeUInt(_values[i]);
unchecked {
++i;
}
}
r2.buf.endSequence();
_req = r2;
}
function _requireTransferLINK(
bool _success,
address _to,
uint256 _amount
) private pure {
if (!_success) {
revert FailedTransferLINK(_to, _amount);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment