Sign and Broadcast Transaction

To complete any bonding or withdrawal operation on Aptos, sign the unsigned transaction provided by the Staking API and broadcast it to the network.

1. Prepare the transaction

Retrieve an unsigned serialized transaction from the relevant API endpoint, e.g., /staking/delegated/add,/staking/delegated/reactivate, /staking/delegated/withdraw.

2. Sign the transaction

Sign the transaction using the code below.

import {
  Aptos,
  Hex,
  Deserializer,
  RawTransaction,
  AptosConfig,
  Network,
  Ed25519PrivateKey,
  Account,
  SimpleTransaction,
  AccountAuthenticator,
} from "@aptos-labs/ts-sdk";

export function signTransaction(rawTx: string, privateKeyHex: string, aptosEnv: "mainnet" | "testnet"): string {
  if (!rawTx || !privateKeyHex) throw new Error("Missing raw transaction or private key");

  const config = new AptosConfig({
    network: aptosEnv === "mainnet" ? Network.MAINNET : Network.TESTNET,
    fullnode: aptosEnv === "mainnet" ? "https://api.mainnet.aptoslabs.com/v1" : "https://api.testnet.aptoslabs.com/v1",
  });

  const aptos = new Aptos(config);
  const signer = Account.fromPrivateKey({ privateKey: new Ed25519PrivateKey(privateKeyHex) });

  const transaction = new SimpleTransaction(
    RawTransaction.deserialize(new Deserializer(Hex.hexInputToUint8Array(rawTx)))
  );

  const signedTx: AccountAuthenticator = aptos.transaction.sign({ signer, transaction });

  return signedTx.toString();
}

const [, , rawTx, privKey, network] = process.argv;

if (!["mainnet", "testnet"].includes(network)) {
  throw new Error("Network must be 'mainnet' or 'testnet'");
}

console.log(signTransaction(rawTx, privKey, network as "mainnet" | "testnet"));

/**
 *  How to run this script:
 *  npx --yes -p @aptos-labs/[email protected] tsx signTransaction.ts <RAW_TX> <PRIVATE_KEY> <mainnet|testnet>
 **/
 
/**
 *  To run with env variables:
 *
 *  $ export RAW_TX= 'rawtxhere'
 *  $ export PRIVATE_KEY= 'privatekeyhere'
 *  $ export NETWORK= 'testnet' 
 *  $ npx --yes -p @aptos-labs/[email protected] tsx signTransaction.ts $RAW_TX $PRIVATE_KEY $NETWORK
 **/

Upon successful execution, the script prints the signed transaction, ready for broadcasting.

3. Send the transaction

Send the signed transaction to the Aptos network by making a POST request to /api/v1/aptos/{network}/transaction/send.

Example request:

curl --request POST \
     --url https://api.p2p.org/api/v1/aptos/mainnet/transaction/send \
     --header 'accept: application/json' \
     --head 'Authorization: Bearer <token>' \
     --header 'content-type: application/json' \
     --data '
{
  "transaction": "0x0020b92f133c8e4768d990f39853f1931eb0481ea289a985687f0b7e59e83456333140d386bb294c9a3ce9c8e6b49c4d6dba1bbf4d99b7803f9947bcec59855414d064bf138d29c14e884fb0e7f18c35fd39ffcae96fe767a3ddcbdc6603e407673006",
  "signature": "0x0020b92f133c8e4768d990f39853f1931eb0481ea289a985687f0b7e59e83456333140960e71dc383c5e0660940bbe476499ed8b64bc37efff47db1c20274f20b39d5858737269d6c7bcb1b9fc88dce0f0f7cc12b5e86516cf9f8d787827eaedf9f906"
}
'
  • transaction — signed transaction in the hexadecimal format which needs to be broadcasted to the network.
  • signature — delegator signature of the transaction.

Example response:

{
  "result": {
    "network": "mainnet",
    "senderAddress": "0xa571a5bc9b1bfd5fe58e6e09a5be251a3299985494d022959ce206f1f23f752e",
    "transaction": "0x0020b92f133c8e4768d990f39853f1931eb0481ea289a985687f0b7e59e83456333140d386bb294c9a3ce9c8e6b49c4d6dba1bbf4d99b7803f9947bcec59855414d064bf138d29c14e884fb0e7f18c35fd39ffcae96fe767a3ddcbdc6603e407673006",
    "status": "success",
    "transactionHash": "0x8d80b8ed85b578eeb873731101a926221701ee48318f6c9b83895f7ac1535640",
    "gas": {
      "unitPrice": 100,
      "maxGasLimit": 100,
      "used": 100
    },
    "createdAt": "2023-08-24T08:14:50.455Z"
  },
  "error": {}
}
  • network — Aptos network: mainnet or testnet.
  • senderAddress — transaction sender address.
  • transaction — signed transaction in hexadecimal format.
  • status — transaction status: pending, success, or failed.
  • transactionHash — hash of the transaction.
  • gas — computational effort required to execute the transaction, measured in gas units.
    • unitPrice — price per unit of gas in Octas for processing the Aptos transaction.
    • maxGasLimit — maximum gas limit for the transaction.
    • used — amount of gas spent for the transaction.
  • createdAt — timestamp of the transaction in the ISO 8601 format.

What's next?