-
Notifications
You must be signed in to change notification settings - Fork 31
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
7cc5e1d
commit df6184e
Showing
7 changed files
with
272 additions
and
32 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
// SPDX-License-Identifier: UNLICENSED | ||
pragma solidity ^0.8.20; | ||
|
||
// Uncomment this line to use console.log | ||
// import "hardhat/console.sol"; | ||
|
||
|
||
interface IOracle { | ||
function createFunctionCall( | ||
uint functionCallbackId, | ||
string memory functionType, | ||
string memory functionInput | ||
) external returns (uint i); | ||
|
||
function createKnowledgeBaseQuery( | ||
uint kbQueryCallbackId, | ||
string memory cid, | ||
string memory query, | ||
uint32 num_documents | ||
) external returns (uint i); | ||
} | ||
|
||
contract Test { | ||
address private owner; | ||
address public oracleAddress; | ||
string public lastResponse; | ||
string public lastError; | ||
uint private callsCount; | ||
|
||
event OracleAddressUpdated(address indexed newOracleAddress); | ||
|
||
constructor( | ||
address initialOracleAddress | ||
) { | ||
owner = msg.sender; | ||
oracleAddress = initialOracleAddress; | ||
} | ||
|
||
modifier onlyOwner() { | ||
require(msg.sender == owner, "Caller is not owner"); | ||
_; | ||
} | ||
|
||
modifier onlyOracle() { | ||
require(msg.sender == oracleAddress, "Caller is not oracle"); | ||
_; | ||
} | ||
|
||
function setOracleAddress(address newOracleAddress) public onlyOwner { | ||
oracleAddress = newOracleAddress; | ||
emit OracleAddressUpdated(newOracleAddress); | ||
} | ||
|
||
function callFunction(string memory name, string memory message) public returns (uint i) { | ||
uint currentId = callsCount; | ||
callsCount = currentId + 1; | ||
|
||
lastResponse = ""; | ||
lastError = ""; | ||
|
||
IOracle(oracleAddress).createFunctionCall( | ||
currentId, | ||
name, | ||
message | ||
); | ||
|
||
return currentId; | ||
} | ||
|
||
function queryKnowledgeBase(string memory cid, string memory query) public returns (uint i) { | ||
uint currentId = callsCount; | ||
callsCount = currentId + 1; | ||
|
||
lastResponse = ""; | ||
lastError = ""; | ||
|
||
IOracle(oracleAddress).createKnowledgeBaseQuery( | ||
currentId, | ||
cid, | ||
query, | ||
3 | ||
); | ||
return currentId; | ||
} | ||
|
||
function onOracleFunctionResponse( | ||
uint runId, | ||
string memory response, | ||
string memory errorMessage | ||
) public onlyOracle { | ||
lastResponse = response; | ||
lastError = errorMessage; | ||
} | ||
|
||
function onOracleKnowledgeBaseQueryResponse( | ||
uint runId, | ||
string [] memory documents, | ||
string memory errorMessage | ||
) public onlyOracle { | ||
string memory newContent = ""; | ||
for (uint i = 0; i < documents.length; i++) { | ||
newContent = string(abi.encodePacked(newContent, documents[i], "\n")); | ||
} | ||
lastResponse = newContent; | ||
lastError = errorMessage; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
import {ethers} from "hardhat"; | ||
|
||
|
||
async function main() { | ||
if (!process.env.ORACLE_ADDRESS) { | ||
throw new Error("ORACLE_ADDRESS env variable is not set."); | ||
} | ||
const oracleAddress: string = process.env.ORACLE_ADDRESS; | ||
await deployTest(oracleAddress); | ||
} | ||
|
||
|
||
async function deployTest(oracleAddress: string) { | ||
const contract = await ethers.deployContract("Test", [oracleAddress], {}); | ||
|
||
await contract.waitForDeployment(); | ||
|
||
console.log( | ||
`Test contract deployed to ${contract.target}` | ||
); | ||
} | ||
|
||
// We recommend this pattern to be able to use async/await everywhere | ||
// and properly handle errors. | ||
main().catch((error) => { | ||
console.error(error); | ||
process.exitCode = 1; | ||
}); |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,133 @@ | ||
import { task } from "hardhat/config"; | ||
import { Contract, TransactionReceipt } from "ethers"; | ||
import { HardhatRuntimeEnvironment } from "hardhat/types"; | ||
import { Func } from "mocha"; | ||
|
||
interface FunctionResponse { | ||
response: string, | ||
error: string, | ||
} | ||
|
||
task("web_search", "Calls the web search function") | ||
.addParam("contractAddress", "The address of the Test contract") | ||
.addParam("query", "The query to ask the contract") | ||
.setAction(async (taskArgs, hre) => { | ||
const contractAddress = taskArgs.contractAddress; | ||
const query = taskArgs.query; | ||
|
||
const contract = await getContract("Test", contractAddress, hre); | ||
const response = await queryContractFunction(contract, "web_search", query, hre); | ||
console.log(response) | ||
if (response.error.length > 0) { | ||
process.exit(1); | ||
} | ||
}); | ||
|
||
task("image_generation", "Calls the image generation function") | ||
.addParam("contractAddress", "The address of the Test contract") | ||
.addParam("query", "The query to ask the contract") | ||
.setAction(async (taskArgs, hre) => { | ||
const contractAddress = taskArgs.contractAddress; | ||
const query = taskArgs.query; | ||
|
||
const contract = await getContract("Test", contractAddress, hre); | ||
const response = await queryContractFunction(contract, "image_generation", query, hre); | ||
console.log(response) | ||
if (response.error.length > 0) { | ||
process.exit(1); | ||
} | ||
}); | ||
|
||
task("code_interpreter", "Calls the code interpreter function") | ||
.addParam("contractAddress", "The address of the Test contract") | ||
.addParam("query", "The query to ask the contract") | ||
.setAction(async (taskArgs, hre) => { | ||
const contractAddress = taskArgs.contractAddress; | ||
const query = taskArgs.query; | ||
|
||
const contract = await getContract("Test", contractAddress, hre); | ||
const response = await queryContractFunction(contract, "code_interpreter", query, hre); | ||
console.log(response) | ||
if (response.error.length > 0) { | ||
process.exit(1); | ||
} | ||
}); | ||
|
||
task("knowledge_base", "Queries a knowledge base") | ||
.addParam("contractAddress", "The address of the Test contract") | ||
.addParam("cid", "The CID of the knowledge base") | ||
.addParam("query", "The query to ask the knowledge base") | ||
.setAction(async (taskArgs, hre) => { | ||
const contractAddress = taskArgs.contractAddress; | ||
const cid = taskArgs.cid; | ||
const query = taskArgs.query; | ||
|
||
const contract = await getContract("Test", contractAddress, hre); | ||
const response = await queryContractKnowledgeBase(contract, cid, query, hre); | ||
console.log(response) | ||
if (response.error.length > 0) { | ||
process.exit(1); | ||
} | ||
}); | ||
|
||
async function getContract( | ||
name: string, | ||
contractAddress: string, | ||
hre: HardhatRuntimeEnvironment | ||
): Promise<Contract> { | ||
const signer = (await hre.ethers.getSigners())[0]; | ||
const ContractArtifact = await hre.artifacts.readArtifact(name); | ||
return new hre.ethers.Contract(contractAddress, ContractArtifact.abi, signer); | ||
} | ||
|
||
async function queryContractFunction( | ||
contract: Contract, | ||
tool: string, | ||
query: string, | ||
hre: HardhatRuntimeEnvironment | ||
): Promise<FunctionResponse> { | ||
try { | ||
const txResponse = await contract.callFunction(tool, query); | ||
await txResponse.wait(); | ||
process.stdout.write("Waiting for response"); | ||
let response = await contract.lastResponse(); | ||
let error = await contract.lastError(); | ||
while (response.length === 0 && error.length === 0) { | ||
await new Promise((resolve) => setTimeout(resolve, 1000)); | ||
response = await contract.lastResponse(); | ||
error = await contract.lastError(); | ||
process.stdout.write("."); | ||
} | ||
console.log(""); | ||
return { response: response, error: error }; | ||
} catch (error) { | ||
console.error(`Error calling contract function: ${error}`); | ||
} | ||
return { response: "", error: "Failed XX"}; | ||
} | ||
|
||
async function queryContractKnowledgeBase( | ||
contract: Contract, | ||
cid: string, | ||
query: string, | ||
hre: HardhatRuntimeEnvironment | ||
): Promise<FunctionResponse> { | ||
try { | ||
const txResponse = await contract.queryKnowledgeBase(cid, query); | ||
await txResponse.wait(); | ||
process.stdout.write("Waiting for response"); | ||
let response = await contract.lastResponse(); | ||
let error = await contract.lastError(); | ||
while (response.length === 0 && error.length === 0) { | ||
await new Promise((resolve) => setTimeout(resolve, 1000)); | ||
response = await contract.lastResponse(); | ||
error = await contract.lastError(); | ||
process.stdout.write("."); | ||
} | ||
console.log(""); | ||
return { response: response, error: error }; | ||
} catch (error) { | ||
console.error(`Error calling contract function: ${error}`); | ||
} | ||
return { response: "", error: "Failed XX"}; | ||
} |