Use Gateway transaction endpoints to simulate, send, batch, cost, and track signed MultiversX transactions.
Base URL
https://rust-gateway.xoxno.com
Responses use the MultiversX Gateway body shape: data, error, and code.
Endpoints
| Need | Endpoint |
|---|
| Send one signed transaction | POST /transaction/send |
| Simulate a transaction | POST /transaction/simulate |
| Send multiple transactions | POST /transaction/send-multiple |
| Estimate transaction cost | POST /transaction/cost |
| Get transaction by hash | GET /transaction/{txhash} |
| Get status by hash | GET /transaction/{txhash}/status |
| Get processed status | GET /transaction/{txhash}/process-status |
| Inspect transaction pool | GET /transaction/pool |
Transaction Fields
| Field | Type | Required | Notes |
|---|
nonce | integer | yes | Sender account nonce. |
value | string | yes | EGLD value in atomic units. |
receiver | string | yes | Bech32 receiver. |
sender | string | yes | Bech32 sender. |
gasPrice | integer | yes | Minimum 1000000000. |
gasLimit | integer | yes | Maximum gas units. |
data | string | no | Base64 payload. |
chainID | string | yes | 1 for mainnet. |
version | integer | yes | Use 2 for current SDK output. |
signature | string | yes | Hex Ed25519 signature. |
The Gateway does not sign transactions. Submit only transactions signed for the exact payload, nonce, sender, and chain ID.
Send Request
cURL
TypeScript
Python
Rust
curl -X POST "https://rust-gateway.xoxno.com/transaction/send" \
-H "content-type: application/json" \
-d '{
"nonce": 42,
"value": "0",
"receiver": "erd1...",
"sender": "erd1...",
"gasPrice": 1000000000,
"gasLimit": 50000,
"data": "",
"chainID": "1",
"version": 2,
"signature": "<hex-signature>"
}'
const tx = {
nonce: 42,
value: "0",
receiver: "erd1...",
sender: "erd1...",
gasPrice: 1000000000,
gasLimit: 50000,
data: "",
chainID: "1",
version: 2,
signature: "<hex-signature>",
};
const res = await fetch("https://rust-gateway.xoxno.com/transaction/send", {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify(tx),
});
if (!res.ok) throw new Error(`gateway failed: ${res.status}`);
const body = await res.json();
if (body.error) throw new Error(body.error);
console.log(body.data.txHash);
import requests
tx = {
"nonce": 42,
"value": "0",
"receiver": "erd1...",
"sender": "erd1...",
"gasPrice": 1000000000,
"gasLimit": 50000,
"data": "",
"chainID": "1",
"version": 2,
"signature": "<hex-signature>",
}
res = requests.post(
"https://rust-gateway.xoxno.com/transaction/send",
json=tx,
timeout=10,
)
res.raise_for_status()
body = res.json()
if body.get("error"):
raise RuntimeError(body["error"])
print(body["data"]["txHash"])
// Run inside an async function with reqwest and serde_json.
let tx = serde_json::json!({
"nonce": 42,
"value": "0",
"receiver": "erd1...",
"sender": "erd1...",
"gasPrice": 1000000000,
"gasLimit": 50000,
"data": "",
"chainID": "1",
"version": 2,
"signature": "<hex-signature>"
});
let body: serde_json::Value = reqwest::Client::new()
.post("https://rust-gateway.xoxno.com/transaction/send")
.json(&tx)
.send()
.await?
.error_for_status()?
.json()
.await?;
if body["error"].as_str().unwrap_or("") != "" {
return Err(format!("gateway error: {}", body["error"]).into());
}
println!("{}", body["data"]["txHash"]);
The JSON examples contain placeholders. Replace them with a real signed transaction before sending.
Status Request
curl "https://rust-gateway.xoxno.com/transaction/<txhash>/status?sender=erd1..."
Pass sender when available so the Gateway can route directly to the sender shard.
Edge Cases
| Case | Behavior | Fix |
|---|
HTTP 200 with error | Observer rejected the operation. | Treat the body as failed. |
nonce too low or nonce too high | Sender nonce differs from signed transaction. | Re-read nonce, rebuild, and sign again. |
Status lookup without sender | Gateway may search more shards. | Pass sender when known. |
| Transaction pool reads | Full pool fetch can be disabled by config. | Use by-sender when possible. |
Verify
- Simulation returns no body-level error before sending.
- Send response has
data.txHash.
- Status endpoint returns the expected hash status after finalization.
- Your client handles body-level
error even when HTTP status is 200.
Related Pages