Node Provisioning API

Dynamically provision nodes and receive staking transactions to sign.

What is the Node Provisioning API?

The Node Provisioning API allows partners to programmatically spin-up nodes for staking. Partners specify the number of nodes needed and receive a transaction to sign that stakes with those node/s.

Chain

Assets per Node

Ethereum 2.0

32 ETH per Validator

Dash

1,000 DASH per Masternode

Horizen

500 ZEN per Supernode

Keep

100,000 KEEP per Node

Ethereum 2.0

Provision multiple validators with an API request and submit the deposits through a single transaction.

Code Sample

Visit the code-samples repository to learn about the API through hands-on experience.

https://github.com/Stakedllc/code-samples/tree/master/eth2

The code-samples README describes the pre-requisites and details of ETH2 staking for those getting started.

post
Post Provisioning Request

https://eth2.staging.staked.cloud/api/provisioning_requests/eth2
Provision ETH2 validators in our secure cloud environments. The response contains a unique identifier for the provisioning request, as well as a deposit transaction for each validator.
Request
Response
Request
Query Parameters
api_key
required
string
Your API Key - (Must have ETH2 access)
Body Parameters
attributes
required
object
See below for object schema.
Response
200: OK
The response contains a unique identifier for the provisioning request, as well as a deposit transaction for each validator under "depositInput". Each deposit input will need to be signed and submitted to the chain unless the batching contract is used (details below).
{
"uuid": "949f8b0113ac4845863e960cff63a5c1",
"created": "2020-05-08T16:40:02",
...
"attributes": {
"validators": [
{
"cloud": "amazon",
"count": 5,
"index": 1,
"depositInput": "22895118000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000120e0adc3769775d2f56d7f5f0b08a280d29d2ab942c0b36819bd46231e5e8ea8e000000000000000000000000000000000000000000000000000000000000000308d2504147e3a0f5612f52baea44157aef71d8913715826515f9f431b5797a7f8c570c2cbd87814d07ae4a98d5dc3510c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000021288b63da4714a3e67e0578ac05d7000ba1d707ca21d741b344fb1cd55d20000000000000000000000000000000000000000000000000000000000000060acea22cd90a6d0fec2853ef375bece0b6f5f1b05fc794e27ba88854bc692d7372c6c74051bd1876a1bf7b51e72908e010c33551423e5c36c1dcff86daff193d9c5857699a97820e024a8735c37ae2a78f9b555e77b5c0797fb6886c801631415",
"validatorKey": "8d2504147e3a0f5612f52baea44157aef71d8913715826515f9f431b5797a7f8c570c2cbd87814d07ae4a98d5dc3510c"
},
{
"cloud": "amazon",
"count": 5,
"index": 2,
"depositInput": "22895118000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000012053f61469f7100ff426cb0b7b18710b18a3e775c3df8f2740324fd51fa4f8ba84000000000000000000000000000000000000000000000000000000000000003093067b1dd358dd8a628e569e3decb92ad996c2ca7578b89db405abfd0736207f75d69515106b6abf73e1c93409e9cc0f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000021288b63da4714a3e67e0578ac05d7000ba1d707ca21d741b344fb1cd55d20000000000000000000000000000000000000000000000000000000000000060b747ea9a0f9c33f8f9c94b994e51e31439a898454b6a479f36f0c9e3d8a43916a6f5399db0ddc0d03c50a0d186da1d150567edc0d3530ed72e65ce4b45fe3b809e6df5753510e934ee1e6278c06694f580d4579d6eb79e62887f889029080c98",
"validatorKey": "93067b1dd358dd8a628e569e3decb92ad996c2ca7578b89db405abfd0736207f75d69515106b6abf73e1c93409e9cc0f"
},
...
],
"withdrawalKey": "b2484e5f4e4410cbcc12117cd922e131576e13d9856fc9bb4c0901383fda7ce42668ecb1ebaba2f8afb5e0afd4f0a0bd"
}
}
// post request body
// params:
// attributes - object describing provisioning request
// withdrawalKey - Your ETH2 Withdrawal Key
// validators - Array describing validators
// provider - Cloud provider or "decentralized"
// count - Number of validators
{
"attributes": {
"withdrawalKey": "{YOUR ETH2 WITHDRAWAL KEY}",
"validators": [
{
"provider": "decentralized",
"count": 5
}
]
}
}

Submit Transactions to the Batching Contract

The canonical ETH2 deposit contract, used to convert ETH1 to ETH2, only supports one deposit transaction at a time. Since 32 ETH is required for each validator, a depositor with 512 ETH would have to submit and broadcast 16 individual deposit transactions to the deposit contract.

To simplify this process, we have created a batching contract which takes up to 20 deposit transactions at once and submits each to the deposit contract. Integrators can therefore stake up to 640 ETH in one Ethereum transaction, and leave behind the hassle of tracking many individually broadcasted transactions. If you want to stake more than 640 ETH in one transaction please contact us as we have tools to facilitate that as well.

ETH2 Testnet

Smart Contract

Goerli Address

Medalla

Batching Contract

0xD3e5AA84e0E6f4247B3609F88ff157c258E1fE89

Spadina

Batching Contract

0x57E01E3f05ebEd69C186BE55dC347490c0B29D93

The transaction to sign for each individual deposit was returned in the provisioning request response object. Each transaction will need to be signed and submitted to the chain unless the batching contract is used.

The batching contract has an external payable function, batchDeposits, which loops over each individual deposit and sends them to the deposit contract. The function arguments are passed as a 2-d array where the data at [i] represents the arguments for deposit transaction i.

Below, the individual deposit transactions are decoded, put into a 2-d transaction data array, and used to call the batching contract to send deposits in a single transaction.

Node.js
Node.js
async function submitBatchTransactions(validators) {
var pubkeys = [];
var withdrawal_credentials = [];
var signatures = [];
var deposit_data_roots = [];
for (let i = 0; i < validators.length; i++) {
let decoded = decodeDepositInput(validators[i].depositInput);
pubkeys.push(decoded.pubkey);
withdrawal_credentials.push(decoded.withdrawal_credentials);
signatures.push(decoded.signature);
deposit_data_roots.push(decoded.deposit_data_root);
}
const batching_abi = require("./BatchDeposit.json");
const batching_address = "0x57E01E3f05ebEd69C186BE55dC347490c0B29D93";
const batching_contract = new web3.eth.Contract(batching_abi, batching_address);
try {
const ether = n => new web3.utils.BN(web3.utils.toWei(n, "ether"));
const gas_price = await web3.eth.getGasPrice();
const gas_price_scalar = 2
const tx = await batching_contract.methods.batchDeposit(
pubkeys,
withdrawal_credentials,
signatures,
deposit_data_roots)
.send({
from: web3.eth.accounts.wallet[0].address,
value: ether(web3.utils.toBN(32 * validators.length)),
gasPrice: gas_price * gas_price_scalar,
gas: 7999999
});
return tx;
} catch (error) {
console.log(error);
}
}
function decodeDepositInput(validator_tx) {
return web3.eth.abi.decodeParameters([
{
"type": "bytes",
"name": "pubkey"
}, {
"type": "bytes",
"name": "withdrawal_credentials"
}, {
"type": "bytes",
"name": "signature"
}, {
"type": "bytes32",
"name": "deposit_data_root"
}],
"0x" + validator_tx.substring(8)
);
}

get
Get Validator Statuses

https://eth2.staging.staked.cloud/api/delegations/eth2
Get the status of provisioned validators.
Request
Response
Request
Query Parameters
api_key
required
string
Your API Key - (Must have ETH2 access)
Response
200: OK
Object containing the provisioning request information for each validator along with the status. See below for status definitions.
{
"results": [
{
"id": 3282,
"address": "819f16c580cc719d970137031eaab169a8c7b0d5211669e734ee2968eb5a3cc7d622e7e340b288bfd7e5780505961905",
"chain": "ETH2",
"attributes": {
"count": 2,
"index": 1,
"provider": "decentralized",
"depositInput": "22895118000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000012039350fc1cf8c3d8417aa56da05841fcbc271118ed67e879404ad83490f39b5180000000000000000000000000000000000000000000000000000000000000030819f16c580cc719d970137031eaab169a8c7b0d5211669e734ee2968eb5a3cc7d622e7e340b288bfd7e578050596190500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000d2f41655473d97617f9b9f4228ea381a04499073c1c3761a97141db7da3a4e0000000000000000000000000000000000000000000000000000000000000060932fcc3cd7f41c9c12948e512673751fea7e414b9b1d06a0e7d33c0227ca206a3986ede018fa12f3f479b70437c2003501c89c1ae5b68d80dd4453331ddb78f6578c6eaf170ac1600e9e7c5479299dbe6259da36c1ad91fb147b137e9feaae63",
"validatorKey": "819f16c580cc719d970137031eaab169a8c7b0d5211669e734ee2968eb5a3cc7d622e7e340b288bfd7e5780505961905"
},
"amount": "32",
"created": "2020-08-05T20:49:20",
"status": "ACTIVE"
},
...
]
}

Status

Definition

Time Period

CREATED

Validator was provisioned through Staked API

n /a

DEPOSITED

Deposit is waiting to be seen by ETH2 chain

0-6 Hours

PENDING

Validator is in the queue waiting to go live

0-6 Days

ACTIVE

Validator is participating and earning rewards

n / a

For release notifications of the ETH2 API and developer tools, click here.

Dash

Automate provisioning of Dash masternodes.

Integration Environment

Staked supports integration on the Dash testnet and mainnet.

Environment

Base URL

Mainnet

https://mainnet.staked.cloud/api

Testnet

https://testnet.staked.cloud/api

Email [email protected] for testnet Dash, or request it in the Dash Discord. Staked will support 2 masternodes per partner account in a testnet environment.

Getting Started

Each masternode requires an unspent transaction output (UTXO) of exactly 1,000 DASH. The address that owns this UTXO is the collateral address.

Instructions below assume use of the dash command line tool or debug console in the GUI wallet. If using the debug console, please remove dash-cli from the beginning of each command.

Create a new address to hold your masternode collateral.

dash-cli getnewaddress <address-alias>

Example

dash-cli getnewaddress masternode_collateral_1

Next, send exactly 1,000 Dash to your collateral address.

dash-cli sendtoaddress <address> <amount>

Example

dash-cli sendtoaddress yTrtvsNuVgezcGmcVyv2n8D2dFeJEHCYhg 1000

Get the transaction id and output index of the transaction you just created (you may need to wait up to 2 minutes until your transaction is added to a block).

dash-cli masternode outputs

masternode outputs
schema
{
"tx id": "collateral index"
}
example
{
"3483e20a675d7585f0d3a07579f52551e59854ee6ad88af80492418c75a5d4a2": "1",
...
}

A payout address is also needed and can be generated using the getnewaddress command. A single payout address can be shared across masternodes.

post
Step 1: Post Masternode Provisioning Request

https://mainnet.staked.cloud/api/delegations/DASH/delegator/:collateralAddress
Provision a new masternode after sending 1,000 DASH to a collateral address.
Request
Response
Request
Path Parameters
collateralAddress
required
string
Your collateral address
Headers
Content-Type
required
string
application/json
Query Parameters
api_key
required
string
Your api key
Body Parameters
attributes
required
object
Using example from pre-reqs: { "collateralHash": "3483e20a675d7585f0...", "collateralIndex": 1, "payoutAddress": "Payout address here" }
Response
200: OK
{
"id": 2691,
"address": "yTrtvsNuVgezcGmcVyv2n8D2dFeJEHCYhg",
"chain": "DASH",
"attributes": {
"payoutAddress": "yQAt7kYbwZAiWVz9LCVzaox7mxrVBZYNAp",
"collateralHash": "3483e20a675d7585f0d3a07579f52551e59854ee6ad88af80492418c75a5d4a2",
"collateralIndex": 1
},
"created": "2020-06-04T21:23:32",
"status": "CREATED"
}

get
Step 2: Poll Masternode Status

https://mainnet.staked.cloud/api/delegations/DASH/delegator/:collateralAddress
Poll the masternode status. The status is initially set as CREATED. Once the masternode registration message is created through Staked's provisioning infrastructure the response will pass the message for signing along with a status of WaitingForSigning.
Request
Response
Request
Path Parameters
collateralAddress
required
string
Your collateral address used previously.
Query Parameters
api_key
required
string
Your API Key
Response
200: OK
Status is "CREATED"
{
"results": [
"id": 2691,
"address": "yTrtvsNuVgezcGmcVyv2n8D2dFeJEHCYhg",
"chain": "DASH",
"attributes": {
"payoutAddress": "yQAt7kYbwZAiWVz9LCVzaox7mxrVBZYNAp",
"collateralHash": "3483e20a675d7585f0d3a07579f52551e59854ee6ad88af80492418c75a5d4a2",
"collateralIndex": 1
},
"created": "2020-06-04T21:23:32",
"status": "CREATED"
],
"page": 1,
"pages": 1,
"per_page": 10,
"total": 1
}
Status is "WaitingForSigning"
{
"results": [
{
"id": 2691,
"address": "yTrtvsNuVgezcGmcVyv2n8D2dFeJEHCYhg",
"chain": "DASH",
"attributes": {
"ipAndPort": "52.10.215.49:19999",
"signMessage": "yQAt7kYbwZAiWVz9LCVzaox7mxrVBZYNAp|1000|yQFVUWVMP5kVM9Rp8oXLScEAsPMB974rPd|yQFVUWVMP5kVM9Rp8oXLScEAsPMB974rPd|d85fcd73cdb916b1dce77e993cbb915b58381d29067d18757550f9a5dfec5de9",
"internalPort": 32419,
"ownerKeyAddr": "yQFVUWVMP5kVM9Rp8oXLScEAsPMB974rPd",
"registerTxId": "03000100012730d8726ddae3434dfec7e66923b01134a1124982e9e71e1a5f79e2575de2a50000000000feffffff0142b19a3b000000001976a914641138d9d61f2b7d8cccd6c29959349549ba5e8388ac00000000d1010000000000a2d4a5758c419204f88ad86aee5498e55125f57975a0d3f085755d670ae283340100000000000000000000000000ffff340ad7314e1f2b210805a79c2e5e453b20ef85d29633c151076c85c86cdb8d2ebf444fbc40c739b190e56a4c2f8ae9d26567bf2b0d3152ff7c435df652866f572af774d11454fe92a6d12b210805a79c2e5e453b20ef85d29633c151076ce8031976a9142a41da2a5517ae71484594d2187c7f99ed20e91e88ac34dec225612f265fb337240197d8f30ba22a6d5ca12547e50a91ff2aec7bedaa00",
"payoutAddress": "yQAt7kYbwZAiWVz9LCVzaox7mxrVBZYNAp",
"collateralHash": "3483e20a675d7585f0d3a07579f52551e59854ee6ad88af80492418c75a5d4a2",
"operatorPubKey": "85c86cdb8d2ebf444fbc40c739b190e56a4c2f8ae9d26567bf2b0d3152ff7c435df652866f572af774d11454fe92a6d1",
"collateralIndex": 1
},
"amount": null,
"created": "2020-06-04T21:23:32",
"status": "WaitingForSigning"
}
],
"page": 1,
"pages": 1,
"per_page": 10,
"total": 1
}

Step 3: Sign Delegation Message

This must be run on the wallet or device that holds collateral key, and can be done completely offline if required. signMessage is returned in the response of the previous step.

signmessage collateralAddress signMessage

Example Output:

H3ub9BATtvuV+zDGdkUQNoUGpaYFr/O1FypmrSmH5WJ0KFRi8T10FSew0EJO/+Ij+OLv4r0rt+HS9pQFsZgc2dE=

put
Step 4: Send Us the Signed Delegation Message

https://mainnet.staked.cloud/api/delegations/DASH/delegator/:collateralAddress
Finally, send Staked the signed transaction and we will broadcast it to the Dash blockchain!
Request
Response
Request
Path Parameters
collateralAddress
required
string
Masternode collateral address set up previously.
Query Parameters
api_key
required
string
Your API Key
Body Parameters
attributes
required
string
{ "signedTx": "Your Signed Message" }
status
required
string
Set as "WaitingtoSubmit"
Response
200: OK

The status of the delegation object is now WaitingToSubmit. When the Masternode is synched, the signedTx will be submitted and the status will be Ready.

Boom! You've programmatically set up a Masternode. Check out the Reporting API to monitor your position.