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
Install the R2 Beacon contract:
npm install @r2-beacon/contracts
# or
yarn add @r2-beacon/contracts
Import and inherit the R2BeaconEmitter contract:
import {R2BeaconEmitter} from "@r2-beacon/contracts/R2BeaconEmitter.sol";
contract YourDApp is R2BeaconEmitter {
constructor(bytes32 appId) R2BeaconEmitter(appId) {}
}
Implementation Guide
Basic Integration
First, inherit from the R2BeaconEmitter contract:
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:
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:
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:
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
function _emitR2Action(
bytes32 action,
uint256 amount,
bytes calldata data
) internal virtual
Emits a business-aware action to the R2 Beacon system.
_createActionId
function _createActionId(
string calldata actionName
) internal pure returns (bytes32 actionId)
Utility function to create action identifiers from strings.
Events
R2Action
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:
// 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:
// 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:
// 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.
Last updated