Submit a payment, swap, or contract call that you signed in your wallet, signer service, or
application. GraphOps RPC broadcasts the signed payload with eth_sendRawTransaction and does not
custody private keys. You store the returned hash, poll for the receipt, and decide when the
transaction is final enough to report success.
Prerequisites
- A GraphOps RPC API key.
- Ethereum mainnet endpoint access.
- A locally signed transaction for the same chain ID as the endpoint.
- Application-side nonce, gas, and fee handling.
Prepare the transaction
Before signing, check the chain and plan fees against the same endpoint you will submit to:
- Call
eth_chainIdand confirm it matches the chain ID in the transaction. This prevents a wrong-chain submission. - Estimate gas with
eth_estimateGas, and set fees frometh_feeHistoryandeth_maxPriorityFeePerGas. - Sign the transaction locally and keep the signed bytes until the receipt confirms it.
Request
curl "https://rpc.graphops.xyz/v1/evm/1" \
-H "Authorization: Bearer <GRAPHOPS_API_KEY>" \
-H "Content-Type: application/json" \
--data '{
"jsonrpc": "2.0",
"id": 1,
"method": "eth_sendRawTransaction",
"params": ["0x<SIGNED_TRANSACTION>"]
}'import { createPublicClient, http } from "viem";
import { mainnet } from "viem/chains";
const client = createPublicClient({
chain: mainnet,
transport: http("https://rpc.graphops.xyz/v1/evm/1", {
fetchOptions: {
headers: {
Authorization: "Bearer <GRAPHOPS_API_KEY>",
},
},
}),
});
const hash = await client.request({
method: "eth_sendRawTransaction",
params: ["0x<SIGNED_TRANSACTION>"],
});
console.log(hash);import { ethers } from "ethers";
const request = new ethers.FetchRequest("https://rpc.graphops.xyz/v1/evm/1");
request.setHeader("Authorization", "Bearer <GRAPHOPS_API_KEY>");
const provider = new ethers.JsonRpcProvider(request);
const response = await provider.broadcastTransaction("0x<SIGNED_TRANSACTION>");
console.log(response.hash);from web3 import Web3
w3 = Web3(
Web3.HTTPProvider(
"https://rpc.graphops.xyz/v1/evm/1",
request_kwargs={
"headers": {
"Authorization": "Bearer <GRAPHOPS_API_KEY>",
},
},
)
)
tx_hash = w3.eth.send_raw_transaction("0x<SIGNED_TRANSACTION>")
print(tx_hash.hex())Response
{
"jsonrpc": "2.0",
"id": 1,
"result": "0x<TRANSACTION_HASH>"
}The hash identifies the transaction before it is included in a block. Store it before you report progress to your application, so a crash or timeout can resume from the hash instead of signing again.
Wait for the receipt
Poll eth_getTransactionReceipt with the stored hash. It returns null until the transaction is
included in a block:
curl "https://rpc.graphops.xyz/v1/evm/1" \
-H "Authorization: Bearer <GRAPHOPS_API_KEY>" \
-H "Content-Type: application/json" \
--data '{
"jsonrpc": "2.0",
"id": 1,
"method": "eth_getTransactionReceipt",
"params": ["0x<TRANSACTION_HASH>"]
}'{ "transactionHash": "0x<TRANSACTION_HASH>",The hash you stored "blockNumber": "0x112a880",The block that included it "blockHash": "0x<BLOCK_HASH>",Recheck this if the block reorganizes "status": "0x1",0x1 succeeded; 0x0 reverted but still paid gas "gasUsed": "0x5208", "effectiveGasPrice": "0x<WEI_PER_GAS>"Gas cost is gasUsed times this}A receipt shows inclusion, not finality. For payments, settlement, or other irreversible steps,
wait until the receipt's block is at or behind the safe or finalized block your workflow
requires. If the block is reorganized, the transaction can return to the pending pool or be
included in a different block, so check the receipt again before acting on it.
Retry guidance
Retrying the exact same signed transaction is usually safe because the transaction hash is deterministic. Do not mutate gas, nonce, or value and retry blindly.
| Message | Meaning | Action |
|---|---|---|
already known | A node already has the transaction. | Track the transaction hash and poll for a receipt. |
nonce too low | The nonce has already been used. | Check whether the transaction was mined or replaced. |
replacement transaction underpriced | A replacement transaction did not pay enough. | Reprice according to wallet policy. |
insufficient funds | Sender cannot cover value plus gas. | Surface the error to the funding workflow. |