Inspiration

Metaverse opens the door to incredible experiences, while it is also challenging for sales and customer service of brands to expand in the new cyberspace. When people play, build, and trade in the metaverse, they definitely need help. In this case, what does customer service look like?

Digital Humans powered by Conversational AI is going to play an important role in the metaverse or at least to innovate sales and customer service out there.

In order to meet the customized data and computing requirements of Digital Human smart contracts on Aurora, we make use of Chainlink Any API and external adapter to enable our contracts to access the off-chain data and computing service.

The global AI Digital Humans market size is projected to reach $95 billion by 2027, at a CAGR of 74.8% during 2021-2027. On-chain Digital Human Engine is going to enable completely new business models in the metaverse and on Aurora Network.

What it does

A brand could embed Digital Humans powered by conversational AI and Chainlink adapters to meet the needs in metaverse. A digital assistance, or concierge, there to answer questions, assist, and facilitate. There can be a few use cases,

1.Retrieve scores and odds data, enable P2P sports betting app, For example, World Cup 2022 or Formula 1 racing;

2.Retrieve real-time quote for commodities, FOREX, and crypto spot market, enable trading and decentralized banking in metaverse;

3.Enable data-driven insurance, for example, vehicle insurance based on the driving style and number of days on road;

4.Retrieve inventory data, enable e-commerce in metaverse, for example, buy/sell ticket or virtual land, borrow books on-chain.

flow chart

How we built it

1.Digital Human engine/service calls the conversational AI model, when digital human speaking with customer;

2.AI model retrieves data from Chainlink external adapter; contract may read data via Chainlink node/adapter on Polygon for now, will migrate to Aurora network soon;

3.Chainlink external adapter retrieves real-time data (e.g. scores and odds) from off-chain API;

4.Digital human interacts with smart contracts, helping customer to place an order or bet. Order information is recorded on Aurora network; It is impossible to modify the order (or betting records) thus prevents fraudulent behavior.

5.Later, as scheduled, Digital Human engine/service retrieves data from Chainlink external adapter again, attaches more info to the orders on Aurora network, such as the final score of matches or the earning or losses of each betting order. flow chart

What's next for Digital Humans On Aurora Network

  1. Upgrade smart contracts on Aurora Network and AI models in different use cases listed above.
  2. Chainlink will release the Aurora version very soon. We plan to build the Chainlink node for Digital Humans on Aurora Network as soon as possible.

We're building Digital Human engine/service for e-commerce, customer service and any other industry that might need them. We turn Chainlink external adapter and nodes to be part of the engine/service behind Digital Humans in metaverse and Aurora Network, taking your business to the next level !

Testing

  1. See the demo at https://youtu.be/ruVA39S-vLI
  2. Download Android App - https://play.google.com/store/apps/details?id=com.planet.second
  3. Run the App, search the game name "world cup" in Android App
  4. Test the following use case: Digital Human on Aurora Network, promoting World Cup 2022 betting.

4.1 Request

curl --request GET --url https://api-football-v1.p.rapidapi.com/v3/timezone --header 'X-RapidAPI-Host: api-football-v1.p.rapidapi.com' --header 'X-RapidAPI-Key: SIGN-UP-FOR-KEY'

4.2 Result

{
    "api": {
        "results": 1,
        "fixtures": [
            {
                "fixture_id": 855736,
                "league_id": 4265,
                "league": {
                    "name": "World Cup",
                    "country": "World",
                    "logo": "https:\/\/media.api-sports.io\/football\/leagues\/1.png",
                    "flag": null
                },
                "event_date": "2022-11-21T00:00:00+08:00",
                "event_timestamp": 1668960000,
                "firstHalfStart": null,
                "secondHalfStart": null,
                "round": "Group Stage - 1",
                "status": "Not Started",
                "statusShort": "NS",
                "elapsed": 0,
                "venue": "Al Bayt Stadium",
                "referee": null,
                "homeTeam": {
                    "team_id": 1569,
                    "team_name": "Qatar",
                    "logo": "https:\/\/media.api-sports.io\/football\/teams\/1569.png"
                },
                "awayTeam": {
                    "team_id": 2382,
                    "team_name": "Ecuador",
                    "logo": "https:\/\/media.api-sports.io\/football\/teams\/2382.png"
                },
                "goalsHomeTeam": 2,
                "goalsAwayTeam": 1,
                "score": {
                    "halftime": "1-0",
                    "fulltime": "2-1",
                    "extratime": null,
                    "penalty": null
                }
            }
       ]
    }
}

4.3 External Adapter

Chainlink Node Job Definition

type = "directrequest"
schemaVersion = 1
name = "Worldcup-Data-football"
forwardingAllowed = false
maxTaskDuration = "0s"
contractAddress = "${YOUR_SMART_ADDRESS}"
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_cbor  [type=cborparse data="$(decode_log.data)"]
    fetch        [type=bridge name="worldcup" requestData="{\\"id\\": $(jobSpec.externalJobID), \\"data\\": { \\"api\\": $(decode_cbor.api)}}"]
    parse        [type=jsonparse path="data" data="$(fetch)"]
    encode_data  [type=ethabiencode
                  abi="(bytes32 _requestId, uint256 _fixtureId, bool _isFinish, uint8 _scoreTeamA, uint8 _scoreTeamB)" 
                  data="{ \\"_requestId\\": $(decode_log.requestId),\\"_fixtureId\\": $(parse.fixture_id),\\"_isFinish\\": $(parse.isFinish),\\"_scoreTeamA\\": $(parse.goalsHomeTeam),\\"_scoreTeamA\\": $(parse.goalsAwayTeam)  }"]
    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="${YOUR_SMART_ADDRESS}" data="$(encode_tx)"]

    decode_log -> decode_cbor -> fetch -> parse -> encode_data -> encode_tx -> submit_tx
"""

4.4 Smart Contract on Aurora Network for Digital Human promoting World Cup 2022 betting.

World Cup 2022 betting

{
  "smartBet": {   "address": "0xB795248717271c50d6D19312B6085bC8c686A529"
  }
}
/* Allow owner to get the data of stored games */
    function requestSchedule() public onlyOwner {
        uint256 matchCount = metaBet.countMatchs();
        require(matchCount > 0, "Match Empty");
        for (uint256 i = 0; i < matchCount; i++) {
            Chainlink.Request memory req = buildChainlinkRequest(
                BYTES_JOB,
                address(this),
                this.fulfillSchedule.selector
            );
            req.add("api",metaBet.matchResultLink(i));
            req.add("fixtureId", "fixture_id"); 
            req.add("statusShort", "statusShort"); 
            req.add("goalsHomeTeam", "goalsHomeTeam"); 
            req.add("goalsAwayTeam", "goalsAwayTeam");

            sendChainlinkRequest(req, LINK_PAYMENT);
        }
    }
/**
     * @notice Stores the scheduled games.
     * @param _requestId the request ID for fulfillment.
     * @param _leagueId the games either to be created or resolved.
     * @param _fixtureId the games either to be created or resolved.
     * @param _isFinish the games either to be created or resolved.
     * @param _scoreTeamA the games either to be created or resolved.
     * @param _scoreTeamB the games either to be created or resolved.
     */
    function fulfillSchedule(
        bytes32 _requestId,
        uint256 _leagueId,
        uint256 _fixtureId,
        bool _isFinish,
        uint8 _scoreTeamA,
        uint8 _scoreTeamB
    ) external onlyOwner recordChainlinkFulfillment(_requestId) {
        if (_isFinish) {
            uint256 _matchId = metaBet.apiMatchId(_fixtureId);
            uint8 _matchResult = 0;
            if (_scoreTeamA == _scoreTeamB) {
                _matchResult = 1;
            } else if (_scoreTeamA > _scoreTeamB) {
                _matchResult = 2;
            } else if (_scoreTeamA < _scoreTeamB) {
                _matchResult = 3;
            }
            metaBet.closeMatch(
                _matchId,
                _matchResult,
                0,
                _scoreTeamA,
                _scoreTeamB
            );
        }
    }

Response data

{
    "jobRunID": "134ea675a9524e8e231585b00368b178",
    "data": "{1, 855736,true,3,4}",
    "result": null,
    "statusCode": 200
}
Share this project:

Updates