The Fireblocks connector polls a Fireblocks workspace and surfaces vault accounts, balances, and transactions as read-only streams.
Prerequisites#
You need a Fireblocks account with an API key carrying the minimum permissions for the capabilities you use.
Make sure to create an API key dedicated to Formance. Doing so will improve your auditability and security and will allow you to revoke access to Formance at any time if needed.
Installation#
curl -X POST $FORMANCE_API_URL/api/payments/v3/connectors/install/fireblocks \
-H "Content-Type: application/json" \
-d @config.jsonWith config.json containing:
{
"apiKey": "string",
"endpoint": "string",
"name": "string",
"pollingPeriod": "30m",
"privateKey": "string"
}Configuration fields#
| Field | Required | Default | Description |
|---|---|---|---|
apiKey | yes | — | API key from the Fireblocks workspace. |
endpoint | yes | — | Fireblocks API base URL — depends on your workspace environment (see Endpoints). |
name | yes | — | Unique name for this connector instance. |
pollingPeriod | no | 30m | Sync cadence. |
privateKey | yes | — | Fireblocks API secret. Signs the JWT for the Authorization header. Single-line string with literal \n characters. |
Convert a PEM file to the expected single-line format with:
cat fireblocks_private.pem | awk '{printf "%s\\n", $0}'Endpoints#
| Environment | URL |
|---|---|
| US Sandbox | https://sandbox-api.fireblocks.io |
| US Mainnet/Testnet | https://api.fireblocks.io |
| EU Mainnet/Testnet | https://eu-api.fireblocks.io |
| EU2 Mainnet/Testnet | https://eu2-api.fireblocks.io |
Capabilities#
Read-only — no payouts, transfers, or webhook deliveries.
- FetchAccounts — vault accounts.
- FetchBalances — per-asset balances per vault.
- FetchPayments — transactions, including withdrawals, transfers, staking/unstaking, and minting/burning.
Account model#
Every Connectivity internal account is one Fireblocks vault account (the multi-asset container that holds wallets across chains). The reference is the vault id; name is the vault name; defaultAsset is null — vaults are multi-asset, with balances per asset via FETCH_BALANCES (same-symbol holdings across chains collapse into one row; see Multi-chain aggregation). Vault-specific fields land under account metadata. No EXTERNAL accounts are emitted — Fireblocks counterparties live in the workspace UI. See Accounts for the cross-connector model.
Asset model#
The canonical asset string is derived from Fireblocks' displaySymbol, sanitized where needed, and suffixed with /precision (USDT/6, ETH/18). The Fireblocks legacyId (USDT_ERC20, ETH_TEST5, …) is preserved on every payment under com.fireblocks.spec/legacy_id.
Multi-chain aggregation#
Same-symbol holdings across chains in one vault collapse into a single balance row. A vault holding USDT_ERC20 and USDT_TRX produces one USDT/6 row with the summed amount. Per-chain identity stays observable at the payment level via com.fireblocks.spec/blockchain_id, legacy_id, and contract_address.
Testnet segregation#
Assets on testnet blockchains (per Blockchain.onchain.test) carry a _TEST suffix and com.fireblocks.spec/testnet=true (e.g. ETH_TEST/18, SOL_TEST/9). Mainnet and testnet holdings of the same symbol never collide.
Asset classes the connector skips#
Only NATIVE, FT, and FIAT are ingested. NFT, SFT, VIRTUAL, and deprecated assets don't appear in Accounts, Balances, or Payments.
Sanitization rules#
When displaySymbol can't be used verbatim:
- Lowercase → uppercase (
xDAI→XDAI). - Digit prefix stripped until first letter (
1INCH→INCH). - Non-
[A-Z0-9]characters dropped. - Base capped at 17 characters; testnet assets additionally carry
_TEST.
First sync
The initial poll pins after=1, bypassing Fireblocks' default 90-day window so the full history is backfilled. Long histories may take several cycles to surface entirely, with new rows appearing each cycle.
Metadata keys#
Fireblocks fields land on the metadata of the Connectivity Account or Payment under com.fireblocks.spec/. The connector stamps them during mapping so chain, contract, and classification stay visible after the canonical asset string is computed.
Account metadata#
Stamped on a Connectivity Account when the VaultAccount field is set or true.
| Key | Source |
|---|---|
com.fireblocks.spec/customer_ref_id | VaultAccount.customerRefId |
com.fireblocks.spec/hidden_on_ui | VaultAccount.hiddenOnUI |
com.fireblocks.spec/auto_fuel | VaultAccount.autoFuel |
Payment metadata#
Two groups of keys land on each Payment:
Cached asset metadata#
Copied from the connector's in-process Asset cache (loaded at install, refreshed via TTL). Stamped on every Payment so consumers retain the chain, contract, and classification even after the asset string is canonicalized away from legacyId.
| Key | Source |
|---|---|
com.fireblocks.spec/legacy_id | Asset.legacyId |
com.fireblocks.spec/asset_uuid | Asset.id |
com.fireblocks.spec/display_name | Asset.displayName |
com.fireblocks.spec/display_symbol | Asset.displaySymbol |
com.fireblocks.spec/blockchain_id | Asset.blockchainId |
com.fireblocks.spec/asset_class | Asset.assetClass (NATIVE, FT, FIAT) |
com.fireblocks.spec/contract_address | Asset.onchain.address |
com.fireblocks.spec/token_standard | Asset.onchain.standards (comma-joined) |
com.fireblocks.spec/verified | Asset.metadata.verified (only when true) |
com.fireblocks.spec/features | Asset.metadata.features (comma-joined) |
com.fireblocks.spec/testnet | derived from Blockchain.onchain.test (only when true) |
Transaction-level metadata#
Read directly from the Fireblocks Transaction. Present only when the upstream field is populated, so absence is meaningful (no tx_hash ⇒ off-chain transfer, no note ⇒ unannotated, …).
| Key | Source |
|---|---|
com.fireblocks.spec/tx_hash | Transaction.txHash |
com.fireblocks.spec/network_fee | Transaction.feeInfo.networkFee |
com.fireblocks.spec/note | Transaction.note |
com.fireblocks.spec/sub_status | Transaction.subStatus |
com.fireblocks.spec/destination_ids | Transaction.destinations[].id (multi-destination transactions only) |
The full Fireblocks Transaction body is preserved verbatim on /v3/payments/{paymentID}.adjustments[].raw. The list endpoint doesn't inline adjustments — fetch by ID for the raw payload. Vault payloads are inlined on both the list and detail account endpoints via the account's raw field.
Rate limits#
Per endpoint, per transaction, per minute — depending on your Fireblocks contract. See the Fireblocks rate-limiting docs.
Known gaps#
- Outbound initiation — Fireblocks supports transaction creation upstream; the connector is read-only.
CreateTransferandCreatePayoutare not wired. - Webhooks — not consumed; refresh runs on the polling cycle.
- External accounts —
FETCH_EXTERNAL_ACCOUNTSis not implemented. Counterparties live in the workspace UI. - NFT, SFT, VIRTUAL — filtered out; only
NATIVE,FT,FIATare ingested (see Asset model).