Retrieve Web2 data and store it on-chain using Chainlink Functions.
Perform custom computation off-chain using Web2 data in your smart contract.
Under the Hood
1// SPDX-License-Identifier: MIT
2pragma solidity ^0.8.19;
3
4import {FunctionsClient} from "@chainlink/contracts/src/v0.8/functions/dev/v1_0_0/FunctionsClient.sol";
5import {ConfirmedOwner} from "@chainlink/contracts/src/v0.8/shared/access/ConfirmedOwner.sol";
6import {FunctionsRequest} from "@chainlink/contracts/src/v0.8/functions/dev/v1_0_0/libraries/FunctionsRequest.sol";
7
8/**
9 * @title Chainlink Functions example consuming weather data
10 */
11contract XUserDataConsumer is FunctionsClient, ConfirmedOwner {
12 using FunctionsRequest for FunctionsRequest.Request;
13
14 enum ResponseType {
15 UserInfo,
16 UserLastTweet
17 }
18
19 struct APIResponse {
20 ResponseType responseType;
21 string response;
22 }
23
24 // Chainlink Functions script soruce code
25 string private constant SOURCE_USERNAME_INFO =
26 "const username = args[0];"
27 "if(!secrets.xBearerToken) {"
28 "throw Error('No bearer token');"
29 "}"
30 "const xUserResponse = await Functions.makeHttpRequest({"
31 "url: `https://api.twitter.com/2/users/by/username/${username}?user.fields=profile_image_url`,"
32 "headers: { Authorization: `Bearer ${secrets.xBearerToken}` },"
33 "});"
34 "if (xUserResponse.error) {"
35 "throw Error(`X User Request Error`);"
36 "}"
37 "const { name, id } = xUserResponse.data.data;"
38 "return Functions.encodeString([name, id]);";
39
40 string private constant SOURCE_LAST_TWEET_INFO =
41 "const id = args[0];"
42 "if (!secrets.xBearerToken) {"
43 "throw Error('No bearer token');"
44 "}"
45 "const xTweetsResponse = await Functions.makeHttpRequest({"
46 "url: `https://api.twitter.com/2/users/${id}/tweets`,"
47 "headers: { Authorization: `Bearer ${secrets.xBearerToken}` },"
48 "});"
49 "if (xTweetsResponse.error) {"
50 "throw Error('X User Request Error');"
51 "}"
52 "const lastTweet = xTweetsResponse.data.data[0].text;"
53 "const shortenedTweet = lastTweet.substring(0, 255);"
54 "return Functions.encodeString(shortenedTweet);";
55
56 bytes32 public donId; // DON ID for the Functions DON to which the requests are sent
57 uint64 private subscriptionId; // Subscription ID for the Chainlink Functions
58 uint32 private gasLimit; // Gas limit for the Chainlink Functions callbacks
59
60 // Mapping of request IDs to weather info
61 mapping(bytes32 => APIResponse) public requests;
62
63 event UserInfoRequested(bytes32 indexed requestId, string username);
64 event UserInfoReceived(bytes32 indexed requestId, string response);
65 event UserLastTweetRequested(bytes32 indexed requestId, string username);
66 event UserLastTweetReceived(bytes32 indexed requestId, string response);
67 event RequestFailed(bytes error);
68
69 constructor(
70 address router,
71 bytes32 _donId,
72 uint64 _subscriptionId,
73 uint32 _gasLimit
74 ) FunctionsClient(router) ConfirmedOwner(msg.sender) {
75 donId = _donId;
76 subscriptionId = _subscriptionId;
77 gasLimit = _gasLimit;
78 }
79
80 /**
81 * @notice Request X profile information for provided handle
82 * @param username username of said user e.g. chainlink
83 * @param slotId the location of the DON-hosted secrets
84 * @param version the version of the secret to be used
85 */
86 function requestUserInfo(string calldata username, uint8 slotId, uint64 version) external {
87 string[] memory args = new string[](1);
88 args[0] = username;
89 bytes32 requestId = _sendRequest(SOURCE_USERNAME_INFO, args, slotId, version);
90
91 requests[requestId].responseType = ResponseType.UserInfo;
92 emit UserInfoRequested(requestId, username);
93 }
94
95 /**
96 * @notice Request last post for given username
97 * @param userId username of said user e.g. chainlink
98 * @param slotId the location of the DON-hosted secrets
99 * @param version the version of the secret to be used
100 */
101 function requestLastTweet(string calldata userId, uint8 slotId, uint64 version) external {
102 string[] memory args = new string[](1);
103 args[0] = userId;
104 bytes32 requestId = _sendRequest(SOURCE_LAST_TWEET_INFO, args, slotId, version);
105
106 requests[requestId].responseType = ResponseType.UserLastTweet;
107 emit UserLastTweetRequested(requestId, userId);
108 }
109
110 /**
111 * @notice Process the response from the executed Chainlink Functions script
112 * @param requestId The request ID
113 * @param response The response from the Chainlink Functions script
114 */
115 function _processResponse(bytes32 requestId, bytes memory response) private {
116 requests[requestId].response = string(response);
117 if (requests[requestId].responseType == ResponseType.UserInfo) {
118 emit UserInfoReceived(requestId, string(response));
119 } else {
120 emit UserLastTweetReceived(requestId, string(response));
121 }
122 }
123
124 // CHAINLINK FUNCTIONS
125
126 /**
127 * @notice Triggers an on-demand Functions request
128 * @param args String arguments passed into the source code and accessible via the global variable `args`
129 * @param slotId the location of the DON-hosted secrets
130 * @param version the version of the secret to be used
131 */
132 function _sendRequest(
133 string memory source,
134 string[] memory args,
135 uint8 slotId,
136 uint64 version
137 ) internal returns (bytes32 requestId) {
138 FunctionsRequest.Request memory req;
139 req.initializeRequest(FunctionsRequest.Location.Inline, FunctionsRequest.CodeLanguage.JavaScript, source);
140 req.addDONHostedSecrets(slotId, version);
141 if (args.length > 0) {
142 req.setArgs(args);
143 }
144 requestId = _sendRequest(req.encodeCBOR(), subscriptionId, gasLimit, donId);
145 }
146
147 /**
148 * @notice Fulfillment callback function
149 * @param requestId The request ID, returned by sendRequest()
150 * @param response Aggregated response from the user code
151 * @param err Aggregated error from the user code or from the execution pipeline
152 * Either response or error parameter will be set, but never both
153 */
154 function fulfillRequest(bytes32 requestId, bytes memory response, bytes memory err) internal override {
155 if (err.length > 0) {
156 emit RequestFailed(err);
157 return;
158 }
159 _processResponse(requestId, response);
160 }
161
162 // OWNER
163
164 /**
165 * @notice Set the DON ID
166 * @param newDonId New DON ID
167 */
168 function setDonId(bytes32 newDonId) external onlyOwner {
169 donId = newDonId;
170 }
171}
172
Recent Requests
We reject: kings, presidents, and voting.
We believe in: rough consensus and running code.
—David Clark,...
Reading through this gives us chills about how it could be a game changer in multi-chain dApp development...
We reject: kings, presidents, and voting.
We believe in: rough consensus and running code.
—David Clark,...
@anth0nybeaumont @encodeclub @oxfordblocksoc @DrAdaku @camblockchains @KissoSelvan Excited to be part of ...
@anth0nybeaumont @encodeclub @oxfordblocksoc @DrAdaku @camblockchains @KissoSelvan Excited to be part of ...
Topping up my 78801C36 wallet with Holesky ETH from @quicknode's faucet. Quick and easy! https://t.co/6K4...
RT @Lang__Leon: Shane Legg, cofounder of DeepMind, in 2009. SIAI was the Singularity Institute for Artifi...