> ## Documentation Index
> Fetch the complete documentation index at: https://thrackle.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Quickstart

> See the Rules Engine in action in minutes

This QuickStart will guide you through using the Forte Rules Engine in a local [anvil](https://book.getfoundry.sh/anvil/) development environment utilizing the [Forte Rules Engine SDK](https://github.com/forte-service-company-ltd/forte-rules-engine-sdk). Following this guide, you will walk through the entire Forte Rules Engine workflow:

1. Set up your environment
2. Create a policy
3. Integrate and deploy an example contract
4. Apply the policy to the example contract
5. Verify functionality

> ***NOTE:*** This guide was developed in a MacOS environment, some modification may be necessary to suit a Linux/Windows environment.

## 1. Set up your environment

### Environment dependencies

This guide assumes the following tools are installed and configured correctly. Please see each tool's installation instructions for more details:

* [Git](https://git-scm.com/)
* [NodeJS](https://nodejs.org/) - v20.x.x
* [Foundry](https://book.getfoundry.sh/getting-started/installation) - v1.0.0-stable

### Build

Create a copy of our template repository in your own github account by navigating here: [https://github.com/forte-service-company-ltd/fre-quickstart](https://github.com/forte-service-company-ltd/fre-quickstart) and clicking the "Use this template" button on GitHub.

<Frame type="simple">
  <img src="https://mintlify.s3.us-west-1.amazonaws.com/thrackle/images/use-template-gh.jpg" alt="Create new repository from template" />
</Frame>

Next, clone the freshly created repository to your local machine:

```bash
git clone https://github.com/<YOUR_GITHUB_USERNAME>/fre-quickstart
```

<Note>
  If you named the repository something different than `fre-quickstart`, use that name in the clone
  command instead.
</Note>

Navigate to the repository in your local shell. To build the repository, run the following commands:

```shell
npm install
forge install
```

### Start a local Anvil chain

An Anvil [dumpState](https://book.getfoundry.sh/anvil/) file is provided with a pre-deployed Rules Engine instance. Start the local Anvil instance in a terminal window with the following command:

```bash
anvil --load-state anvilState.json
```

`Listening on 127.0.0.1:8545` should be the last thing displayed if the state file was successfuly loaded. Leave this Anvil instance running in this terminal for the rest of the quickstart. It may be restarted at any time but restarting will lose any on-chain progress you've made during the quickstart.

### Configure your local environment

The `.env.sample` environment file contains the values needed to continue this guide. Expand the Accordion below for more information.

<Accordion title="Environment File Details">
  **RPC\_URL** - The RPC endpoint to utilize when interacting with an EVM chain. This is defaulted to a local anvil RPC that is enabled when starting anvil. This can be updated to point to any testnet/mainnet RPC if desired. See [anvil](https://book.getfoundry.sh/anvil/) for more details.

  ```yaml+
  # local anvil RPC, change this if you're deploying to a network
  RPC_URL=http://127.0.0.1:8545
  ```

  **PRIV\_KEY** - The private key for the account that will be performing the actions outlined in this guide. This is defaulted to a widely known default Anvil account for the purposes of this guide. It is recommended that this be updated prior to deploying to any testnet or mainnet.

  ```yaml+
  # local anvil account private key, change to your deployer wallet key when using a live network
  PRIV_KEY=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80
  ```

  **RULES\_ENGINE\_ADDRESS** - The address of the deployed Rules Engine instance on the target RPC's chain. This is defaulted to the address where the Rules Engine was deployed in the anvilState.json file. For additional chain locations, please see the Forte Rules Engine docs.

  ```yaml+
  # address of the rules engine within the anvil state file
  RULES_ENGINE_ADDRESS=0x2279B7A0a67DB372996a5FaB50D91eAA73d2eBe6
  ```
</Accordion>

Copy the sample environment file and then source the file to make those values available in your terminal.

```bash
cp .env.sample .env
```

```bash
source .env
```

<Warning>
  The SDK utilizes the Rules Engine address and private key values from the environment file. This
  requires that you name your file `.env`, which enables the SDK to access the values.
</Warning>

## 2. Create a sample policy

To use the Rules engine, we must first create a [policy](/v2/concepts/policies). A default policy has been written for you within the [policy.json](https://github.com/forte-service-company-ltd/fre-quickstart/blob/main/policy.json) that is tailored to work with the [ExampleContract](https://github.com/forte-service-company-ltd/fre-quickstart/blob/main/src/ExampleContract.sol). To create this policy in the Rules Engine, run the following command:

<CodeGroup>
  ```bash command
  npx tsx index.ts setupPolicy policy.json
  ```

  ```json policy.json
  {
    "Policy": "Test Policy",
    "PolicyType": "open",
    "ForeignCalls": [],
    "Trackers": [
      {
        "name": "trackerOne",
        "type": "uint256",
        "initialValue": 1
      }
    ],
    "Rules": [
      {
        "condition": "value > 10000",
        "positiveEffects": ["emit TransferSuccessful"],
        "negativeEffects": ["revert(\"Transfer Failed\")"],
        "callingFunction": "transfer(address to, uint256 value)",
        "encodedValues": "address to, uint256 value"
      }
    ]
  }
  ```
</CodeGroup>

Note the returned Policy Id, for this example the Policy Id should be 1, and create a local environment variable to store this Id for uses in subsequent commands:

```bash
export POLICY_ID=1
```

This policy now exists, but no contracts are yet subscribed to it.

## 3. Integrate and deploy an example contract

The [ExampleContract](https://github.com/forte-service-company-ltd/fre-quickstart/blob/main/src/ExampleContract.sol) is a blank contract that conforms to a standard ERC20 interface transfer() function. The file does not store any data. The integration of the Rules Engine occurs by adding a modifier. This modifier may be generated by passing the policy information, destination modifier filename, and the example contract to the SDK. The SDK will process the policy, generate modifiers within the specified modifier file for each function within the Policy, and inject these newly generated modifiers within the supplied contract. This has been scripted in the index.ts with the following command:

```bash
npx tsx index.ts injectModifiers policy.json src/RulesEngineIntegration.sol src/ExampleContract.sol
```

After running this command, it will inject the beforeXXX() modifier within the function specified within the policy.json file. Verify the contract compiles and deploy the contract with the following commands:

```bash
forge script script/ExampleContract.s.sol --ffi --broadcast -vvv --non-interactive --rpc-url $RPC_URL --private-key $PRIV_KEY
```

Note the contract address, and export the address in your local terminal for subsequent testing.

```bash
export CONTRACT_ADDRESS=<0xYourContractAddress>
```

## 4. Apply the policy to the example contract

The ExampleContract extends the [RulesEngineClient](https://github.com/forte-service-company-ltd/forte-rules-engine/blob/main/src/client/RulesEngineClient.sol) to encapsulate storing the Rules Engine address and checks. It is recommended that all calling contracts extend this contract. This ensures calling contracts will only invoke the Rules Engine checks if the Rules Engine Address is specified. Set the Rules Engine Address in the ExampleContract via the following command:

First, we need to set the Rules Engine Address for the ExampleContract.

```bash
cast send $CONTRACT_ADDRESS "setRulesEngineAddress(address)" $RULES_ENGINE_ADDRESS --rpc-url $RPC_URL --private-key $PRIV_KEY
```

To verify the address was set correct, the following commmand should return the same Rules Engine Address:

```bash
cast call $CONTRACT_ADDRESS "rulesEngineAddress()(address)" --rpc-url $RPC_URL
```

Next, you need to set the Calling Contract Admin:

```bash
cast send $CONTRACT_ADDRESS "setCallingContractAdmin(address)" $USER_ADDRESS --rpc-url $RPC_URL --private-key $PRIV_KEY
```

The last thing to do is to subscribe our example contract to the Policy we created.

```bash
npx tsx index.ts applyPolicy $POLICY_ID $CONTRACT_ADDRESS
```

## 5. Verify Functionality

### Test Success Condition

```bash
cast send $CONTRACT_ADDRESS "transfer(address,uint256)" 0x70997970C51812dc3A010C7d01b50e0d17dc79C8 10001 --rpc-url $RPC_URL --private-key $PRIV_KEY
```

You should receive a successful transaction!

### Test Failure Condition

```bash
cast send $CONTRACT_ADDRESS "transfer(address,uint256)" 0x70997970C51812dc3A010C7d01b50e0d17dc79C8 9999 --rpc-url $RPC_URL --private-key $PRIV_KEY
```

You should receive a revert with the text "Failed Test"
