Skip to main content
Soroban contract calls are in Early Availability. Contact Fireblocks Support to enable them for your workspace.
Soroban is the smart contract platform on the Stellar network. To call a Soroban contract from a Fireblocks vault, you build an unsigned Stellar transaction envelope that invokes the contract, then submit it with the Create a new transaction endpoint using the SOROBAN_CALL operation. The envelope you submit is the same artifact a Soroban dApp hands a wallet. Fireblocks decodes it, determines the footprint, resource fee, sequence number, and authorization entries from its own simulation, and signs a transaction it rebuilt from your invocation. Only the contract invocation itself is carried through unchanged.

Before you start

Make sure the following are in place:
  • Soroban contract calls enabled for your workspace. If they are not, the request fails with HTTP 403 and error code 16001 (SOROBAN_CALL_FORBIDDEN).
  • XLM in the source vault. Fees are paid in XLM from the source vault’s Stellar account. The vault needs enough XLM to cover the resource fee and the inclusion fee.
  • A whitelisted contract wallet for the contract you want to call, unless your workspace has one-time addresses enabled. See Whitelist the contract.
  • A Policy rule for Soroban contract calls. Without a matching rule, the call is blocked. See Policy configuration.

How Soroban contract calls work on Fireblocks

You build and submit the envelope:
  1. Build the envelope. Use a Stellar SDK to build a TransactionEnvelope that carries one invokeHostFunction operation invoking your contract. Set the source account to the vault account’s Stellar address and set a time bound. See Envelope requirements.
  2. Encode it. Serialize the unsigned envelope to XDR and encode it in base64. Do not sign it.
  3. Submit it. Call Create a new transaction with operation set to SOROBAN_CALL and the base64 envelope in extraParameters.sorobanCallData.envelopeXdr.
Fireblocks then processes the call in this order:
  1. Validates the envelope.
  2. Screens the transaction and checks that the vault holds XLM for fees.
  3. Simulates the call to determine its footprint, resource fee, and authorization entries.
  4. Checks that the call needs authorization from the source vault only.
  5. Checks that the vault can pay the simulated resource fee plus the inclusion fee.
  6. Evaluates the call against your Policy.
  7. After approval, assigns the sequence number, assembles the final transaction, signs it, and broadcasts it.
Because simulation runs before Policy evaluation, a call that fails simulation never reaches your approvers. For building Soroban transactions, see the Stellar documentation on contract invocations.

Envelope requirements

The envelope must meet all of these conditions:
  • It carries exactly one invokeHostFunction operation, and that operation invokes a contract.
  • It is unsigned and carries no authorization entries.
  • It has no memo and no fee-bump wrapper.
  • Its source account is the Stellar address of the vault account you use as source. Multiplexed (M...) addresses are not accepted.
  • It has a time bound with a non-zero maxTime that is still in the future.
  • It carries no other preconditions: ledgerBounds, minAccountSequence, minAccountSequenceAge, minAccountSequenceLedgerGap, and extraSigners must be unset.
  • Its declared fee does not exceed 1,000,000 stroops.
  • The invoked contract is the contract of your destination. See Whitelist the contract.
Fireblocks sets the footprint, resource fee, sequence number, and authorization entries itself. Values you set for these in the envelope are not used. The inclusion fee of the signed transaction is also set by Fireblocks: your declared fee is only checked against the 1,000,000 stroop limit and against the vault’s balance. A Stellar transaction cannot exceed 132,096 bytes, which is about 176,128 base64 characters. The API rejects a request whose envelopeXdr is longer than 176,128 characters.
The API checks the request shape and that envelopeXdr is present. Fireblocks decodes and validates the envelope after the transaction is created, so an invalid envelope still returns a transaction ID. A transaction whose envelope fails validation is not signed and ends with status FAILED and sub-status INVALID_CONTRACT_CALL_DATA. Check the transaction status rather than treating a successful create response as acceptance.

Whitelist the contract

Soroban contracts use the same contract wallet whitelisting as other contracts on Fireblocks:
  1. Create a contract wallet with POST /v1/contracts, giving it a display name.
  2. Add the contract’s Stellar address (C...) to the wallet with POST /v1/contracts/{contractId}/{assetId}, using XLM on mainnet or XLM_TEST on testnet as the assetId.
  3. Pass the contract wallet’s ID as the destination of your SOROBAN_CALL transaction, with type CONTRACT.
Adding the address to the contract wallet returns the status WAITING_FOR_APPROVAL. Until the address is approved and active, a transaction to that wallet is rejected with a 400 error (code 1412, destination contract suspended). The contract your envelope invokes must be the address registered on that wallet. If the wallet does not exist or has no address for the asset, the request is rejected with a 400 error (code 1411, destination contract not found). If the wallet holds a different address, the transaction is created and ends FAILED with sub-status INVALID_CONTRACT_CALL_DATA. If one-time addresses are enabled for your workspace, you can instead pass the contract’s C... address as a ONE_TIME_ADDRESS destination. The envelope must invoke that same address. If one-time addresses are not enabled, Policy blocks the call.

Policy configuration

Soroban contract calls have their own Policy rule type, SOROBAN_CALL. Rules for other operation types, including CONTRACT_CALL, MINT, and BURN, do not apply to Soroban contract calls. If no SOROBAN_CALL rule matches a call, the call is blocked. A SOROBAN_CALL rule matches on three conditions, and all three are required:
  • Initiator: who submitted the call.
  • Source: the vault account the call is made from.
  • Destination: the contract being called.
The rule’s action allows the call, blocks it, or sends it for two-tier approval. An allow rule must name the designated signers. SOROBAN_CALL rules do not support conditions on asset or amount. To restrict which contracts a vault can call, set the rule’s destination.

Example request

The SDK and CLI examples assume an initialized fireblocks client, as described in Choose an interface.

Parameters

A Soroban contract call takes exactly one destination: destinations is not supported. replaceTxByHash is not supported.

Limits and constraints

Sequence numbers

Fireblocks assigns the sequence number of each Soroban contract call from the vault’s Stellar account, after Policy approval. You do not set or manage it.

Transaction validity window

The signed transaction is valid on the Stellar network for three hours from the moment Fireblocks assigns its sequence number, which happens after Policy approval. If it is not included in that window, it expires and cannot be broadcast. Submit a new request to try again. The maxTime you set in your envelope is checked only when the request is validated, and is not carried into the signed transaction.

Cancelling

You can cancel a Soroban contract call until it is signed. A call rejected by an approver ends CANCELLED.

Policy approval window

Policy must return a verdict within 10 minutes, including the time your approvers take on a two-tier rule. If it does not, the transaction ends FAILED with sub-status TIMEOUT.

Authorization

Fireblocks supports calls that need authorization from the source vault only. A call whose simulation shows it needs authorization from any other address, such as a contract account or a second signer, fails before Policy evaluation. A call whose simulation shows it needs no authorization at all is not supported either: it passes Policy but fails afterwards with sub-status INVALID_CONTRACT_CALL_DATA.

Fee estimation

The Estimate transaction fee endpoint does not support the SOROBAN_CALL operation. Fireblocks determines the resource fee from its own simulation.

Transaction outcomes

A Soroban contract call can end early at several points. The transaction’s sub-status identifies the reason. Fireblocks never rebuilds or resubmits a failed or expired call on your behalf. Fix the cause and submit a new request.

Webhooks

Status changes for Soroban contract calls arrive through the standard Fireblocks transaction webhooks, with SOROBAN_CALL as the transaction’s operation. If your webhook handler branches on the operation type, add SOROBAN_CALL so these transactions are not skipped.