# X-to-Earn Design Pattern

## Intro

It's now common practice to reward your users/fans/following for positive behavior. Game-to-earn, Social-to-earn and even Step-to-earn takes only minutes to set up on XP Protocol.

The key to this design pattern is in the Idompotency of the **updateId** parameter of the **updateScore()** method.

### Repeatable Actions

{% hint style="info" %}
Great for use with "Liked", "Saved", and "Posted". Types of Actions that a user should perform regularly
{% endhint %}

Below is a great example of an **updateId** for an action that a user will do often. Notice how the string remains static except for the last edition of the unix time.&#x20;

The Unix time in milliseconds attached to the end of the string will ensure that this updateId will always change each time a user performs that action.

```javascript
Let updateId = "<actionName>:<non-checksum-address>:<UnixTimeSinceEpoch>"
```

### Full Example

```javascript
let myHeaders = new Headers();
let message = Date.now().toString();
let signatureObject = await web3.eth.accounts.sign(message, <PRIVATE_KEY>); //Private key of a wallet that is either an Updater or an Owner of the current project.
let signature = signatureObject.signature;

//Headers
myHeaders.append("X-API-KEY","<key>");
myHeaders.append("Content-Type", "application/json");
 
 let targetAddress = "0xa6869c3001de171c26418e9e2eedca1c0d763ee2";
 let updateId = "liked:"+targetAddress+":"+Date.now().toString();
 updateId = '0x' + sha256(updateId).toString(); // 0x to signify its a bytes32
  //Send to API
    const body = JSON.stringify({
        "updateId": updateId,
        "projectId": "0xadb591795f9e9047f9117163b83c2ebcd5edc4503644d59a98cf911aef0367f8",
        "actionName": "liked",
        "scoreType": "social",
        "targetWallet": targetAddress,
        "signature": signature,
        "message": message
    })
    const requestOptions = {
        method: 'POST',
        headers: myHeaders,
        body: body,
        redirect: 'follow'
    };
    
    let response = await fetch('https://api.xp-protocol.io/update-score, requestOptions).then(async (response) => ({ status: response.status, value: await response.text() }));
```

### Semi-Repeatable Actions (time-based)

Sometimes you will also want to reward your users for time based actions, such as a "Daily Login".

Typically as a developer, you would have to track each day that your users log in and ensure that you do not accidentally give them that reward more than once in a 24h period.

Because XP has built-in Dedupe capabilities, you no longer need to keep track of that.

This can be achieved with **"Semi-Repeatable Actions",** this design again simply relies on how we construct the **updateId.**

```javascript
let dateNow = new Date();
let dayNumberSinceEpoch = (Math.floor(dateNow / 8.64e7)).toString();
let updateId = '0x' + await sha256('dailyLogin:'+ targetAddress + ':' + dayNumberSinceEpoch);
```

Notice how the <mark style="color:purple;">**dayNumberSinceEpoch**</mark> will change every 24h. This allows you as a developer to not worry about storing and tracking the reward, you can simply let an updateScore() transaction fire upon a "Login" event on your platform, and know that it will only be counted toward that user's score every 24h.
