-
Notifications
You must be signed in to change notification settings - Fork 469
Expand file tree
/
Copy pathAPIConsumerForwarder.sol
More file actions
123 lines (107 loc) · 3.98 KB
/
APIConsumerForwarder.sol
File metadata and controls
123 lines (107 loc) · 3.98 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
import {Chainlink, ChainlinkClient} from "@chainlink/contracts/src/v0.8/operatorforwarder/ChainlinkClient.sol";
import {ConfirmedOwner} from "@chainlink/contracts/src/v0.8/shared/access/ConfirmedOwner.sol";
import {LinkTokenInterface} from "@chainlink/contracts/src/v0.8/shared/interfaces/LinkTokenInterface.sol";
/**
* THIS IS AN EXAMPLE CONTRACT THAT USES UN-AUDITED CODE.
* DO NOT USE THIS CODE IN PRODUCTION.
*/
contract APIConsumerForwarder is ChainlinkClient, ConfirmedOwner {
using Chainlink for Chainlink.Request;
uint256 private constant ORACLE_PAYMENT = (1 * LINK_DIVISIBILITY) / 10; // 0.1 * 10**18
uint256 public currentPrice;
string public id;
event RequestEthereumPriceFulfilled(bytes32 indexed requestId, uint256 indexed price);
event RequestFirstId(bytes32 indexed requestId, string id);
/**
* Sepolia
* @dev LINK address in Sepolia network: 0x779877A7B0D9E8603169DdbD7836e478b4624789
* @dev Check https://docs.chain.link/docs/link-token-contracts/ for LINK address for the right network
*/
constructor() ConfirmedOwner(msg.sender) {
_setChainlinkToken(0x779877A7B0D9E8603169DdbD7836e478b4624789);
}
function requestEthereumPrice(
address _oracle,
string memory _jobId
) public onlyOwner {
Chainlink.Request memory req =
_buildChainlinkRequest(stringToBytes32(_jobId), address(this), this.fulfillEthereumPrice.selector);
req._add("get", "https://min-api.cryptocompare.com/data/price?fsym=ETH&tsyms=USD");
req._add("path", "USD");
req._addInt("times", 100);
_sendChainlinkRequestTo(_oracle, req, ORACLE_PAYMENT);
}
/**
* Create a Chainlink request to retrieve API response, find the target
* data which is located in a list
*/
function requestFirstId(
address _oracle,
string memory _jobId
) public onlyOwner {
Chainlink.Request memory req =
_buildChainlinkRequest(stringToBytes32(_jobId), address(this), this.fulfillFirstId.selector);
// Set the URL to perform the GET request on
// API docs: https://www.coingecko.com/en/api/documentation?
req._add("get", "https://api.coingecko.com/api/v3/coins/markets?vs_currency=usd&per_page=10");
// Set the path to find the desired data in the API response, where the response format is:
// [{
// "id": "bitcoin",
// "symbol": "btc",
// ...
// },
//{
// ...
// .. }]
// request.add("path", "0.id"); // Chainlink nodes prior to 1.0.0 support this format
req._add("path", "0,id"); // Chainlink nodes 1.0.0 and later support this format
// Sends the request
_sendChainlinkRequestTo(_oracle, req, ORACLE_PAYMENT);
}
function fulfillEthereumPrice(
bytes32 _requestId,
uint256 _price
) public recordChainlinkFulfillment(_requestId) {
emit RequestEthereumPriceFulfilled(_requestId, _price);
currentPrice = _price;
}
/**
* Receive the response in the form of string
*/
function fulfillFirstId(
bytes32 _requestId,
string memory _id
) public recordChainlinkFulfillment(_requestId) {
emit RequestFirstId(_requestId, _id);
id = _id;
}
function getChainlinkToken() public view returns (address) {
return _chainlinkTokenAddress();
}
function withdrawLink() public onlyOwner {
LinkTokenInterface link = LinkTokenInterface(_chainlinkTokenAddress());
require(link.transfer(msg.sender, link.balanceOf(address(this))), "Unable to transfer");
}
function cancelRequest(
bytes32 _requestId,
uint256 _payment,
bytes4 _callbackFunctionId,
uint256 _expiration
) public onlyOwner {
_cancelChainlinkRequest(_requestId, _payment, _callbackFunctionId, _expiration);
}
function stringToBytes32(
string memory source
) private pure returns (bytes32 result) {
bytes memory tempEmptyStringTest = bytes(source);
if (tempEmptyStringTest.length == 0) {
return 0x0;
}
assembly {
// solhint-disable-line no-inline-assembly
result := mload(add(source, 32))
}
}
}