|
| 1 | +# OPAgent: Onchain Perpetual Agent |
| 2 | + |
| 3 | + |
| 4 | + |
| 5 | +To gain a deeper understanding of the OP Agent's design, please refer to [this article](./article.md). |
| 6 | + |
| 7 | +## Prerequisites |
| 8 | + |
| 9 | +Install the dependencies: |
| 10 | +```shell |
| 11 | +npm install |
| 12 | +``` |
| 13 | + |
| 14 | +Prepare your environment: |
| 15 | +```shell |
| 16 | +cp .env.example .env |
| 17 | +``` |
| 18 | +Then, update the `.env` file with your own values. |
| 19 | +```shell |
| 20 | +PRIVATE_KEY=3d59c... |
| 21 | +BASE_MAINNET_RPC=https://... |
| 22 | +ETHERSCAN_API_KEY=XPP8... |
| 23 | +ORA_API_KEY=BASE:5FH4... |
| 24 | +``` |
| 25 | +You can get your `ORA_API_KEY` from [here](https://rms.ora.io/). |
| 26 | + |
| 27 | +## Customize your opAgent |
| 28 | + |
| 29 | +Each opAgent corresponds to a smart contract on the blockchain. |
| 30 | + |
| 31 | +### Create your agent |
| 32 | + |
| 33 | +Create a copy of sample agent and name it "NewAgent". |
| 34 | +```shell |
| 35 | +cp contracts/examples/SimpleAgent.sol contracts/examples/NewAgent.sol |
| 36 | +``` |
| 37 | + |
| 38 | +Inside `contracts/examples/NewAgent.sol`, change name of contract into `NewAgent` or any other name. |
| 39 | + |
| 40 | +```js |
| 41 | +contract NewAgent is OPAgent { |
| 42 | + |
| 43 | + /// @notice Initialize the contract, binding it to a specified AIOracle contract |
| 44 | + constructor(IAIOracle _aiOracle, string memory _modelName, string memory _systemPrompt) OPAgent(_aiOracle, _modelName, _systemPrompt) {} |
| 45 | + |
| 46 | +} |
| 47 | +``` |
| 48 | + |
| 49 | +There are some examples of opAgent shown in `contracts/examples`. |
| 50 | + |
| 51 | +Requirements: |
| 52 | +- You need to specify the contract name in the `contractName` field of the `deploy-config.json` file. |
| 53 | +- The contract name should be the same as the file name of the solidity contract and `contractName` of `deploy-config.json` file. |
| 54 | +- The solidity contract should be located in the `contracts/examples` folder. |
| 55 | + |
| 56 | +### Customization |
| 57 | + |
| 58 | +Take `contracts/examples/SimpleAgent.sol` as an example. |
| 59 | +By inheriting from `OPAgent.sol`, you can get a very simple opAgent onchain. |
| 60 | + |
| 61 | +```js |
| 62 | +contract SimpleAgent is OPAgent { |
| 63 | + |
| 64 | + /// @notice Initialize the contract, binding it to a specified AIOracle contract |
| 65 | + constructor(IAIOracle _aiOracle, string memory _modelName, string memory _systemPrompt) OPAgent(_aiOracle, _modelName, _systemPrompt) {} |
| 66 | + |
| 67 | +} |
| 68 | +``` |
| 69 | + |
| 70 | +In op agent framework, we support highly customized onchain actions. So you can customize your op agent onchain action by writing any solidity function with the `onlyOPAgentCallback` modifier. In this way, we can support various of onchain actions of the opAgent such as trading on DEX, transfering token, and even deploying a new contract. |
| 71 | + |
| 72 | +Take `contracts/examples/TransferAgent.sol` as an example. It inherits from `OPAgent.sol` and implements the `transferETH` function. When the opAgent calls the `transferETH` function, it will transfer the specified amount of ETH to the specified address. |
| 73 | + |
| 74 | +```js |
| 75 | +// SampleContract.sol |
| 76 | +// SPDX-License-Identifier: MIT |
| 77 | +pragma solidity ^0.8.13; |
| 78 | + |
| 79 | +import "../OPAgent.sol"; |
| 80 | + |
| 81 | +contract TransferAgent is OPAgent { |
| 82 | + |
| 83 | + event Transfer(uint256 requestId, address to, uint256 amount); |
| 84 | + |
| 85 | + /// @notice Initialize the contract, binding it to a specified AIOracle contract |
| 86 | + constructor(IAIOracle _aiOracle, string memory _modelName, string memory _systemPrompt) OPAgent(_aiOracle, _modelName, _systemPrompt) {} |
| 87 | + |
| 88 | + /** |
| 89 | + * This function is called by the OP Agent. |
| 90 | + * It transfers the specified amount of ETH to the specified address. |
| 91 | + * |
| 92 | + * @param requestId uint256, the request ID in AI Oracle |
| 93 | + * @param to address, the address to transfer to |
| 94 | + * @param amount uint256, the amount to transfer |
| 95 | + */ |
| 96 | + function transferETH(uint256 requestId, address to, uint256 amount) public onlyOPAgentCallback { |
| 97 | + // transfer ETH to the specified address |
| 98 | + (bool success, ) = to.call{value: amount}(""); |
| 99 | + require(success, "Transfer failed"); |
| 100 | + emit Transfer(requestId, to, amount); |
| 101 | + } |
| 102 | +} |
| 103 | +``` |
| 104 | + |
| 105 | +## Deploy your opAgent |
| 106 | + |
| 107 | +Prepare the configuration file `deploy-config.json` in the `config` folder. |
| 108 | + |
| 109 | +```shell |
| 110 | +cp config/deploy-config.example.json config/deploy-config.json |
| 111 | +``` |
| 112 | + |
| 113 | +Fill in the `deploy-config.json` file with your own values. |
| 114 | +```shell |
| 115 | +{ |
| 116 | + "network": "base", |
| 117 | + "aiOracleAddress": "0x0A0f4321214BB6C7811dD8a71cF587bdaF03f0A0", |
| 118 | + "modelName": "ora/opagent", |
| 119 | + "systemPrompt": "Your system prompt here", |
| 120 | + "contractName": "SimpleAgent", |
| 121 | + "utilsLibAddr": "", |
| 122 | + "opAgentContract": "", |
| 123 | + "isVerified": false |
| 124 | +} |
| 125 | +``` |
| 126 | + |
| 127 | +- network: the blockchain network to deploy your opAgent. We only support `base` now. Don't change it. |
| 128 | +- aiOracleAddress: the address of the AI Oracle contract. Don't change it. |
| 129 | +- modelName: the name of the model. We only support `ora/opagent` now. Don't change it. |
| 130 | +- systemPrompt: the system prompt for the model. You can customize it. If you don't want to customize it, you can leave it empty as "". |
| 131 | +- contractName: the name of your contract. |
| 132 | +- utilsLibAddr: the address of the utils library. If you want to deploy one by yourself, you can leave it empty as "". If you want to use the default utils library, you can leave it as "0xD06CEfaE49f5c92733Bb4dcF1a7b20482E3D2AE3". |
| 133 | +- opAgentContract: the address of your opAgent contract. If you have not deployed it, you can leave it empty as "". After deployment, we will automatically update it. |
| 134 | +- isVerified: whether the opAgent is verified. If you not sure whether it is verified, you should leave it as false. |
| 135 | + |
| 136 | +After the configuration file is prepared, to deploy your agent, you can create your opAgent by running the following command: |
| 137 | +```shell |
| 138 | +npx hardhat run scripts/createAgent.ts |
| 139 | +``` |
| 140 | + |
| 141 | +## On-chain chat |
| 142 | + |
| 143 | +The on-chat chatting functionality is supported by OAO (Onchain AI Oracle). You can learn more about OAO from [here](https://github.com/ora-io/OAO). You can chat with your opAgent on-chain by calling the `singleChat` function in the OPAgent contract. |
| 144 | +```js |
| 145 | + function singleChat( |
| 146 | + string calldata prompt, |
| 147 | + uint64 gaslimit |
| 148 | + ) external payable; |
| 149 | +``` |
| 150 | +The opAgent will respond back through `aiOracleCallback` function. By default, it will call the following function to respond back to the user: |
| 151 | +```js |
| 152 | +function chatRespond( |
| 153 | + uint256 requestId, |
| 154 | + string calldata message |
| 155 | +) public virtual onlyOPAgentCallback { |
| 156 | + emit OPAgentChatResponse(requestId, message); |
| 157 | +} |
| 158 | +``` |
| 159 | +When the opAgent responds with function calling, it will trigger the customized onchain action of the opAgent. |
| 160 | + |
| 161 | +Here is a simple script for you to chat with your opAgent using OAO: |
| 162 | +```shell |
| 163 | +PROMPT="who are u" npx hardhat run scripts/onchainChat.ts |
| 164 | +``` |
| 165 | + |
| 166 | +## Off-chain chat |
| 167 | + |
| 168 | +The off-chain chatting functionality is supported by RMS (Resilient Model Services). You can learn more about RMS from [here](https://rms.ora.io/). For the off-chain chatting, you can get the response by the following command: |
| 169 | + |
| 170 | +Here is a simple script for you to chat with your opAgent through RMS: |
| 171 | +```shell |
| 172 | +npx ts-node ./scripts/offchainChat.ts "who are you?" |
| 173 | +``` |
| 174 | + |
| 175 | +After exporting environment variables, you can also directly chat with your agent with curl: |
| 176 | + |
| 177 | +```shell |
| 178 | +curl -X POST "https://api.ora.io/v1/agents/chat" \ |
| 179 | + -H "Authorization: Bearer $ORA_API_KEY" \ |
| 180 | + -H "Content-Type: application/json" \ |
| 181 | + -d '{ |
| 182 | + "model": "ora/opagent", |
| 183 | + "messages": [{"role": "user", "content": "who are you?"}], |
| 184 | + "registerHash": $registerHash, |
| 185 | + "contractAddress": $opAgentContract |
| 186 | + }' |
| 187 | +``` |
0 commit comments