Introducion

To unleash the power of the rules engine, the data used to determine rule outcomes must be onchain. The O2 API eanbles you to programmatically push off-chain data onchain in a reliable way. No need to to build and maintain the infrastructure yourself.

The potential reasons are many, however to make it more concrete let’s cover an example.

Consider a trading card game where each card is an NFT. As you utilize these cards in battle they are leveled up, unlocking new attacks, but the card level is stored in offchain metadata. New players are granted a starter pack of these cards to begin playing. Your game has a marketplace to enable players to buy and sell new cards and build out their deck.

The crux is that you only want the starter NFTs to be tradeable once they’ve reached a particular level to ensure players are actually participating in the game before they are able to sell their gifted NFTs.

As it stands now this rule isn’t possible because the level of the card is not readable onchain. Time to bring it onchain!

Prerequisites

You will need an account in the O2 Oracle dashboard to complete this guide.

Create Your Property List

The O2 Oracle API deploys a smart contract to store the data you need onchain to power rules. Once you’re logged into the O2 Dashboard, navigate to an existing app or create a new one.

Once you’ve selected your app, create the property list to store card level data. Select the Create Property List button to proceed.

Now, it’s time to setup a property to hold the card level data. As you can see below the best index type for this is uint256 which represents the tokenId of the specific NFT that has leveled up. The level property is also set as the uint256 type because it will store a simple integer indicating the level of that card.

When you save the property and return to the listview you’ll notice the status is draft. In this example you can go ahead and publish. As you develop more sophisticated property lists you can delay publishing until all of your properties have been drafted and fine tuned.

Now you have an onchain place to store card level data! Next, you’ll learn how to add items to this list that can be used in the evaluation of rules.

Push Data Onchain

You can use the same dashboard to add data to the property list, which is useful for quick testing. Let’s look into how to add an item to the property list via API since that best fits the example scenario.

Pushing data onchain is a two step process. First, you create the new property list item. Then you publish the data onchain. This enables you to batch the updates you actually push onchain, potentially saving on gas.

The example below will create one new property list item. You can pass multiple rows as well in a single call.

The index value passed for the row items should match the tokenId of the NFT card you intend to level up. In the example below, the tokenId is 333.

const appId = "your-app-id";
const propListId = "your-prop-list-id";
const accessToken = "your-access-token";

const addPropertyListItem = async () => {
  const response = await fetch(
    `https://sandbox.api.o2-oracle.io/apps/${appId}/propertylists/${propListId}/rows`,
    {
      method: "PATCH",
      headers: {
        "Content-Type": "application/json",
        Authorization: `Bearer ${accessToken}`,
      },
      body: JSON.stringify({
        operation: "create",
        rows: {
          333: {
            level: 6,
          },
        },
      }),
    }
  );
  console.log(await response.json());
};

addPropertyListItem();

A succcessful response will look like so:

{
  "status": "success",
  "data": {
    "operationId": "operation-uuid"
  }
}

Updating NFT Card Level

The section above can also be used to guide you through updating the card level over time. In fact, you can still pass the create value for the operation property and if the index/tokenId matches your change will be reflected. You will still need to publish those changes, which is outlined below.

Publishishing Properties Onchain

When you’re ready to publish your property list item changes, a single API call will push staged items and make them available for onchain consumption.

const appId = "your-app-id";
const propListId = "your-prop-list-id";
const accessToken = "your-access-token";

const publishPropertyListItems = async () => {
  const response = await fetch(
    `https://sandbox.api.o2-oracle.io/apps/${appId}/propertylists/${propListId}/publish`,
    {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        Authorization: `Bearer ${accessToken}`,
      },
    }
  );
  console.log(await response.json());
};

publishPropertyListItems();

This final call to publish the data onchain will return a JSON response similar to:

{
  "id": "uuid",
  "entity_id": "entity-uuid",
  "entity_type": "property_list",
  "operation_type": "publish",
  "status": "pending"
}

Wrapping Up

Now you’re ready to push your offchain data onchain and make it available for rules evaluations! The next step from here is to actually leverage this onchain data in a rule, which is covered in the next guide. See you there!