Guides
Fireblocks
The Fireblocks API Co-Signer calls Immiscible before it signs each transfer, and signs only when an unused receipt covers it.
Fireblocks documents an outside approval step that runs before signing: the API Co-Signer callback handler. The Co-Signer, which you run and which holds your key share, calls a handler you name before it signs each transaction, and signs only if the handler answers APPROVE. Immiscible can be that handler. It holds no key share, no seed phrase and no funds, and never signs a transaction; the Co-Signer does.
Fireblocks’ documentation: creating a callback handler, secure communication, the response object, approving transactions.
#The exchange, as documented
- The Co-Signer sends
POST {callback URL}/v2/tx_sign_request. The body is a JWT signed RS256 with the Co-Signer’s private key. Its payload carriesrequestId,txId,operation,asset,amountStr,destAddress,externalTxId,noteand more. - The handler answers with a JWT signed RS256 with its own RSA-2048 key:
{ action, requestId, rejectionReason }, whereactionisAPPROVE,REJECTorRETRY.
#How Immiscible answers
The same rule as the card rail: no unused receipt, no signature.
- The agent asks
POST /v1/actions/authorizewith the crypto payment, as on Crypto payments. - On allow, it creates the Fireblocks transaction with the Immiscible action id as
externalTxId(orimmiscible:<action id>in thenote). - The Co-Signer calls Immiscible. Immiscible verifies the request’s signature with the Co-Signer’s public key, then approves only if that action was allowed, its agent is not frozen, its receipt is unused, unrevoked and unexpired, and the transfer matches it: the same destination address, an asset id that names the same asset (
USDC,USDC_POLYGONand so on), andamountStrno larger than allowed. Approving uses the receipt up, so it approves one signature. - Anything else, including a request it cannot verify or any error, is a signed
REJECTwith a reason. Every answer is awallet_authorizationrecord in the ledger.
What is not checked: the network inside a Fireblocks asset id (asset ids are Fireblocks’ own names, and the mapping to networks is not published in a form Immiscible reads), and the source vault account. Immiscible answers TRANSFER operations only and rejects any other.
#Set it up
- In Immiscible, Settings, Connections, choose Connect on the Fireblocks API Co-Signer card and paste the Co-Signer’s public key (PEM). Owners and admins can do this. Immiscible makes the handler’s RSA-2048 key pair and shows the public key and the callback URL,
https://<your Immiscible>/wallets/<workspace>/fireblocks. - In your Co-Signer’s setup, give it that callback URL and the handler public key.
- In Fireblocks, route the agent’s transactions through the API user whose Co-Signer has the callback.
The API is PUT /api/w/:wid/wallets/fireblocks with { "cosignerPublicKey": "-----BEGIN PUBLIC KEY-----..." }, and DELETE to disconnect.
#Not verified
Tested against a fake Co-Signer that replays the documented request shape and checks the signed answer (test/crypto-wallets.test.js), not against a real Co-Signer. The configuration-change callback (/v2/config_change_sign_request) is not handled.