Getting Started

Process Overview

The Unified API is designed to simplify and standardize interactions across all supported networks. Whether you are staking or unstaking assets, the process follows a consistent and straightforward flow, ensuring seamless integration for all networks.

Each network integration follows 3 key operations:

  1. stake: Initiate a staking transaction to delegate your assets.
  2. unstake: Initiate an unstaking transaction, beginning the process of withdrawing your assets.
  3. withdraw: Complete the process by withdrawing the unstaked assets to your wallet.

How It Works

For each operation—staking, unstaking, and withdrawing—the Unified API returns an unsigned transaction. Here's how the flow works:

  1. Transaction Preparation: The API generates a raw unsigned transaction for your desired operation (stake, unstake, or withdraw).
  2. Transaction Signing: You sign the transaction using your preferred method. We provide separate, detailed instructions for transaction signing tailored to various networks.
  3. Transaction Broadcasting: Use the API’s dedicated broadcast method to submit the signed transaction to the network.

Network-Specific Details

While the process remains consistent, the distinction between networks lies in the specific POST request parameters required.

In the following article, we’ll cover the integration process for the solana chain and testnet network.

For details on other networks, refer to the Networks .

Prerequisites

Chain and Network Mapping refers to the mapping table on the overview page for detailed information.

Get an authentication token to start using the Unified API.

Request examples are provided using cURL .

Staking Flow

Step 1. Create Staking Transaction

Send a POST request to https://api-test.p2p.org/api/v1/unified/staking/stake.

Example request:

curl --request POST \
     --url https://api-test.p2p.org/api/v1/unified/staking/stake \
     --header 'Content-Type: application/json' \
     --header 'Authorization: Bearer <token>' \
     --data '{
    "chain": "solana",
    "network": "testnet",
    "stakerAddress": "9i5cTqci1W6DHdYfT7WbiNhP5DXvnPNTXvS9fTBFfuSw",
    "amount": "1002282880"
}'
  • chain — defines the target blockchain network. In this case, solana specifies the Solana blockchain.
  • network — specifies the environment:
    • mainnet for production use.
    • testnet for development and testing purposes (as used here).
  • stakerAddress — serves as a unified input for multiple Solana parameters:
    • feePayer — the account responsible for paying transaction fees.
    • fromPublicKey — the account used to create the staking account.
    • stakeAuthority — grants permissions for staking operations (defaults to fromPublicKey if not explicitly provided).
    • withdrawAuthority — grants permissions for withdrawal operations (defaults to fromPublicKey if not explicitly provided).
  • amount — the stake amount in lamports (1 SOL = 10^9 lamports).
    • Example: 1002282880 lamports = 1.00228288 SOL.
    • Minimum allowed amount: 1002282880 lamports.

Example response:

{
    "error": null,
    "result": {
        "amount": 1002282880,
        "stakerAddress": "6GtymMn8cDTy3xHH9AitwP6skbKvBkD53XBE2xSu1tCR",
        "unsignedTransactionData": "AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAcJgWOF0j3LZd8/2fe+xWth5iFvfdEnpRBZ9lu0+nSj6cBOXOtVnnzgdQsGlzC2Y3c6ptktzhYaKKHNw0Bi1oHf4gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAh8iugT4hbb/uMDOx66iyC43XvE2dwUsI1HUUjzs6IbAGodgXkTdUKpg0N73+KnqyVX9TXIp4citopJ3AAAAAAAah2BelAgULaAeR5s5tuI4eW3FQ9h/GeQpOtNEAAAAABqfVFxjHdMkoVmOYaR1etoteuKObS21cc1VbIQAAAAAGp9UXGSxcUSGMyUw9SvF/WNruCJuh/UTj29mKAAAAAAan1RcZNYTQ/u2bs0MdEyBr5UQoG1e4VmzFN1/0AAAAHKEjIcCxFWx4HvZBQrHANtq0grHucq4V1OVMlBvalFQDAgIAAXQDAAAAgWOF0j3LZd8/2fe+xWth5iFvfdEnpRBZ9lu0+nSj6cAYAAAAAAAAAEZiVWJmK1A0UzRLK1h5V3pTRXBjaHc9PYCfvTsAAAAAyAAAAAAAAAAGodgXkTdUKpg0N73+KnqyVX9TXIp4citopJ3AAAAAAAQCAQd0AAAAAIFjhdI9y2XfP9n3vsVrYeYhb33RJ6UQWfZbtPp0o+nAgWOF0j3LZd8/2fe+xWth5iFvfdEnpRBZ9lu0+nSj6cAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBgEDBggFAAQCAAAA",
        "createdAt": "2024-12-17T19:40:29.176Z",
        "extraData": {
            "network": "testnet",
            "feePayer": "9i5cTqci1W6DHdYfT7WbiNhP5DXvnPNTXvS9fTBFfuSw",
            "fromPublicKey": "9i5cTqci1W6DHdYfT7WbiNhP5DXvnPNTXvS9fTBFfuSw",
            "stakeAuthority": "9i5cTqci1W6DHdYfT7WbiNhP5DXvnPNTXvS9fTBFfuSw",
            "withdrawAuthority": "9i5cTqci1W6DHdYfT7WbiNhP5DXvnPNTXvS9fTBFfuSw",
            "voteAccount": "A93XLdBKfc4pwEMAvdFeyxnF6HauN5erNDFbUsemWiaB"
        }
    }
}
  • error — indicates if an error occurred (null means success).
  • result — contains transaction details:
    • amount — amount to stake, in lamports (1002282880 = 1.00228288 SOL).
    • stakerAddress — the staking account address receiving the staked tokens.
    • unsignedTransactionData — base64-encoded unsigned transaction data to be signed and broadcasted.
    • createdAt — timestamp of when the transaction was created, in ISO 8601 format.
    • extraData — additional transaction metadata:
      • network — specifies the environment (e.g., testnet).
      • feePayer — address paying the transaction fee.
      • fromPublicKey — address used to create the staking account.
      • stakeAuthority — address authorized for staking operations.
      • withdrawAuthority — address authorized for withdrawal operations.
      • voteAccount — the validator's vote account receiving the stake.

Step 2. Sign and Broadcast transaction

Use unsignedTransactionData to sign the transaction.

Send a POST request to https://api-test.p2p.org/api/v1/unified/transaction/broadcast.

Example request:

curl --request POST \
     --url https://api-test.p2p.org/api/v1/unified/transaction/broadcast \
     --header 'Content-Type: application/json' \
     --header 'Authorization: Bearer <token>' \
     --data '{
    "chain": "solana",
    "network": "testnet",
    "stakerAddress": "9FfyCk9kqgfpg1gYMw8rhksZcAg4JiD9xhuMvkFVdjQY",
    "signedTransaction": "AdtQhLeM0eOMdV7rvagYx3V8mra6CMaiVgeNTcgTds8ltjDUwJi3LMGhZ+Txqj26nJMJa7MxFWe5lmIxAnjKsQUBAAIEep+wazhVDEf2XiuHusgypzGMGyd4WaFZ6lzpHIypRJ3qFo72gQoaoUsCAJcUGGTQGdOONNYMBdVbIhEKwGitMwah2BeRN1QqmDQ3vf4qerJVf1NcinhyK2ikncAAAAAABqfVFxjHdMkoVmOYaR1etoteuKObS21cc1VbIQAAAABojzQ55lMuIXx6AWTccH48p4L12JlvUuCfHkOik1nJLAECAwEDAAQFAAAA"
}'
  • chain — defines the blockchain network. In this case, solana indicates that the transaction is for the Solana blockchain.
  • network — specifies the environment in which the transaction is executed:
    • mainnet for production use.
    • testnet for testing purposes (used here).
  • stakerAddress — represents the address initiating the transaction.
  • signedTransaction — a Base64-encoded string representing the signed transaction data.
    • This contains all transaction details (e.g., accounts, instructions, and signatures) required to broadcast the transaction to the Solana network.

Example response

{
    "error": null,
    "result": {
        "extraData": {
            "transactionId": "2Bno5j3tex8VmcCR2M6JQnjtPxDuqAvSAUjSDpd6gaasRfEQeoWH9MRQdU7ANNtFFbG9UQAGByG1UwPS1qersmyd",
            "slot": 307375529,
            "signerAccounts": [
                "9i5cTqci1W6DHdYfT7WbiNhP5DXvnPNTXvS9fTBFfuSw",
                "6GtymMn8cDTy3xHH9AitwP6skbKvBkD53XBE2xSu1tCR",
                "11111111111111111111111111111111",
                "A93XLdBKfc4pwEMAvdFeyxnF6HauN5erNDFbUsemWiaB",
                "Stake11111111111111111111111111111111111111",
                "StakeConfig11111111111111111111111111111111",
                "SysvarC1ock11111111111111111111111111111111",
                "SysvarRent111111111111111111111111111111111",
                "SysvarStakeHistory1111111111111111111111111"
            ],
            "createdAt": "2024-12-17T19:41:27.450Z"
        }
    }
}
  • error — indicates if an error occurred (null means success).
  • result — contains details about the broadcasted transaction.
    • extraData — additional transaction details:
      • transactionId — unique ID of the transaction on the Solana blockchain (used for tracking or verification).
      • slot — slot number where the transaction was confirmed (marker of blockchain time).
      • signerAccounts — array of accounts involved in the transaction (e.g., fee-payer, system accounts, and stake-related accounts).
      • createdAt — timestamp of when the transaction was broadcasted, in ISO 8601 format.

Unstaking Flow

Step 1: Create an Unstaking Transaction

Send a POST request to https://api-test.p2p.org/api/v1/unified/staking/unstake.

Example request:

curl --request POST \
     --url https://api-test.p2p.org/api/v1/unified/staking/unstake \
     --header 'Content-Type: application/json' \
     --header 'Authorization: Bearer <token>' \
     --data '{
    "chain": "solana",
    "network": "testnet",
    "stakerAddress": "9FfyCk9kqgfpg1gYMw8rhksZcAg4JiD9xhuMvkFVdjQY",
    "extra": {
        "amount": "1002282880",
        "stakeAccount": "GknMRQYxnoZphCUUKJJLuw27hwCW8qPKuJ4CsTpchj5L"
    }
}'
  • chain — defines the blockchain network. In this case, solana indicates that the transaction is for the Solana blockchain.
  • network — specifies the environment in which the transaction is executed:
    • mainnet for production use.
    • testnet for testing purposes (used here).
  • stakerAddress — represents the address initiating the transaction.
  • extra — contains additional data specific to the unstake operation:
    • amount — the number of tokens to unstake, specified in lamports (1 SOL = 10^9 lamports). In this case, 1002282880 lamports = 1.00228288 SOL.
    • stakeAccount — the account address where the staked tokens are stored.

Example response:

{
    "error": null,
    "result": {
        "stakerAddress": "6GtymMn8cDTy3xHH9AitwP6skbKvBkD53XBE2xSu1tCR",
        "unsignedTransactionData": "AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAIEgWOF0j3LZd8/2fe+xWth5iFvfdEnpRBZ9lu0+nSj6cBOXOtVnnzgdQsGlzC2Y3c6ptktzhYaKKHNw0Bi1oHf4gah2BeRN1QqmDQ3vf4qerJVf1NcinhyK2ikncAAAAAABqfVFxjHdMkoVmOYaR1etoteuKObS21cc1VbIQAAAAC6Oo3oUHKupolPnHZ0RH2ZxtrEHm8tk2Qp2iW0vfhHhgECAwEDAAQFAAAA",
        "createdAt": "2024-12-17T19:46:06.403Z",
        "extraData": {
            "network": "testnet",
            "feePayer": "9i5cTqci1W6DHdYfT7WbiNhP5DXvnPNTXvS9fTBFfuSw",
            "stakeAuthority": "9i5cTqci1W6DHdYfT7WbiNhP5DXvnPNTXvS9fTBFfuSw"
        }
    }
}
  • error — indicates whether an error occurred (null means success).
  • result — contains the details of the generated transaction:
    • stakerAddress — the staking account address involved in the operation (6GtymMn8cDTy3xHH9AitwP6skbKvBkD53XBE2xSu1tCR).
    • unsignedTransactionData — base64-encoded unsigned transaction data that must be signed and broadcasted to execute the transaction.
    • createdAt — timestamp indicating when the transaction data was created, in ISO 8601 format.
    • extraData — additional metadata about the transaction
      • network — specifies the environment (e.g., testnet).
      • feePayer — address responsible for paying the transaction fee.
      • stakeAuthority — address authorized to perform staking operations on the staking account.

Step 2. Sign and Broadcast Unstake Transaction

Sign and broadcast the transaction as outlined in step 2 .

Step 3. Withdraw

Send a POST request to https://api-test.p2p.org/api/v1/unified/staking/withdraw.

Example request:

curl --request POST \
     --url https://api-test.p2p.org/api/v1/unified/staking/withdraw \
     --header 'Content-Type: application/json' \
     --header 'Authorization: Bearer <token>' \
     --data '{
    "chain": "solana",
    "network": "testnet",
    "stakerAddress": "9FfyCk9kqgfpg1gYMw8rhksZcAg4JiD9xhuMvkFVdjQY",
    "extra": {
        "amount": "1002282880"
    }
}'
  • chain — defines the blockchain network. In this case, solana indicates that the transaction is for the Solana blockchain.
  • network — specifies the environment in which the transaction is executed:
    • mainnet for production use.
    • testnet for testing purposes (used here).
  • stakerAddress — represents the address initiating the transaction.
  • extra — contains additional data specific to the unstake operation:
    • amount — the number of tokens to unstake, specified in lamports (1 SOL = 10^9 lamports). In this case, 1002282880 lamports = 1.00228288 SOL.
    • stakeAccount — the account address where the staked tokens are stored.

Example response:

{
    "error": null,
    "result": {
        "stakerAddress": "6GtymMn8cDTy3xHH9AitwP6skbKvBkD53XBE2xSu1tCR",
        "unsignedTransactionData": "AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAMFgWOF0j3LZd8/2fe+xWth5iFvfdEnpRBZ9lu0+nSj6cBOXOtVnnzgdQsGlzC2Y3c6ptktzhYaKKHNw0Bi1oHf4gah2BeRN1QqmDQ3vf4qerJVf1NcinhyK2ikncAAAAAABqfVFxjHdMkoVmOYaR1etoteuKObS21cc1VbIQAAAAAGp9UXGTWE0P7tm7NDHRMga+VEKBtXuFZsxTdf9AAAAPOAx5l5F5rUaY7eB6UQVXzEi9E6HWzj9Mg5vRAcUMlcAQIFAQADBAAMBAAAAICfvTsAAAAA",
        "createdAt": "2024-12-17T19:49:22.476Z",
        "extraData": {
            "network": "testnet",
            "feePayer": "9i5cTqci1W6DHdYfT7WbiNhP5DXvnPNTXvS9fTBFfuSw",
            "withdrawAuthority": "9i5cTqci1W6DHdYfT7WbiNhP5DXvnPNTXvS9fTBFfuSw",
            "recipient": "9i5cTqci1W6DHdYfT7WbiNhP5DXvnPNTXvS9fTBFfuSw",
            "amount": 1002282880
        }
    }
}
  • error — indicates whether an error occurred (null means success).
  • result — contains the details of the withdrawal transaction:
    • stakerAddress — the staking account address associated with the withdrawal operation (6GtymMn8cDTy3xHH9AitwP6skbKvBkD53XBE2xSu1tCR).
    • unsignedTransactionData — base64-encoded unsigned transaction data that must be signed and broadcasted to complete the withdrawal.
    • createdAt — timestamp of when the transaction data was created, in ISO 8601 format.
    • extraData — additional metadata about the transaction:
      • network — specifies the environment (e.g., testnet).
      • feePayer — address responsible for paying the transaction fee.
      • withdrawAuthority — address authorized to perform the withdrawal.
      • recipient — address to receive the withdrawn tokens.
      • amount — the amount of tokens to withdraw, in lamports (1002282880 = 1.00228288 SOL).

Step 4. Sign and Broadcast Withdrawal Transaction

Sign and broadcast the transaction as outlined in step 2 .

What's Next?