Figment's Staking API increases the speed at which you can add new transfer and staking functionalities for many Proof-of-Stake (PoS) assets. The Staking API abstracts away all network-specific infrastructure and work to enable API interaction in the exact same way, regardless of network or the type of action being taken. It gets you to market faster, by reducing research and discovery work by weeks and the engineering time by months.
Using the Staking API's concepts of flows, actions, inputs and payloads, it is possible to build dynamic forms to collect data and guide users through each workflow without the need to hard code specifics for a given network. For non-ETH chains, stake with any validator on the network. For ETH, you still need to provision validators with each staking provider you use.
Staking API Core Concepts
Flows
The Staking API is based around the concept of a flow. A flow is a combination of a network, a chain and an operation. For example: Solana (network) + devnet (chain) + staking (operation)
A flow is made of multiple steps (states) and a specific set of actions to be completed to move between states
Each flow has a unique id
to be used for querying and advancing the flow.
Actions
At each step in the flow, the Staking API's response contains a JSON object with each possible action that can be taken, including the action's name
and the inputs
for submitting that action.
In the example above ("Solana staking on devnet"), some SOL tokens first need to be held in a system account. After creating a flow, the reponse will contain two possible actions that can be taken to advance the flow to the next state:
create_stake_account
(to create and fund a new account)assign_stake_account
(to use an existing inactive account)
{
"id": "e2285668-f6ab-4b77-9e96-edbcca63cd24",
"operation": "staking",
"state": "initialized",
"actions": [
{
"name": "assign_stake_account",
// "inputs": [...]
},
{
"name": "create_new_stake_account",
// "inputs": [...]
}
],
}
Inputs
Each action comes with a set of inputs that indicate what data needs to be collected and submitted to the advance to the next state.
In our example ("Solana staking on devnet"), let's assume we want to go with the create_stake_account
action. The response of the request indicates that create_stake_account
needs to be submitted with 4 input fields. It contains metadata for data type, display label, validations, etc that can be used for building a UI.
{
"id": "e2285668-f6ab-4b77-9e96-edbcca63cd24",
"operation": "staking",
"state": "initialized",
"actions": [
{
"name": "create_new_stake_account",
"inputs": [
{
"name": "funding_account_pubkey",
"display": "Stake Account Pubkey",
"description": "",
"type": "string",
"validations": [
{
"type": "presence",
"options": {}
}
],
"array": false,
"default_value": null
},
{
"name": "stake_authority_pubkey",
// type, display, validations, etc
},
{
"name": "withdraw_authority_pubkey",
// type, display, validations, etc
},
{
"name": "amount",
// type, display, validations, etc
}
]
}
],
}
Payloads
For each step in a Flow where a transaction must be signed, the response from the Staking API includes a serialized transaction payload ready for signature. It is your responsibility to manage signing the transaction and submitting the signed Payload back to the Staking API for broadcasting to the network.
Webhooks
The Staking API utilizes webhooks to notify you of completed actions, reducing the need for manual polling. Every network supported by the Staking API uses the same API endpoints to create, modify, list or delete webhooks.
Decoding and Signing Transactions
We have published an npm package for decoding and signing Staking API transactions. Learn how to use it here: Signing Transactions with Figment's NPM Package
Advance a flow using a transaction hash
Figment's API provides the option for clients to use an existing solution to sign and broadcast transactions themselves, using a transaction hash from a completed transaction to advance the state of a flow and confirm the transaction on-chain — in lieu of providing a signed transaction payload.
This action is also available for other networks and flows. The following example uses a Polkadot bonding flow on the Westend testnet to illustrate the process.
Example: Polkadot
Polkadot delegation flows use the create_bonding_tx
action to generate a transaction payload.
It is still possible to bond from a Stash account, completing this transaction without use of Figment's API.
In this case, we want to perform the bond transaction (including the signature) from the Polkadot.js Apps UI,
then complete the bonding flow with the Staking API by providing the transaction hash of the completed transaction.
The general form of this action is confirm_<action>_tx_by_hash
.
Since we are performing a bonding
transaction, the action name to use is confirm_bonding_tx_by_hash
.
Using this action in a flow lets you supply a transaction hash to the API while the flow is in the <action>_tx_signature
state.
In the case of Polkadot, the block number of the block which includes the transaction hash must also be specified.
{
"id": "3ace9f6b-7298-4fc7-b780-f2c3ea521784",
"state": "bonding_tx_signature",
"actions": [
...
{
"name": "confirm_bonding_tx_by_hash",
"inputs": [
{
"name": "hash",
"display": "Hash",
"description": "",
"type": "string",
"validations": [
{
"type": "presence",
"options": {}
}
],
"array": false,
"default_value": null
},
{
"name": "block_number",
"display": "Block Number",
"description": "",
"type": "integer",
"validations": [],
"array": false,
"default_value": null
}
]
}
],
...
"network_code": "polkadot",
"chain_code": "westend",
"created_at": "2023-01-20T22:10:26.800Z",
"updated_at": "2023-01-20T22:28:19.348Z"
}
Usage
On Polkadot, the input for hash
should be the Extrinsic Hash of the transaction, and the input for block
should be the block number in which that extrinsic occurred. Refer to a bonding transaction on the Subscan block explorer for an example of where to find this information.
For other networks, supply the hash
of a confirmed transaction.
Code Examples
Important
Code examples provided as samples only and should not be used in production out of the box. Use at your own risk.
curl -X PUT 'https://polkadot-slate.figment.io/api/v1/flows/<flow_id>/next' \
-H 'Authorization: API-KEY' \
-H 'Content-Type: application/json' \
-d '{
"name": "confirm_bonding_tx_by_hash",
"inputs": {
"hash": "0x53b66da426dca5386408f0a3cdc5300477dd7151c7459701e9dcbbf0fa0b07c8",
"block_number": "14295923"
}
}'
fetch(`https://polkadot-slate.figment.io/api/v1/flows/${FLOW_ID}/next`, {
method: 'PUT',
headers: {
"Authorization" : "<API_KEY>",
"Content-Type": "application/json"
},
body: JSON.stringify({
"name": "confirm_bonding_tx_by_hash",
"inputs": {
"hash": "0x53b66da426dca5386408f0a3cdc5300477dd7151c7459701e9dcbbf0fa0b07c8",
"block_number": "14295923"
}
});
});
Note
The parameter
block_number
only applies to Polkadot. For other networks, only thehash
is required.
Flow State
The action confirm_<action>_tx_by_hash
updates the flow state, depending on whether the confirmed transaction hash can be found by the API.
-
When
confirm_<action>_tx_by_hash
succeeds, the flow state will reflect the successful action, the same as if a transaction payload had been signed and sent to the API. -
In case
confirm_<action>_tx_by_hash
fails, the flow state will remain<action>_tx_signature
, allowing for retries — the flow state does not become<action>_tx_broadcasting
.
In the case of the example Polkadot bonding transaction, the state would be bonding_complete
after a successful confirm_bonding_tx_by_hash
action.
For comparison, an Ethereum staking flow state would be deposited
after a successful confirm_deposit_tx_by_hash
action.
Check the table below for a summary of flow states after confirm_<action>_tx_by_hash
.
Network | Flow(s) | Final State |
---|---|---|
Avalanche | Staking | completed |
Cardano | Staking, Transfer | completed |
Cosmos | Staking, Redelegate, Transfer, Claim Rewards | completed |
Cosmos | Unstaking | unbonding during the unbonding period.completed when successful. |
Ethereum | Staking | deposited |
Ethereum | Unstaking | unstaked |
Ethereum | Aggregated Staking | activating during the activation period.active when successful. |
Ethereum | Aggregated Unstaking | broadcasting if awaiting manual Figment approval, or exiting while the validator(s) are in the exit queue.unstaked when successful. |
NEAR | Staking | delegated |
NEAR | Unstaking | cool_down during the unbonding period.withdrawn after a successful withdrawal transaction. |
NEAR | Transfer | transferred |
Polkadot | Staking | bonding_complete after a successful bonding transaction.delegated after a successful nomination transaction. |
Polkadot | Unstaking | done after a successful chill transaction.ready_to_withdraw after a successful unbond transaction.done after a successful withdrawal transaction. |
Polkadot | Add or Remove Proxy | registered after a successful add proxy transaction.removed after a successful remove proxy transaction. |
Polkadot | Transfer | transferred |
Polygon | Staking | create_delegate_tx after a successful allowance transaction.completed after a successful delegate transaction. |
Polygon | Unstaking | unbonding during the unbonding period.done after a successful claim transaction. |
Polygon | Claim Rewards | done after a successful claim rewards transaction. |
Solana | Staking | stake_account after a stake account is created or assigned.delegation_activating during the bonding period.delegation_active after a successful delegation. |
Solana | Unstaking | cool_down during the deactivation period.withdrawn after a successful withdrawal transaction. |
Solana | Transfer | transferred |
Solana | Merge / Split Stake Account | completed |