Sign and Broadcast Transaction

To sign and broadcast a transaction to the Story network, follow these steps:

1. Prepare the Unsigned Transaction

Obtain the unsignedTransaction object by following the staking, unstaking, or withdrawal flow via the Staking API. The object will have the format returned in previous API responses.

2. Sign the Transaction

Use any Ethereum-compatible signing method or library to sign the transaction. Below is an example using ethers.js. Note that for package.json the 5.7.2 version of ethers is required.

import { Wallet, utils } from 'ethers';

// Your private key (use secure storage in production)
const PRIVATE_KEY = '***';

// Unsigned transaction in hex format
const unsignedTxHex = '***';

const wallet = new Wallet(PRIVATE_KEY);

(async () => {
    try {
        const parsedTx = utils.parseTransaction(unsignedTxHex);
        const signedTx = await wallet.signTransaction({
            to: parsedTx.to,
            value: parsedTx.value,
            data: parsedTx.data,
            gasLimit: parsedTx.gasLimit,
            maxFeePerGas: parsedTx.maxFeePerGas,
            maxPriorityFeePerGas: parsedTx.maxPriorityFeePerGas,
            nonce: parsedTx.nonce,
            type: parsedTx.type || undefined,
            chainId: parsedTx.chainId
        });
        const signedTxBytes = utils.arrayify(signedTx);
        console.log(Buffer.from(signedTxBytes).toString('base64'));
    } catch (error) {
        console.error('Error:', error);
    }
})();

The output will be a0x-prefixed hex string containing your signed transaction, ready for broadcasting.

3. Broadcast the Signed Transaction

Send the signed transaction to the Story network by making a POST request to /api/v1/story/[network]/tx/send.

  1. Example request (for aeneid network):

    curl --request POST \
         --url https://api-test.p2p.org/api/v1/story/aeneid/tx/send \
         --header 'Authorization: Bearer <token>' \
         --header 'Content-Type: application/json' \
         --data '{
           "signedTransaction": "<hex_signed_tx>"
         }'
    • signedTransaction — signed transaction in the hexadecimal format.

    Example response:

    {
      "result": {
        "transactionId": "0xadcba25d1bcedaa2fd17ff5db6b45d5e7060cf3a3c17e263feebf7b460f742c9",
        "signerAccounts": [
          "0x3202B5B0602274197CcB22B8c02CEC9539990c7c"
        ],
        "createdAt": "2025-07-22T14:08:23.456Z"
      }
    }
    • transactionId — hash of the transaction included in the Story Protocol chain.
    • signerAccounts — list of account addresses that signed the transaction.
    • createdAt — timestamp of the transaction in the ISO 8601 format.

What's Next?