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 Human Engine 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 Engine smart contracts, we make use of Chainlink Any API and external adapter to enable our contracts to access the off-chain Conversational AI 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.
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.

How we built it
1.Digital Human AI engine calls the conversational AI model, when digital human speaking with customer;
2.AI model retrieves data from Chainlink external adapter; use IPFS for data addressing, decentralized storage;
3.Chainlink external adapter retrieves real-time data (e.g. scores and odds) from off-chain API, or from Truflation data;
4.Digital human interacts with smart contracts, helping customer to place an order. Order information is recorded on-chain; It is impossible to modify the order (say betting records) thus prevents fraudulent behavior.
5.Later, as scheduled, Digital Human AI engine retrieves data from Chainlink external adapter again, attaches more info to the orders on-chain, such as the final score of matches or the earning or losses of each betting order.

What's next for Digital Humans powered by AI, Chainlink and Smart Contract
- Upgrade AI models in different use cases listed above.
- Build solution using Truflation data: NFT indexes, commodities data, FIFA soccer data.
We're building Digital Human AI engine 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 AI engine behind Digital Humans in metaverse, taking your business to the next level !
Testing
- Android App - https://play.google.com/store/apps/details?id=com.planet.second
- Search the game name "world cup" in Android App
- Test the use case: Digital Human powered by Chainlink node, promoting World Cup 2022 betting.
3.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'
3.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
}
}
]
}
}
3.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
"""
3.4 Smart Contract
/* 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
}

Log in or sign up for Devpost to join the conversation.