> For the complete documentation index, see [llms.txt](https://read.roke.to/roketo-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://read.roke.to/roketo-docs/infrastracture/r2-interchain-incentivisation/r2-integration-guide.md).

# R2: Integration Guide

## R2 Beacon Integration Guide for DApp Developers

### Overview

R2 Beacon is an omni-chain identity system that tracks and scores user activities across different blockchains. By integrating R2 Beacon into your DApp, you enable "business-aware" actions that contribute to users' identity scores while maintaining privacy and security.

> **Note**: Business-aware actions provide context about user interactions, making them more meaningful than raw transaction data. For example, instead of just recording a transfer of 0.1 ETH, you can specify that a user purchased a subscription.

### Prerequisites

* Solidity ^0.8.24
* An APP\_ID registered with R2 Registry
* Basic understanding of smart contract development

### Quick Start

1. Install the R2 Beacon contract:

```bash
npm install @r2-beacon/contracts
# or
yarn add @r2-beacon/contracts
```

2. Import and inherit the R2BeaconEmitter contract:

```solidity
import {R2BeaconEmitter} from "@r2-beacon/contracts/R2BeaconEmitter.sol";

contract YourDApp is R2BeaconEmitter {
    constructor(bytes32 appId) R2BeaconEmitter(appId) {}
}
```

### Implementation Guide

#### Basic Integration

1. First, inherit from the R2BeaconEmitter contract:

```solidity
contract GameMarketplace is R2BeaconEmitter {
    constructor(bytes32 appId) R2BeaconEmitter(appId) {}
}
```

#### Defining Business Actions

Define constants for your business actions using the `_createActionId` helper or direct `keccak256` hashing:

```solidity
contract GameMarketplace is R2BeaconEmitter {
    bytes32 public constant PURCHASE_ITEM = keccak256("PURCHASE_ITEM");
    bytes32 public constant START_SUBSCRIPTION = keccak256("START_SUBSCRIPTION");
    bytes32 public constant COMPLETE_ACHIEVEMENT = keccak256("COMPLETE_ACHIEVEMENT");

    constructor(bytes32 appId) R2BeaconEmitter(appId) {}
}
```

#### Emitting Actions

Use the `_emitR2Action` function to record business-aware actions:

```solidity
function purchaseGameItem(uint256 itemId) external payable {
    require(msg.value >= getItemPrice(itemId), "Insufficient payment");
    
    // Your item purchase logic here
    
    _emitR2Action(
        PURCHASE_ITEM,
        msg.value,
        abi.encode(itemId)
    );
}

function startSubscription(uint256 durationInDays) external payable {
    require(msg.value >= getSubscriptionPrice(durationInDays), "Insufficient payment");
    
    // Your subscription logic here
    
    _emitR2Action(
        START_SUBSCRIPTION,
        msg.value,
        abi.encode(durationInDays)
    );
}
```

### Configuration

The R2BeaconEmitter interface accepts the following parameters when emitting actions:

| Parameter | Type    | Description                           | Required |
| --------- | ------- | ------------------------------------- | -------- |
| action    | bytes32 | Identifier for the business action    | Yes      |
| amount    | uint256 | Value/amount involved in the action   | Yes      |
| data      | bytes   | Additional context data (ABI encoded) | No       |

### API Reference

#### Core Functions

**\_emitR2Action**

```solidity
function _emitR2Action(
    bytes32 action,
    uint256 amount,
    bytes calldata data
) internal virtual
```

Emits a business-aware action to the R2 Beacon system.

**\_createActionId**

```solidity
function _createActionId(
    string calldata actionName
) internal pure returns (bytes32 actionId)
```

Utility function to create action identifiers from strings.

#### Events

**R2Action**

```solidity
event R2Action(
    address indexed user,
    bytes32 indexed appId,
    bytes32 indexed action,
    uint256 amount,
    bytes data
);
```

### Common Issues & Solutions

#### 1. Invalid APP\_ID

**Issue**: Contract deployment fails with `R2Beacon_InvalidAppId`

**Solution**: Ensure you've registered your DApp with R2 Registry and are using the correct APP\_ID:

```solidity
// Incorrect
bytes32 appId = bytes32(0); // Will revert

// Correct
bytes32 appId = bytes32(uint256(keccak256("YOUR_APP_NAME")));
```

#### 2. Action Not Registered

**Issue**: Actions aren't appearing in the R2 Beacon

**Solution**: Verify that your action identifiers are properly registered:

```solidity
// Incorrect
_emitR2Action(bytes32(0), amount, data); // Will revert

// Correct
bytes32 constant MY_ACTION = keccak256("MY_ACTION");
_emitR2Action(MY_ACTION, amount, data);
```

#### 3. Data Encoding Issues

**Issue**: Action data is not properly decoded

**Solution**: Always use `abi.encode` for complex data types:

```solidity
// Incorrect
bytes memory data = bytes(abi.encodePacked(value1, value2));

// Correct
bytes memory data = abi.encode(value1, value2);
```

> **Warning**: Never include sensitive user data in the `data` parameter. The R2 Beacon is public, and all emitted data will be visible on-chain.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://read.roke.to/roketo-docs/infrastracture/r2-interchain-incentivisation/r2-integration-guide.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
