Installing the Rayls SDK
Prerequisites
The SDK must be installed in a project targeting a Rayls Privacy Node \u2014 an EVM-compatible chain with a Rayls endpoint smart contract configured.
If you have any questions, contact us here.
Installation
# npm
npm install @rayls/contracts
# pnpm
pnpm add @rayls/contractsCurrent version: 2.6.3-nightly.2
All contracts must use the fixed pragma:
pragma solidity 0.8.24;What the SDK provides
The SDK is a set of abstract Solidity contracts you inherit to build tokens and cross-chain apps on Rayls Privacy Nodes:
| Contract | Purpose |
|---|---|
RaylsApp | Base for all cross-chain apps — provides _raylsSend and _raylsSendToResourceId |
RaylsErc20Handler | ERC20 token with teleport support |
RaylsErc721Handler | ERC721 NFT with teleport support |
RaylsErc1155Handler | ERC1155 multi-token with teleport support |
RaylsEnygmaHandler | Enygma settlement token with batch cross-chain transfers and DvP |
RaylsErc721DvpHandler | ERC721 DvP asset-leg handler |
RaylsErc1155DvpHandler | ERC1155 DvP asset-leg handler |
See Building using Rayls SDK for the full contract reference.
Setting up a token
Extend RaylsErc20Handler and pass all required params to the parent constructor:
// SPDX-License-Identifier: MIT
pragma solidity 0.8.24;
import "@rayls/contracts/tokens/RaylsErc20Handler.sol";
contract MyToken is RaylsErc20Handler {
constructor(
string memory _name,
string memory _symbol,
address _endpoint,
address _raylsNodeEndpoint,
address _userGovernance,
address _owner
)
RaylsErc20Handler(
_name,
_symbol,
_endpoint,
_raylsNodeEndpoint,
_userGovernance,
_owner,
false // isCustom: false for standard tokens
)
{
// optional: mint initial supply
// _mint(msg.sender, 1_000_000 * 10 ** 18);
}
}The constructor parameters:
| Parameter | Description |
|---|---|
_endpoint | Privacy Node endpoint for cross-PN messaging |
_raylsNodeEndpoint | Endpoint for Public Chain bridging |
_userGovernance | RBAC contract for user roles within the PN |
_owner | Address granted the Owner role (mint, burn) |
Token registration
After deploying, call registerToken on the Privacy Node's TokenRegistryReplica system contract:
TokenRegistryReplica.registerToken(tokenAddress, ErcStandard.ERC20, false)Once the Private Hub operator approves it, the relayer calls receiveResourceId() on your contract automatically. After that, teleport functions are ready to use.
Minting tokens
// Owner role only — also notifies the Private Hub's TokenRegistry
function mint(address to, uint256 value) public virtual restrictedmint and burn are protected by restricted (role-based access control). The Owner role is granted to the address passed as _owner at deployment.
Access control: Rayls uses
RaylsAccessManagedinstead ofOwnable. Privileged functions use therestrictedmodifier, which checks roles via the Privacy Node'sRaylsAccessManagerV1. There is noonlyOwnerin the current SDK.
Teleporting tokens
Vanilla teleport (VT20)
Burns on source, mints on destination. No revert mechanism.
function teleport(address to, uint256 value, uint256 chainId) public virtual returns (bool)Atomic teleport (AT20)
Tokens are locked on destination until confirmed. If the destination fails, the relayer reverts and returns tokens to sender.
function teleportAtomic(address to, uint256 value, uint256 destinationChainId) public virtual returns (bool)Sending arbitrary messages
For custom cross-chain logic that doesn't involve tokens, extend RaylsApp directly:
// SPDX-License-Identifier: MIT
pragma solidity 0.8.24;
import "@rayls/contracts/RaylsApp.sol";
contract HelloWorldContract is RaylsApp {
string public message;
constructor(
address _endpoint,
address _raylsNodeEndpoint,
address _userGovernance
) RaylsApp(_endpoint, _raylsNodeEndpoint, _userGovernance) {}
function sendGreeting(uint256 destChainId, address destContract, string memory _msg) external {
_raylsSend(
destChainId,
destContract,
abi.encodeWithSignature("receiveGreeting(string)", _msg)
);
}
// In production: mark restricted and register selector under MESSAGE_EXECUTOR
function receiveGreeting(string memory _msg) public {
message = _msg;
}
}The sender deploys this contract on their Privacy Node, the receiver deploys it on theirs. The sender calls sendGreeting with the receiver's chain ID and contract address. The relayer delivers the payload and calls receiveGreeting on the receiver.
Security: Receive functions should be marked
restrictedin production so only the Rayls relayer (MESSAGE_EXECUTOR role) can invoke them. See RaylsApp for details.
Updated 15 days ago
