Skip to main content
POST
/
wallet
/
proxy
Execute proxy wallet call
curl --request POST \
  --url https://relayer.forka.st/wallet/proxy \
  --header 'Content-Type: application/json' \
  --data '
{
  "owner": "0x82d3c1afe6b917c2d4ef6ab3b5c17408b9f5a4ce",
  "calls": [
    {
      "type": "CALL",
      "to": "0x5fa1e8b0dc9b67a4350e2cfea3d5b7c48290d579",
      "value": "0",
      "data": "0xa9059cbb000000000000000000000000b9d7c3f1e6a547281bf4aca0fe4d73c5887c1d5a00000000000000000000000000000000000000000000000000000000000003e8"
    },
    {
      "type": "DELEGATE_CALL",
      "to": "0x3d12ac4a8fe9052f8f049cd64496f89c45d1eb12",
      "value": "0",
      "data": "0x6a761202"
    }
  ],
  "nonce": "17",
  "signature": "0xbd8cd8efe71e382e0ab025ede9a7b09e34154a2796ae036bf438082e35801297c4a262fc73c55690f4c7da011f82ef80e8f0d1a36078fac3b7eaa1280b6366baf6",
  "approvalData": "0x"
}
'
{
"txHash": "0xa1f59c7d9e4b08e43fa4c6ed28f15c9f7ed1b0a2bde3f59c8d31b2388a148a52",
"confirmations": 1
}
Submit batched contract calls through the Forkast relayer (https://relayer.forka.st/wallet/proxy). This router shares the exact authentication headers used by POST /order and executes transactions from the managed proxy wallet tied to your API key.
Call https://relayer.forka.st/wallet/proxy with the L2 headers FORKAST_ADDRESS, FORKAST_SIGNATURE, FORKAST_TIMESTAMP, FORKAST_API_KEY, and FORKAST_PASSPHRASE. The owner field must match FORKAST_ADDRESS.
calls defaults to an empty array. When you omit calls the relay only ensures the smart wallet is deployed, increments the nonce, and returns the RelayHub transaction hash.
If the proxy already exists and you send an empty calls array, the service does not post a new RelayHub transaction and responds with txHash = 0x000…000 while still reporting the configured confirmation target.

Request body

Root fields

FieldTypeRequiredDescription
ownerstringYesPolygon/EVM address that matches the authenticated API key.
callsarray<object>NoOrdered list of proxy invocations. Defaults to [].
noncestringYesDecimal RelayHub nonce for owner. Fetch with RelayHub.getNonce(owner).
signaturestringYesEIP-191 signature covering the payload defined in Signature requirements.
approvalDatastringNoHex blob forwarded to acceptRelayedCall. Use 0x when unused.

Call entries (calls[])

FieldTypeRequiredDescription
typestringYes"CALL" for a standard call or "DELEGATE_CALL" to preserve storage context (1 and 2 respectively on-chain).
tostringYesTarget contract address.
valuestringNoDecimal string amount of wei to forward. Defaults to "0".
datastringNoLowercase 0x-prefixed calldata. Defaults to 0x.
value and data must be strictly formatted strings—no scientific notation or uppercase hex. The router executes calls sequentially and stops if any revert, surfacing the RelayHub error.

Execution behavior

  • Wallet deployment happens automatically the first time you call the endpoint (or when you send an empty calls array).
  • Gas price, gas limit, and transaction fee inputs are ignored; the backend enforces the environment-configured values present in the signature payload.
  • The response returns the RelayHub transaction hash (txHash) plus confirmation depth once available.
  • If the target contract reverts, the router still posts the RelayHub tx but responds with 400 {"error":"relay call reverted"} along with the revert reason in the logs.

Signature requirements

  1. Obtain the latest nonce = RelayHub.getNonce(owner) before constructing the payload.
  2. Encode the relayed call following OpenZeppelin GSN v1:
    keccak256(abi.encodePacked("rlx:", owner, proxyFactory, encodedFunction, transactionFee, gasPrice, gasLimit, nonce, relayHub, relayAddress)).
  3. Ensure transactionFee, gasPrice, and gasLimit match the configured backend values. Mismatches cause WrongSignature/WrongNonce errors that bubble up as 400 responses.
  4. Sign the hash with toEthSignedMessageHash() (EIP-191) using the same key referenced by the FORKAST_ADDRESS header.

Responses and errors

StatusBodyDescription
200{"txHash": "...","confirmations": 1}RelayHub accepted the call and the transaction hash is returned. confirmations increments as replays are queried.
400{"error":"owner_address_mismatch"}owner differs from the authenticated address.
400{"error":"invalid_field ... "}Malformed address/hex/value, negative numbers, or schema violations.
400{"error":"relay call reverted"}Proxy execution reverted inside the recipient contract.
400/503{"error":"wallet_service_disabled"}Wallet service missing or disabled in the environment.
502{"error":"wallet_transport_error: ..."}RPC/RelayHub transport failure before execution.
txHash always references the RelayHub transaction—use your own wallet logs or explorer traces if you need the proxy wallet address or emitted events from downstream contracts.

Body

application/json
owner
string
required

Polygon/EVM address that must match the FORKAST_ADDRESS header.

Example:

"0x82d3c1afe6b917c2d4ef6ab3b5c17408b9f5a4ce"

nonce
string
required

Decimal RelayHub nonce for the owner. Fetch it via RelayHub.getNonce(owner).

Example:

"17"

signature
string
required

EIP-191 signature produced over the OpenZeppelin GSN v1 payload.

Example:

"0xbd8cd8efe71e382e0ab025ede9a7b09e34154a2796ae036bf438082e35801297c4a262fc73c55690f4c7da011f82ef80e8f0d1a36078fac3b7eaa1280b6366baf6"

calls
object[]

Ordered list of proxy wallet invocations. Defaults to an empty array to trigger wallet deployment only.

Example:
[
{
"type": "CALL",
"to": "0x5fa1e8b0dc9b67a4350e2cfea3d5b7c48290d579",
"value": "0",
"data": "0xa9059cbb000000000000000000000000b9d7c3f1e6a547281bf4aca0fe4d73c5887c1d5a00000000000000000000000000000000000000000000000000000000000003e8"
}
]
approvalData
string

Hex blob forwarded to acceptRelayedCall. Use 0x to skip.

Example:

"0x"

Response

Proxy wallet call accepted by the relay.

txHash
string
required

RelayHub transaction hash broadcast by the router.

Example:

"0xa1f59c7d9e4b08e43fa4c6ed28f15c9f7ed1b0a2bde3f59c8d31b2388a148a52"

confirmations
integer
required

Number of confirmations observed when responding.

Example:

1