# IE commands [`IE`](https://github.com/NaniDAO/ie) is a natural language router for Ethereum transactions. This means you can send plain text *strings* and the IE smart contract will convert these requests into calldata and provide execution methods, as well, such as pulling tokens or ETH from the caller account to complete a swap or transfer. These commands are labeled as `intents` in the `command()` function like so: ```solidity function command(string calldata intent) public payable virtual { . . . } ``` ## IE for LLM Agents IE provides a simple function calling capability for LLM Agents and other user-facing bots. Rather than rely on offchain code which may have unreliable runtime guarantees or errors, IE is deterministic in how it translates common text commands into calldata. For example, users are guaranteed that the calldata produced by "send 1 ETH to [0xaddress]" will always return the same output. Users can therefore trust IE to complete essential financial functions while relying on the economic security of Ethereum. Decimal conversion among different types of assets is also hardcoded into the IE smart contract, such that 18 decimals are always assigned to ETH or DAI, for example, and 8 for wBTC and 6 for USDT, respectively. LLMs are positioned well to take in more complicated requests and summarize them into their correct IE command syntax, such that a prompt like "I am thinking of sending a hundred dollars to bob" might be summarized and then sent onchain as "send bob 100 USDC" or "send 100 USDC to bob".* ### Agent Command Examples #### Transfer "*send* **0.0000001 ETH** to `0xDa000000000000d2885F108500803dfBAaB2f2aA`" "*transfer* `0xDa000000000000d2885F108500803dfBAaB2f2aA` **100 USDC**" "*pay* **0.01 bitcoin** to `z0r0z`" "*grant* **10000 DAI** to `nani`" As you can see, the following transfer action keywords are as follows: `send`, `transfer`, `pay`, `grant`. Generally, the shortest action should be used to save gas unless reflecting the breadth of the intent onchain is more important (for example, to solidify the understanding that something is a grant or donation for accounting or legal purposes). **Note:* On L1, IE natively uses ENS domains. On L2, full addresses should be used unless the domain has been registered (this will be rolled out in phases). #### Swap "*swap* **1 bitcoin** for **ether**" "*swap* **1 wBTC** for **ETH**" "*swap* **0.01 ETH** to **400 DAI**" As you can see the user can also request a specific minimum output of their swap. Currently IE assumes the user has an input amount in mind. Later versions will include more granular swapping commands. ### Command Preview IE provides a granular preview of command calldata based on a provided string input in the IE function `previewCommand(string calldata intent)`. In this case, a command of "send 0.00001 ether to z0r0z" will return the output arguments of: ``` to: 0x1C0Aa8cCD568d90d61659F060D1bFb1e6f855A20 amount: 10000000000000 minAmountOut: 0 token: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE callData: executeCallData: 0xb61d27f60000000000000000000000001c0aa8ccd568d90d61659f060d1bfb1e6f855a20000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000 ``` ### Command Translation IE also supports the reverse capability of *transaction-to-text*. Meaning that you can input raw calldata and return a human-readable string explaining the user intent in the preferred IE command syntax. In order to do so, input the calldata representation of a command into the IE function `translateCommand(bytes calldata callData)` which will then return the equivalent string. For example, the long-form and raw bytes of `0x5fcc45000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001a73656e6420302e303030303120657468657220746f206e616e69000000000000` dutifully returns `send 0.00001 ether to nani`. ### userOp Checks IE also anticipates that many user accounts will be smart contracts that follow ERC-4337. In order to provide an onchain safeguard convenience, users can input their structured userOp and their expected equivalent command intent string, and receive a boolean that confirms whether they match. The code is excerpted below as it most clearly showcases this functionality (and which functionality is natively supported on the [nani.ooo](https://nani.ooo/) app): ```solidity /// @dev Checks ERC4337 userOp against the output of the command intent. function checkUserOp(string calldata intent, UserOperation calldata userOp) public view virtual returns (bool intentMatched) { (,,,,, bytes memory executeCallData) = previewCommand(intent); if (executeCallData.length != userOp.callData.length) return false; return keccak256(executeCallData) == keccak256(userOp.callData); } /// @dev Checks packed ERC4337 userOp against the output of the command intent. function checkPackedUserOp(string calldata intent, PackedUserOperation calldata userOp) public view virtual returns (bool intentMatched) { (,,,,, bytes memory executeCallData) = previewCommand(intent); if (executeCallData.length != userOp.callData.length) return false; return keccak256(executeCallData) == keccak256(userOp.callData); } ```