Skip to content

Commit

Permalink
POST jobs for Kovan & Mumbai
Browse files Browse the repository at this point in the history
  • Loading branch information
ijonas committed May 21, 2022
1 parent 1d2e02c commit ee6d1fc
Show file tree
Hide file tree
Showing 16 changed files with 723 additions and 2 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.DS_Store
68 changes: 68 additions & 0 deletions ethereum-kovan/Post > Bytes/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# Post > Bytes

This job retrieves a variable-length string after posting to an internet-facing JSON API.

## Contract Address & JobID

Contract: [0xf71775b3640D7034466e0321E35c5CFB78fd212F](https://rinkeby.etherscan.io/address/0xf71775b3640D7034466e0321E35c5CFB78fd212F)

JobID: fc2ecbc2f58f45c4868d3959850df8c3

## Parameters

The job requires the following parameters to be specified:

* `post` - internet-facing URL to post the `requestData` to
* `requestData` - the JSON-string payload that will be sent to the URL
* `path` - comma-separated JSON path used to extract the string value

Note: use commas not dots for JSON paths.

## Price

0.05 LINK

## Example

If you set the following parameters

* post : https://httpbin.org/post
* requestData: `"{\"email\": \"[email protected]\", \"anInteger\": 2008}"`
* path : json,email

Note: use commas not dots for JSON paths.

You will receive a JSON response that may look like this:

{
"args": {},
"data": "{\"email\": \"[email protected]\", \"anInteger\": 2008}",
"files": {},
"form": {},
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate, br",
"Content-Length": "53",
"Content-Type": "text/plain",
"Host": "httpbin.org",
"Postman-Token": "fd36b43e-fc40-45c9-8050-2c01d8b03d09",
"User-Agent": "PostmanRuntime/7.29.0",
"X-Amzn-Trace-Id": "Root=1-6288c9cd-42ae35b57cab267656b82236"
},
"json": {
"anInteger": 2008,
"email": "[email protected]"
},
"origin": "84.71.9.112",
"url": "https://httpbin.org/post"
}

The job populated with the example parameters above would return with: `[email protected]`

See [example.sol](example.sol) for an example client contract.

## Troubleshooting

1. Please make sure you load your client contract, e.g. example.sol, with enough LINK, otherwise you'll get a "Gas estimation failed" error.
2. The contract address and jobId mentioned above are specific to the network and won't work on other networks.
3. Please find us in our [Discord](https://discord.gg/2bSBwJDJ) if you're stuck and needing help.
65 changes: 65 additions & 0 deletions ethereum-kovan/Post > Bytes/example.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;

import "@chainlink/contracts/src/v0.8/ChainlinkClient.sol";
import "@chainlink/contracts/src/v0.8/ConfirmedOwner.sol";

/**
* @notice DO NOT USE THIS CODE IN PRODUCTION. This is an example contract.
*/
contract PostBytes is ChainlinkClient, ConfirmedOwner {
using Chainlink for Chainlink.Request;

uint256 private constant ORACLE_PAYMENT =
((1 * LINK_DIVISIBILITY) / 100) * 5;
string public stringData;

event RequestValue(bytes32 indexed requestId, bytes indexed value);

string constant jobId = "15504b1312d5469fb92cabdc3d46c2ae";

constructor() ConfirmedOwner(msg.sender) {
// KOVAN
setChainlinkToken(0xa36085F69e2889c224210F603D836748e7dC0088);
setChainlinkOracle(0xf71775b3640D7034466e0321E35c5CFB78fd212F);
}

function requestValue() public onlyOwner returns (bytes32 requestId) {
Chainlink.Request memory req = buildChainlinkRequest(
stringToBytes32(jobId),
address(this),
this.fulfillValue.selector
);
req.add("post", "https://httpbin.org/post");
req.add(
"requestData",
'{"email": "[email protected]", "anInteger": 2008}'
);
req.add("path", "json,email");
return sendOperatorRequest(req, ORACLE_PAYMENT);
}

function fulfillValue(bytes32 _requestId, bytes memory _value)
public
recordChainlinkFulfillment(_requestId)
{
emit RequestValue(_requestId, _value);
stringData = string(_value);
}

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))
}
}
}
30 changes: 30 additions & 0 deletions ethereum-kovan/Post > Bytes/jobspec.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
type = "directrequest"
schemaVersion = 1
name = "TL Post > Bytes"
externalJobID = "15504b13-12d5-469f-b92c-abdc3d46c2ae"
maxTaskDuration = "0s"
contractAddress = "0xf71775b3640D7034466e0321E35c5CFB78fd212F"
minIncomingConfirmations = 0
minContractPaymentLinkJuels = 50000000000000000
observationSource = """
decode_log [type="ethabidecodelog"
abi="OracleRequest(bytes32 indexed specId, address requester, bytes32 requestId, uint256 payment, address callbackAddr, bytes4 callbackFunctionId, uint256 cancelExpiration, uint256 dataVersion, bytes data)"
data="$(jobRun.logData)"
topics="$(jobRun.logTopics)"]
decode_cbor [type="cborparse" data="$(decode_log.data)"]
post [type="http" method=POST url="$(decode_cbor.post)" requestData="$(decode_cbor.requestData)"]
parse [type="jsonparse" path="$(decode_cbor.path)" data="$(post)"]
encode_large [type="ethabiencode"
abi="(bytes32 requestId, bytes _data)"
data="{\\"requestId\\": $(decode_log.requestId), \\"_data\\": $(parse)}"
]
encode_tx [type="ethabiencode"
abi="fulfillOracleRequest2(bytes32 requestId, uint256 payment, address callbackAddress, bytes4 callbackFunctionId, uint256 expiration, bytes calldata data)"
data="{\\"requestId\\": $(decode_log.requestId), \\"payment\\": $(decode_log.payment), \\"callbackAddress\\": $(decode_log.callbackAddr), \\"callbackFunctionId\\": $(decode_log.callbackFunctionId), \\"expiration\\": $(decode_log.cancelExpiration), \\"data\\": $(encode_large)}"
]
submit_tx [type="ethtx" to="0xf71775b3640D7034466e0321E35c5CFB78fd212F" data="$(encode_tx)"]
decode_log -> decode_cbor -> post -> parse -> encode_large -> encode_tx -> submit_tx
"""
70 changes: 70 additions & 0 deletions ethereum-kovan/Post > Uint256/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# Post > Uint256

This job retrieves a `uint256` integer after posting to an internet-facing JSON API.

## Contract Address & JobID

Contract: [0xf71775b3640D7034466e0321E35c5CFB78fd212F](https://rinkeby.etherscan.io/address/0xf71775b3640D7034466e0321E35c5CFB78fd212F)

JobID: fc2ecbc2f58f45c4868d3959850df8c3

## Parameters

The job requires the following parameters to be specified:

* `post` - internet-facing URL to post the `requestData` to
* `requestData` - the JSON-string payload that will be sent to the URL
* `path` - comma-separated JSON path used to extract the integer value
* `multiply` - factor using to deal with precision and rounding errors

Note: use commas not dots for JSON paths.

## Price

0.05 LINK

## Example

If you set the following parameters

* post : https://httpbin.org/post
* requestData: `"{\"email\": \"[email protected]\", \"anInteger\": 2008}"`
* path : json,anInteger
* multiply : 100

Note: use commas not dots for JSON paths.

You will receive a JSON response that may look like this:

{
"args": {},
"data": "{\"email\": \"[email protected]\", \"anInteger\": 2008}",
"files": {},
"form": {},
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate, br",
"Content-Length": "53",
"Content-Type": "text/plain",
"Host": "httpbin.org",
"Postman-Token": "fd36b43e-fc40-45c9-8050-2c01d8b03d09",
"User-Agent": "PostmanRuntime/7.29.0",
"X-Amzn-Trace-Id": "Root=1-6288c9cd-42ae35b57cab267656b82236"
},
"json": {
"anInteger": 2008,
"email": "[email protected]"
},
"origin": "84.71.9.112",
"url": "https://httpbin.org/post"
}

The job populated with the example parameters above would return with: `200800`

See [example.sol](example.sol) for an example client contract.

## Troubleshooting

1. Please make sure you load your client contract, e.g. example.sol, with enough LINK, otherwise you'll get a "Gas estimation failed" error.
2. The contract address and jobId mentioned above are specific to the network and won't work on other networks.
3. Please find us in our [Discord](https://discord.gg/2bSBwJDJ) if you're stuck and needing help.
66 changes: 66 additions & 0 deletions ethereum-kovan/Post > Uint256/example.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;

import "@chainlink/contracts/src/v0.8/ChainlinkClient.sol";
import "@chainlink/contracts/src/v0.8/ConfirmedOwner.sol";

/**
* @notice DO NOT USE THIS CODE IN PRODUCTION. This is an example contract.
*/
contract PostUint256 is ChainlinkClient, ConfirmedOwner {
using Chainlink for Chainlink.Request;

uint256 private constant ORACLE_PAYMENT =
((1 * LINK_DIVISIBILITY) / 100) * 5;
uint256 public value;

event RequestValue(bytes32 indexed requestId, uint256 indexed value);

string constant jobId = "fc2ecbc2f58f45c4868d3959850df8c3";

constructor() ConfirmedOwner(msg.sender) {
// KOVAN
setChainlinkToken(0xa36085F69e2889c224210F603D836748e7dC0088);
setChainlinkOracle(0xf71775b3640D7034466e0321E35c5CFB78fd212F);
}

function requestValue() public onlyOwner returns (bytes32 requestId) {
Chainlink.Request memory req = buildChainlinkRequest(
stringToBytes32(jobId),
address(this),
this.fulfillValue.selector
);
req.add("post", "https://httpbin.org/post");
req.add(
"requestData",
'{"email": "[email protected]", "anInteger": 2008}'
);
req.add("path", "json,anIteger");
req.addInt("multiply", 100);
return sendChainlinkRequest(req, ORACLE_PAYMENT);
}

function fulfillValue(bytes32 _requestId, uint256 _value)
public
recordChainlinkFulfillment(_requestId)
{
emit RequestValue(_requestId, _value);
value = _value;
}

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))
}
}
}
27 changes: 27 additions & 0 deletions ethereum-kovan/Post > Uint256/jobspec.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
type = "directrequest"
schemaVersion = 1
name = "TL Post > Uint256"
externalJobID = "fc2ecbc2-f58f-45c4-868d-3959850df8c3"
maxTaskDuration = "0s"
contractAddress = "0xf71775b3640D7034466e0321E35c5CFB78fd212F"
minIncomingConfirmations = 0
minContractPaymentLinkJuels = 50000000000000000
observationSource = """
decode_log [type="ethabidecodelog"
abi="OracleRequest(bytes32 indexed specId, address requester, bytes32 requestId, uint256 payment, address callbackAddr, bytes4 callbackFunctionId, uint256 cancelExpiration, uint256 dataVersion, bytes data)"
data="$(jobRun.logData)"
topics="$(jobRun.logTopics)"]
decode_cbor [type="cborparse" data="$(decode_log.data)"]
post [type="http" method=POST url="$(decode_cbor.post)" requestData="$(decode_cbor.requestData)"]
parse [type="jsonparse" path="$(decode_cbor.path)" data="$(post)"]
multiply [type="multiply" input="$(parse)" times="$(decode_cbor.multiply)"]
encode_data [type="ethabiencode" abi="(uint256 value)" data="{ \\"value\\": $(multiply) }"]
encode_tx [type="ethabiencode"
abi="fulfillOracleRequest(bytes32 requestId, uint256 payment, address callbackAddress, bytes4 callbackFunctionId, uint256 expiration, bytes32 data)"
data="{\\"requestId\\": $(decode_log.requestId), \\"payment\\": $(decode_log.payment), \\"callbackAddress\\": $(decode_log.callbackAddr), \\"callbackFunctionId\\": $(decode_log.callbackFunctionId), \\"expiration\\": $(decode_log.cancelExpiration), \\"data\\": $(encode_data)}"
]
submit_tx [type="ethtx" to="0xf71775b3640D7034466e0321E35c5CFB78fd212F" data="$(encode_tx)"]
decode_log -> decode_cbor -> post -> parse -> multiply -> encode_data -> encode_tx -> submit_tx
"""
Loading

0 comments on commit ee6d1fc

Please sign in to comment.