πŸš€ Getting started

Estimated time to complete this guide: less than 10 minutes

Rockside relayer is a non-custodial transaction delivery service. When sending a transaction to Rockside, you provide:

  • the gas price limit which is the maximum price you want to apply to the transaction

  • a chosen speed of inclusion in the blockchain

We make sure your transaction is then executed at the best price in respect to the delay.

What problem are we solving?

Including transactions in Blockchain can be difficult and it hurts the user experience. Gaseless transactions are a good way to improve this, but their implementation is complex. To solve this problem, developers overpay transactions and must remain on-call to unblock them.

Our solution is a new approach to deal with this situation.

Transaction Relay overview

Relay overview

For more details go on transaction relay page.

How does it work?

Depending on your given gas price limit, your requested speed and the current market gas prices, we decide whether or not to relay your transaction.

Once accepted, we ensure your transaction is validated at the best price at your speed.

  • API and SDK: Send your transactions using our API and open source SDK (JS, iOS)

  • Speed: available speeds are safelow (around 30 minutes), average or standard(around 5 minutes), fast (around 2 minutes), fastest (around 30 seconds)

  • Gas price limit: Maximum gas price value in wei, you are willing to apply to your transaction.

  • Meta-transactions: To relay your transactions we use the concept of meta-transactions, wrapping your signed message in a new transaction. More on meta-transactions page.

  • Gasless transaction: Thanks to meta-transactions, Rockside allows you to pay gas fees for your DApp's users. They no longer need ethers to interact with your DApp.

  • Transaction auto replay: We monitor your transaction and we replace it with one with a higher gas price when necessary to validate your transaction according to your requested speed. More on transaction replay page.

  • Pool of signers: We manage a pool of signers with a multi-dimensionnal replay protection to guarantee no stuck transactions.

  • Transaction batch You can group your transactions in a batch. You then have an atomic operation and your transactions will be executed on chain within a single transaction.

  • Tracking ID: When sending a transaction to Rockside, we also provide you with its tracking ID. Use it to have the latest and automatically updated status of your transaction even in case of replays and other actions taken.

Getting Started

Connect to Rockside

Go to dashboard.rockside.io and connect using your github account. You will get your API key that will allow you to access our API.

Deploy your Forwarder

To relay your transaction, you need to deploy a Forwarder contract. Rockside covers transaction fees (gas) for this operation.

You must specify an owner account. Only the owner can transfer funds from the Forwarder contract.

By default forwarders only accept transactions coming from Rockside signers. Only the owner can modify the list of authorized senders.

To deploy a forwarder execute this request:

curl --request POST 'https://api.rockside.io/ethereum/ropsten/forwarders' \
--header 'apikey: YOUR_API_KEY' \
--header 'Content-Type: application/json' \
--data '{"owner": "YOUR_OWNER_ADDRESS"}'

You get:

{
"address": "0xa83E94cA4A9D92009C1Bf6dCA54b3E34D4463138",
"transaction_hash": "0x6663a81a1a827c4bf2301eb169de900c51d2b6e4e2c26d503dce10888f8cdee9",
"tracking_id": "01E9ZSDHMYYFMW3E1CVQ9ADVHK"
}

Send ether to your Forwarder

Because the forwarder will payback for the transaction fees it needs to be funded in ether.

On Ropsten, we fund your forwarder with 0.01 ETH when it's deployed. When your credit is consumed you have to fund it by sending ether to your Forwarder contract address.

Create your relay message

As an example, let's call a smart contract that simply stores the address of the account that signed the relay message.

The contract is deployed at: 0x9DF66f93374117EFac8349151fE607F5347F5895 on the Ropsten network.

We create a node project to be able to build the relay message.

npm init

Install Rockside Wallet SDK

npm install @rocksideio/rockside-wallet-sdk

On index.js add:

const Wallet = require('@rocksideio/rockside-wallet-sdk/lib/wallet.js')
const Hash = require('@rocksideio/rockside-wallet-sdk/lib/hash.js')
const Web3 = require('web3')
​
const web3 = new Web3()
​
const wallet = Wallet.BaseWallet.createRandom();
​
const voteContractAddress = "0xFb428d37AcC708F37A40c8D95d723e1Aea49cc07"
const voteContractABI = [{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"no","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"value","type":"bool"}],"name":"vote","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"yes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]
​
var voteContract = new web3.eth.Contract(voteContractABI, voteContractAddress)
​
const messageData = voteContract.methods.vote(true).encodeABI();
​
const domain = { chainId: 3, verifyingContract: 'YOUR_RELAYER_ADDRESS' };
​
const metatx = {
signer: wallet.getAddress(),
to: voteContractAddress,
data: messageData,
nonce: 0,
};
​
const hash = Hash.executeMessageHash(domain, metatx);
wallet.sign(hash).then((value) => {
console.log("Message Signer: "+wallet.getAddress())
console.log("Message To: "+voteContractAddress)
console.log("Message Data: "+messageData)
console.log("Signature: "+value)
​
});

Run the script

node index.js

You get:

Message Signer: 0x857782111AFbC67c6338547854D4Db307F748B60
Message To: 0xFb428d37AcC708F37A40c8D95d723e1Aea49cc07
Message Data: 0x4b9f5c980000000000000000000000000000000000000000000000000000000000000001
Signature: 0x48df3199c6ac37c4773a917980c1095b100a75a57a279037d03f1a0190781282131aaa54f533205b8f01ff5bddebf6be5e36ed2a73d9dd3a970b4ad2c14b5d8c1c

Keep those two parameters, you will use it to call Rockside API.

Relay your transaction

To use Rockside API, you need to provide a speed and a gas price limit.

Available speeds are:

  • safelow (around 30 minutes)

  • average/standard (around 5 minutes)

  • fast (around 2 minutes)

  • fastest (around 30 seconds)

Depending on your choice, you have to specify your gas price limit. It defines the maximum gas price you agree to pay to execute your transaction at the requested speed.

If you want to have an idea of the price to provide you can use EthGasStation.

EthGasStation

Note: EthGasStation gas prices are provided on Gwei on their front page, and as 10xGwei when using their API. Make sure to convert it to wei before sending the value to Rockside (ex: 39 Gwei -> 39000000000 Wei)

Let's use curl to relay your transaction:

curl --request POST 'https://api.rockside.io/ethereum/ropsten/forwarders/FORWARDER_ADDRESS' \
--header 'apikey: YOUR_API_KEY' \
--header 'Content-Type: application/json' \
--data '{
"speed": "average",
"gas_price_limit": "19000000000",
"message": {
"signer": "ADDRESS_OF_THE_SIGNER",
"to": "0xFb428d37AcC708F37A40c8D95d723e1Aea49cc07",
"data": "0x4b9f5c980000000000000000000000000000000000000000000000000000000000000001"
"nonce": "0"
},
"signature": "SIGNATURE_OF_THE_MESSAGE"
}'

Attention, the value of the data parameters (gas_price_limit, to, ...) must be the same used for signature generation.

You will get:

{
"transaction_hash": "0x2968698cb90ec9d95f8656d28bb29593029c79bcd22b42dc6b9469cb03729e2a",
"tracking_id": "01EA266P6PKN0ZY01P0Q6G7WR5"
}

You can follow your transaction on Etherscan with the transaction_hash. But since Rockside is susceptible to replay a stuck transaction, this hash value can changes.

So to keep track of your transaction - whatever happens to it - use the tracking_id as follow:

curl --request GET 'https://api.rockside.io/ethereum/ropsten/transactions/TX_TRACKING_ID' \
--header 'apikey: YOUR_API_KEY'

You will get:

{
"transaction_hash": "0x2968698cb90ec9d95f8656d28bb29593029c79bcd22b42dc6b9469cb03729e2a",
"tracking_id": "01EA266P6PKN0ZY01P0Q6G7WR5",
"from": "0xdd0f36e17474e8cbf9c4e483d02a1cf34f41550a",
"to": "0x7bb7703f2c601a54b484add52a07afad9c9f495e",
"data_length": 484,
"value": 0,
"gas": 87601,
"gas_price": 19270,
"chain_id": 3,
"deadline": "2020-06-05T12:15:03.337Z",
"receipt": {
"status": 1,
"cumulative_gas_used": 6332041,
"logs": [],
"transaction_hash": "0x2968698cb90ec9d95f8656d28bb29593029c79bcd22b42dc6b9469cb03729e2a",
"contract_address": "0x0000000000000000000000000000000000000000",
"gas_used": 86687,
"block_hash": "0xd21a10cc344cb84faaab6725de8dedf51ae8deaacba62c6e0a570dc2578481f2",
"block_number": 8035552,
"transaction_index": 8
},
"created": "2020-06-05T12:10:03.337Z",
"updated": "2020-06-05T12:11:23.632Z",
"status": "success",
}

Go further...

Check out our demo app to see how to create a simple dApp that allows users to interact with a smart contract without having ETH.