How to send a transaction

🚀

Hyperstrate accepts serialized, signed transactions. Never send a private key, seed phrase, or unsigned signing request to the transaction endpoint.

Send a Polygon transaction

This guide submits a signed Polygon transaction through the Ethereum JSON-RPC 2.0 compatibility endpoint and shows how to inspect both its on-chain receipt and its Hyperstrate private-delivery lifecycle.

Prerequisites

Before continuing, make sure you have:

  • A Hyperstrate workspace
  • A submit-scoped API key
  • Sufficient prepaid credit when billing is enabled
  • A transaction signed for the configured Polygon chain
  • Your Hyperstrate API base URL

Set the examples as environment variables:

export HYPERSTRATE_API_URL="https://app.hyperstrate.xyz/api"
export HYPERSTRATE_API_KEY="ak_your_api_key"

1. Discover the Polygon network

Request the current network configuration:

curl --fail-with-body \
  --request GET \
  --url "$HYPERSTRATE_API_URL/v1/networks"

Find the response with "namespace": "polygon" and confirm that:

  • private is true when you require private delivery
  • availability.accepting is true
  • capabilities.submissionFormat is evm-signed-hex
  • Your transaction uses the returned chainId

You can also retrieve the chain ID through JSON-RPC:

curl --fail-with-body \
  --request POST \
  --url "$HYPERSTRATE_API_URL/polygon/rpc" \
  --header "Authorization: Bearer $HYPERSTRATE_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{"jsonrpc":"2.0","method":"eth_chainId","params":[],"id":1}'

Polygon PoS chain ID 137 is returned as the hexadecimal quantity 0x89.

⚠️

Always use the discovered numeric chain ID when constructing and signing the transaction. A transaction signed for another chain will be rejected.

2. Sign the transaction locally

Use your existing wallet, HSM, custody platform, or signing library to produce the serialized signed transaction.

The result should be a hexadecimal value similar to:

0x02f8...

When constructing the transaction, your application remains responsible for:

  • Selecting and coordinating the nonce
  • Estimating the gas limit
  • Choosing fee parameters
  • Selecting the recipient, value, and calldata
  • Protecting the signing key

Store the signed value for the next step:

export SIGNED_TRANSACTION_HEX="0x02f8..."

3. Submit with eth_sendRawTransaction

Send the signed payload to the Polygon JSON-RPC endpoint:

curl --fail-with-body \
  --request POST \
  --url "$HYPERSTRATE_API_URL/polygon/rpc" \
  --header "Authorization: Bearer $HYPERSTRATE_API_KEY" \
  --header "Content-Type: application/json" \
  --data "{
    \"jsonrpc\": \"2.0\",
    \"method\": \"eth_sendRawTransaction\",
    \"params\": [\"$SIGNED_TRANSACTION_HEX\"],
    \"id\": 1
  }"

A successful call returns HTTP 200 with the standard Polygon transaction hash:

{
  "jsonrpc": "2.0",
  "result": "0x7e8f000000000000000000000000000000000000000000000000000000000000",
  "id": 1
}

Save result for later queries:

export POLYGON_TRANSACTION_HASH="0x7e8f..."
📘

A successful RPC response confirms durable intake by Hyperstrate. It does not mean the transaction has already been delivered, included, or executed successfully.

4. Read the transaction receipt

Call eth_getTransactionReceipt with the transaction hash:

curl --fail-with-body \
  --request POST \
  --url "$HYPERSTRATE_API_URL/polygon/rpc" \
  --header "Authorization: Bearer $HYPERSTRATE_API_KEY" \
  --header "Content-Type: application/json" \
  --data "{
    \"jsonrpc\": \"2.0\",
    \"method\": \"eth_getTransactionReceipt\",
    \"params\": [\"$POLYGON_TRANSACTION_HASH\"],
    \"id\": 2
  }"

While the transaction has no visible on-chain receipt, result is null:

{
  "jsonrpc": "2.0",
  "result": null,
  "id": 2
}

After inclusion, result contains the standard Polygon receipt. Check its status field:

  • 0x1 means execution succeeded.
  • 0x0 means the transaction was included but execution reverted.

You can call eth_getTransactionByHash in the same way when you need the standard transaction object.

5. Inspect the Hyperstrate lifecycle

JSON-RPC intentionally returns the standard transaction hash rather than the Hyperstrate submission record. Both interfaces use the same submission pipeline, so you do not need to submit the transaction again. To inspect the record created by the JSON-RPC call—including its native ID and current private-delivery, execution, billing, and allowed-action fields—query REST by transaction hash:

curl --fail-with-body \
  --request GET \
  --url "$HYPERSTRATE_API_URL/polygon/v1/transactions?reference=$POLYGON_TRANSACTION_HASH" \
  --header "Authorization: Bearer $HYPERSTRATE_API_KEY"

The matching item includes both identifiers and the current lifecycle states:

{
  "items": [
    {
      "id": "txn_01K7EXAMPLE",
      "namespace": "polygon",
      "chainId": 137,
      "reference": "7e8f000000000000000000000000000000000000000000000000000000000000",
      "status": "queued",
      "deliveryState": "queued",
      "executionState": "pending",
      "billingState": "reserved",
      "allowedActions": ["stop", "replace"]
    }
  ],
  "meta": {
    "total": 1,
    "count": 1,
    "perPage": 30,
    "pages": 1,
    "page": 1
  }
}

For most integrations:

  • Treat queued and submitted as non-terminal.
  • Treat included as successful on-chain inclusion.
  • Treat reverted, expired, and failed as terminal failures.
  • Route review_required to operational review.
  • Do not assume stopped means an already dispatched transaction cannot land.

JavaScript example

const rpcUrl = `${process.env.HYPERSTRATE_API_URL}/polygon/rpc`;
const apiKey = process.env.HYPERSTRATE_API_KEY;
const signedTransaction = process.env.SIGNED_TRANSACTION_HEX;

async function rpc(method, params) {
  const response = await fetch(rpcUrl, {
    method: "POST",
    headers: {
      Authorization: `Bearer ${apiKey}`,
      "Content-Type": "application/json"
    },
    body: JSON.stringify({
      jsonrpc: "2.0",
      method,
      params,
      id: crypto.randomUUID()
    })
  });

  if (!response.ok) {
    throw new Error(`RPC transport failed with HTTP ${response.status}`);
  }

  const message = await response.json();
  if (message.error) {
    throw new Error(`${message.error.code}: ${message.error.message}`);
  }
  return message.result;
}

const transactionHash = await rpc("eth_sendRawTransaction", [signedTransaction]);
console.log("Polygon transaction hash:", transactionHash);

const receipt = await rpc("eth_getTransactionReceipt", [transactionHash]);
console.log("Receipt:", receipt);

JSON-RPC errors

Valid JSON-RPC errors normally return HTTP 200 with an error object:

{
  "jsonrpc": "2.0",
  "error": {
    "code": -32602,
    "message": "Invalid params"
  },
  "id": 1
}
CodeMeaning
-32700The request body is not valid JSON
-32600The JSON value is not a valid JSON-RPC 2.0 request
-32601The requested method is not supported
-32602The parameters or signed transaction are invalid
-32603Hyperstrate encountered an internal error
-32000Admission failed, for example insufficient credit, unavailable delivery, a capacity limit, or missing submit scope

Transport and authentication failures still use HTTP status codes such as 401, 413, and 429.

Supported RPC scope

The compatibility endpoint supports:

  • eth_chainId
  • eth_sendRawTransaction
  • eth_getTransactionByHash
  • eth_getTransactionReceipt

It is not a complete Polygon node endpoint. Libraries that automatically call methods such as eth_estimateGas, eth_getTransactionCount, eth_feeHistory, or eth_blockNumber need a normal Polygon RPC for transaction construction and general chain reads. Use Hyperstrate /polygon/rpc for the signed submission and supported transaction queries.

Production checklist

  • Create a dedicated submit-scoped API key.
  • Store the key in a secret manager.
  • Never expose the API key in browser code.
  • Discover and validate the chain configuration during startup.
  • Sign transactions only for the discovered chain ID.
  • Persist the returned Polygon transaction hash.
  • Query the REST API by reference when you need the Hyperstrate txn_... ID or detailed lifecycle.
  • Treat successful submission as intake, not inclusion.
  • Monitor until the receipt or Hyperstrate lifecycle reaches the state your application requires.
  • Add explicit handling for review_required.
  • Coordinate nonce allocation across concurrent signers.

Did this page help you?