Transactions API

Transfer Tokens (v2)

Send XRGE or custom tokens to another address using client-side ML-DSA-65 signing.

POST /api/v2/transfer
Content-Type: application/json

Request Body

{
  "payload": {
    "to": "recipient-public-key-hex",
    "amount": 100.0,
    "token": "XRGE",
    "from": "sender-public-key-hex",
    "timestamp": 1706745600000,
    "nonce": "random-hex-string"
  },
  "signature": "ml-dsa65-signature-hex",
  "public_key": "sender-public-key-hex"
}
FieldTypeRequiredDescription
tostringYesRecipient's public key (hex) or rouge1 address
amountnumberYesAmount to send
tokenstringNoToken symbol (default: "XRGE")

Fee: The transaction fee is fixed at 1 XRGE and enforced by the server; any client-supplied fee in the payload is ignored.

Security: Private keys never leave your application. The transaction is signed client-side using ML-DSA-65 and the server verifies the signature before processing.

Response

{
  "success": true,
  "message": "Transfer transaction submitted"
}

The response does not include a transaction id.

Error Response

{
  "success": false,
  "error": "insufficient XRGE balance: have 50.0000, need 101.0000"
}

Get Transactions

Retrieve recent transactions.

GET /api/txs?limit=50&offset=0

Query Parameters

ParameterTypeDefaultDescription
limitnumber200Max transactions to return (max 1000)
offsetnumber0Pagination offset

Response

Each item wraps the transaction with its block context. The wrapper fields are camelCase (txId, blockHeight, blockHash, blockTime); the nested tx (a TxV1) is snake_case.

{
  "txs": [
    {
      "txId": "abc123...",
      "blockHeight": 42,
      "blockHash": "xyz...",
      "blockTime": 1706745600000,
      "tx": {
        "version": 1,
        "tx_type": "transfer",
        "from_pub_key": "abc...",
        "nonce": 1234567890,
        "payload": {
          "to_pub_key_hex": "def...",
          "amount": 100
        },
        "fee": 1.0,
        "sig": "ghi..."
      }
    }
  ],
  "total": 150
}

Get Transaction by Hash

GET /api/tx/:hash

Response

txId, blockHeight, blockHash and blockTime are top-level (not inside tx). The nested tx is the stored TxV1 exactly as it was signed and accepted, in snake_case; receipt is the execution receipt (present once the block is applied; null only for a transaction that is known but not yet executed). The example below is a real mainnet transfer (3c1b71bc…, block 110); unused payload fields are returned as null and omitted here.

{
  "success": true,
  "txId": "3c1b71bc59557f9b4d1191bc299e1bd2d8b6ad4058147efebe70d0f6c07daae1",
  "blockHeight": 110,
  "blockHash": "7ee2afd4eaebdcd4…",
  "blockTime": 1790297628272,
  "tx": {
    "version": 1,
    "tx_type": "transfer",
    "from_pub_key": "df255dbd…",
    "nonce": 4,
    "payload": {
      "to_pub_key_hex": "rouge1cd3mkuu6p89nm6uakpcchfmkvhj8x2z0xfx33gag9t5kma2s8fcs4m9mda",
      "amount": 50,
      "token_name": "XRGE"
    },
    "fee": 1.0,
    "sig": "…",
    "signed_payload": "{…}"
  },
  "receipt": {
    "tx_hash": "3c1b71bc…",
    "block_height": 110,
    "block_hash": "7ee2afd4eaebdcd4…",
    "index": 0,
    "tx_type": "transfer",
    "from": "df255dbd…",
    "status": "Success",
    "fee_paid": 1.0,
    "timestamp": 1790297628272,
    "logs": [
      { "event_type": "transfer", "data": { "amount": 50, "to": "rouge1cd3mkuu…", "token": "XRGE" } }
    ]
  }
}

Field notes

  • tx.payload.to_pub_key_hex holds the recipient exactly as it was submitted — either a rouge1… address (as in the example) or a hex public key. The name is historical; treat it as "recipient", not as a guarantee of a hex key. To convert either form to the other, call GET /api/resolve/:input (auto-detects the format and returns address, publicKey and balance).
  • receipt.logs[].data.to carries the same recipient value; receipt.status is "Success" or {"Failed": "<reason>"}.
  • signed_payload is the exact JSON the sender signed (V2 transactions); consensus binds the executed fields to it, so tx.* never differs from what was signed.
  • Stability: the tx and receipt field names are the serialized TxV1 / TxReceipt types and are stable; any change would ship as a new versioned endpoint, not as a rename.

Get Transaction Receipt

GET /api/tx/:hash/receipt

Returns execution receipt for contract calls and other complex transactions.


Request Faucet (v2)

Get free testnet XRGE tokens. The faucet is only enabled on test networks; elsewhere it returns 403.

POST /api/v2/faucet
Content-Type: application/json

Request Body

{
  "payload": {
    "from": "your-public-key-hex",
    "timestamp": 1706745600000,
    "nonce": "random-hex-string"
  },
  "signature": "your-signature-hex",
  "public_key": "your-public-key-hex"
}

Response

{
  "success": true,
  "message": "Faucet: 10000 XRGE sent"
}

Limits

The faucet refuses a request with 429 while you already have a faucet transfer pending, if your balance is already above the faucet threshold, or during the 24-hour per-key cooldown (shared with POST /api/faucet; the response then also carries retryAfterSecs). When the node sets --faucet-whitelist, keys that are not listed get 403.


Transaction Types

TypeDescription
transferStandard XRGE or token transfer (faucet payouts are transfers with payload.faucet = true)
stakeStake tokens to become validator
unstakeUnstake tokens
create_tokenCreate custom token (token_mintable / token_max_supply only from TOKEN_MINTING activation)
mint_tokensCreator mints more of a mintable token (token_total_supply = amount) — applied only from TOKEN_MINTING activation
burnBurn tokens permanently
shield / shielded_transfer / unshieldSuspended since block 245 (V1 shielded pool; a block carrying one is invalid). Also suspended: token_lock, token_unlock, create_staking_pool, token_stake, token_unstake, create_proposal, cast_vote, execute_proposal, delegate, undelegate, token_approve, token_transfer_from; and slash is rejected. See Status
contract_deployDeploy WASM smart contract
contract_callCall smart contract method