Chainlink – Fix ETHABIEncode Error: Unsupported Arg Type in Chainlink Any API

chainlinkoraclessolidity

I am trying to fetch data from an api which gives multiple response in single call and I am doing this using chainlink external API calls.

In my smart contract i have use array of struct to store requested data after request fulfil by Operator contract. I had also created my own job spec [TOML File] by running node locally on my system.

Now my error occur inside job spec file when i request for data.

For better understanding i have provided my smart contract code and job code also there is a screen shot of error that occur when execution while fetch populating fetch data into struct formate of fulfillMultipleParameters(bytes32 requestId,Trade[] memory _prices)

Screen shot of error

enter image description here

Node Operator Job Spec TOML File

schemaVersion = 1
name = "Multiple_Array_of_Struct_Datas_1"
forwardingAllowed = true
maxTaskDuration = "0s"
contractAddress = "0x2D470Df5823edefe6941F8F737660661e47f62af"
minContractPaymentLinkJuels = "0"
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_log -> decode_cbor


decode_cbor  [type="cborparse" data="$(decode_log.data)"]

fetch [type="http" method=GET url="$(decode_cbor.url)" allowunrestrictednetworkaccess="true"]


decode_cbor -> fetch



path1_parse [type="jsonparse" path="$(decode_cbor.path1)" data="$(fetch)" ]

path2_parse [type="jsonparse" path="$(decode_cbor.path2)" data="$(fetch)"]

path3_parse [type="jsonparse" path="$(decode_cbor.path3)" data="$(fetch)"]

path4_parse [type="jsonparse" path="$(decode_cbor.path4)" data="$(fetch)"]

path5_parse [type="jsonparse" path="$(decode_cbor.path5)" data="$(fetch)"]

fetch -> path1_parse
fetch -> path2_parse
fetch -> path3_parse
fetch -> path4_parse
fetch -> path5_parse

path5_parse -> encode_mwr
path4_parse -> encode_mwr
path3_parse -> encode_mwr
path2_parse -> encode_mwr
path1_parse -> encode_mwr


encode_mwr [type="ethabiencode"
                abi="(bytes32 requestId, Trade[] _prices)"
                data="{\\"requestId\\": $(decode_log.requestId), \\"_prices\\": [[ $(path1_parse)], [$(path2_parse)], [$(path3_parse)], [$(path4_parse)], [$(path5_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_mwr)}"
                ]
    submit_tx  [type="ethtx" to="0x2D470Df5823edefe6941F8F737660661e47f62af" data="$(encode_tx)" from="[\\"0x761Cd84957ecD0344E6C01a02A7cAe479D07B838\\"]"]
    encode_mwr -> encode_tx -> submit_tx
"""

Smart Contract Code

pragma solidity ^0.8.7;

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

/**
 * Request testnet LINK and ETH here: https://faucets.chain.link/
 * Find information on LINK Token Contracts and get the latest ETH and LINK faucets here: https://docs.chain.link/docs/link-token-contracts/
 */

/**
 * THIS IS AN EXAMPLE CONTRACT THAT USES HARDCODED VALUES FOR CLARITY.
 * THIS IS AN EXAMPLE CONTRACT THAT USES UN-AUDITED CODE.
 * DO NOT USE THIS CODE IN PRODUCTION.
 */

contract MultiWordConsumer is ChainlinkClient, ConfirmedOwner {
    using Chainlink for Chainlink.Request;

    struct Trade{
        string price;
    }

    bytes32 private jobId;
    uint256 private fee;

    // multiple params returned in a single oracle response
    Trade[] public trades;
   

    event RequestMultipleFulfilled(
        bytes32 indexed requestId,
        Trade[] indexed prices
    );

    /**
     * @notice Initialize the link token and target oracle
     * @dev The oracle address must be an Operator contract for multiword response
     *
     *
     * Sepolia Testnet details:
     * Link Token: 0x779877A7B0D9E8603169DdbD7836e478b4624789
     * Oracle: 0x6090149792dAAeE9D1D568c9f9a6F6B46AA29eFD (Chainlink DevRel)
     * jobId: 53f9755920cd451a8fe46f5087468395
     *
     */
    constructor() ConfirmedOwner(msg.sender) {
        setChainlinkToken(0x779877A7B0D9E8603169DdbD7836e478b4624789); 
        setChainlinkOracle(0x2D470Df5823edefe6941F8F737660661e47f62af); // Operator Contract Address
        jobId = "3464b5f4c3f74b66a22f881506d2aae5"; //3464b5f4-c3f7-4b66-a22f-881506d2aae5
        fee = (1 * LINK_DIVISIBILITY) / 10; // 0,1  10**18 (Varies by network and job)
    }

    /**
     * @notice Request mutiple parameters from the oracle in a single transaction
     */
    function requestMultipleParameters() public {
        Chainlink.Request memory req = buildChainlinkRequest(
            jobId,
            address(this),
            this.fulfillMultipleParameters.selector
        );
        req.add(
            "url",
            "https://api3.binance.com/api/v3/trades?symbol=BTCUSDT&limit=5"
        );

        for(uint i=0; i<5; i++){
        string memory strindex = Strings.toString(i);
        uint index = i + 1;
        string memory pathindex = Strings.toString(index);
        req.add(string.concat("path",pathindex), string.concat(strindex,",price"));

        }
        // req.add("path2", "1,price");
        // req.add("path3", "2,price");
        // req.add("path4", "3,price");
        // req.add("path5", "4,price");
        sendChainlinkRequest(req, fee); // MWR API.
    }

    /**
     * @notice Fulfillment function for multiple parameters in a single request
     * @dev This is called by the oracle. recordChainlinkFulfillment must be used.
     */
    function fulfillMultipleParameters(
        bytes32 requestId,
        Trade[] memory _prices
    ) public recordChainlinkFulfillment(requestId) {
        emit RequestMultipleFulfilled(
            requestId,
            _prices
        );

        for(uint i = 0; i< _prices.length; i++){
            trades.push(_prices[i]);
        }

    }

    function viewprice() public view returns(Trade[] memory ){
       
        return trades;
    }

    /**
     * Allow withdraw of Link tokens from the contract
     */
    function withdrawLink() public onlyOwner {
        LinkTokenInterface link = LinkTokenInterface(chainlinkTokenAddress());
        require(
            link.transfer(msg.sender, link.balanceOf(address(this))),
            "Unable to transfer"
        );
    }
}```



 

Best Answer

Can you try changing bytes32 to bytes in encode_tx and see if it works?

Related Topic