Installing the Rayls SDK
Prerequisites
The SDK must be installed in a project targeting a Rayls Sovereign ledger, meaning an EVM-compatible chain with a Rayls endpoint smart contract configured.
For questions, contact Rayls 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 that you inherit in order to build tokens and cross-chain apps in a Rayls Sovereign ledger:
| Contract | Purpose |
|---|---|
RaylsApp | Base for all cross-chain apps, providing _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 | Endpoint for cross-Sovereign messaging |
_raylsNodeEndpoint | Endpoint for Public Chain bridging |
_userGovernance | RBAC contract for user roles within Rayls Sovereign |
_owner | Address granted the Owner role (mint, burn) |
Token registration
After deploying, call registerToken on the TokenRegistryReplica system contract in the Rayls Sovereign ledger:
TokenRegistryReplica.registerToken(tokenAddress, SharedObjects.ErcStandard.ERC20, false)Once the Private Network Operator approves it, the relayer calls receiveResourceId() on your contract automatically, and the teleport functions are then 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, which is role-based access control. The Owner role is granted to the address passed as _owner at deployment.
Access control: Rayls uses
RaylsAccessManagedrather thanOwnable. Privileged functions use therestrictedmodifier, which checks roles throughRaylsAccessManagerV1in the Rayls Sovereign ledger. There is noonlyOwnerin the current SDK.
Teleporting tokens
Vanilla teleport (VT20)
Burns on source, mints on destination, with no revert mechanism.
function teleport(address to, uint256 value, uint256 chainId) public virtual returns (bool)Atomic teleport (AT20)
Tokens are locked on the destination until the transfer is confirmed. Where the destination fails, the relayer reverts the operation and returns the tokens to the sender.
function teleportAtomic(address to, uint256 value, uint256 destinationChainId) public virtual returns (bool)Sending arbitrary messages
For custom cross-chain logic that does not 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 in their own Rayls Sovereign ledger and the receiver deploys it in theirs. The sender then calls sendGreeting with the receiver's chain ID and contract address, and the relayer delivers the payload and calls receiveGreeting on the receiver.
Security: Receive functions should be marked
restrictedin production so that only the Rayls relayer (MESSAGE_EXECUTOR role) can invoke them. See RaylsApp for details.
Updated 17 days ago
