# Referral Design Pattern

## Intro

**Referrals**

One way to use XP Protocol is as an on-chain **Referral System**. This design encourages your users to refer new users to your platform/protocol.

A referral is said to be "attributed" to the person who brought the new user in.&#x20;

The key to setting this up correctly while ensuring it does not get gamed is to tap into the unique identifier of a **updateScore()** transaction.

{% hint style="info" %}
updateId: Is a unique identifier that must be sent with each updateScore() transaction. This transaction is Deduped on-chain to prevent attacks.
{% endhint %}

```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 attributedAddress = "0xa6869c3001de171c26418e9e2eedca1c0d763ee2";
 let newUserAddress = "0x0baBda04f62C549A09EF3313Fe187f29c099FF3C";
 let updateId = "referral:"+attributedAddress+":"+newUserAddress;
 updateId = '0x' + sha256(updateId).toString(); // 0x to signify its a bytes32
  //Send to API
    const body = JSON.stringify({
        "updateId": updateId,
        "projectId": "0xadb591795f9e9047f9117163b83c2ebcd5edc4503644d59a98cf911aef0367f8",
        "actionName": "referral",
        "scoreType": "social",
        "targetWallet": attributedAddress,
        "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() }));

```

Notice this particular line below:

```javascript
 let updateId = "referral:"+attributedAddress+":"+newUserAddress
```

This line sets the **updateId** to a concatenation of the two user addresses involved in this score update.&#x20;

The simplicity in this line is that as a developer you do not need to worry about checking to see if a user has already gotten a reward for referring that particular user. This means there is no state management or querying that needs to happen before you fire off a score update.

The deduping will happen on-chain, each score update is **Idempotent**.

Idempotence is a key differentiator with XP Protocol which allows developers to bypass complexity in storying and tracking referrals.

That's it!
